Vue3.x集成 Pinia 之 用户管理系统

3/30/2022

用户管理系统

# 创建用户Store

  1. 修改 useUserStore.js
// useUserStore.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
    state: () => {
        return {
            users: [
                { id: 1, name: '张三', gender: '男', age: 16, date: '2015/10/12' },
                { id: 2, name: '李四', gender: '女', age: 17, date: '2017/10/12' },
                { id: 3, name: '王五', gender: '男', age: 18, date: '2019/10/12' },
                { id: 4, name: '赵六', gender: '女', age: 19, date: '2022/3/30' },
            ],
            search: '',
            tempUser: {
                id: '',
                name: '',
                gender: '',
                age: '',
                date: new Date().toLocaleDateString()
            }
        }
    },
    // getters
    getters: {
    },
    // actions
    actions: {
    }
})

# 展示用户数据

  1. App.vue页面调整,展示用户列表
// App.vue

<script setup>
import { storeToRefs } from "pinia";
import { useUserStore } from "./store/useUserStore";

const { users } = storeToRefs(useUserStore());
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />

  <div class="container">
    <table border="1">
      <tr>
        <td class="no_line">
          <label for="id">序号:</label>
          <input type="text" placeholder="请填写序号" />
        </td>
        <td class="no_line">
          <label for="name">姓名:</label>
          <input type="text" placeholder="请填写姓名" />
        </td>
        <td class="no_line">
          <label for="gender">性别:</label>
          <input type="text" placeholder="请填写性别" />
        </td>
        <td class="no_line">
          <label for="age">年龄:</label>
          <input type="text" placeholder="请填写年龄" />
          <button>添加</button>
        </td>
        <td class="no_line">
          <label for="search">搜索</label>
          <input type="text" placeholder="请输入要搜索的人名" />
        </td>
      </tr>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>年龄</th>
        <th>时间</th>
        <th>操作</th>
      </tr>
      <tr v-for="item in users" :key="item.id">
        <td>{{ item.id }}</td>
        <td>{{ item.name }}</td>
        <td>{{ item.gender }}</td>
        <td>{{ item.age }}</td>
        <td>{{ item.date }}</td>
        <td><a href="#" @click="del(item.id)">删除</a></td>
      </tr>
    </table>
  </div>
</template>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.container {
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-top: 20px;
}
input {
  width: 80px;
}
td {
  padding: 3px 25px;
}
.no_line {
  border: none;
}
</style>

上边我们通过 v-for 将用户列表展示出来

效果图

# 添加用户数据

  1. 模拟添加数据

在actions中加入添加数据的方法:

// useUserStore.js -> actions
addUser() {
    // 添加 新用户到 用户列表
    this.users.push(this.tempUser)
    // 清空 新用户字段
    this.tempUser = {
        id: '',
        name: '',
        gender: '',
        age: '',
        date: new Date().toLocaleDateString()
    }
},

App.vue中引入当前方法:

// App.vue -> script
const { addUser,searchUser,delUser } = useUserStore();//这里把搜索用户和删除用户的方法一起引入
const { users, tempUser, searchName } = storeToRefs(useUserStore());

input标签的值与 临时用户对象 tempUser 进行数据的双向绑定

<!-- App.vue -> template -->
<template>
<input type="text" placeholder="请填写序号" v-model="tempUser.id" />
<input type="text" placeholder="请填写姓名" v-model="tempUser.name" />
<input type="text" placeholder="请填写年龄" v-model="tempUser.age" />
<input type="text" placeholder="请填写性别" v-model="tempUser.gender"/>

<!-- 将方法绑定到按钮上 -->
<button @click="addUser()">添加</button>
</template>

# 搜索用户

  1. 模拟搜索用户

将 搜索框input标签的值与搜索 searchUser 进行数据的双向绑定

<!-- App.vue -> template-->
<template>
<input type="text" placeholder="搜索人名" v-model="searchName" />
<!-- 将方法绑定到按钮上 -->
<button @click="searchUser()">搜索</button>
</template>

useUserStore.js 中加入 搜索方法

searchUser() {
    this.users = this.users.filter(item => item.name == this.searchName)
}

filter函数是一个高阶函数,用它可以更快的筛选出我们想要的内容

# 删除用户

  1. 模拟删除用户
<!-- App.vue -> template -->
<template>
<input type="text" placeholder="搜索人名" v-model="searchName" />
</template>

useUserStore 中加入 搜索方法

delUser(id) {
    this.users = this.users.filter(item => item.id != id)
}

到这里一个用户管理系统就算完成了。


# 完整代码

完整的 useUserStore.js

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
    // state
    state: () => {
        return {
            users: [
                { id: 1, name: '张三', gender: '男', age: '16', date: '2015/10/12' },
                { id: 2, name: '李四', gender: '女', age: '17', date: '2017/10/12' },
                { id: 3, name: '王五', gender: '男', age: '18', date: '2019/10/12' },
                { id: 4, name: '赵六', gender: '女', age: '19', date: '2022/3/30' },
            ],
            searchName: '',
            tempUser: {
                id: '',
                name: '',
                gender: '',
                age: '',
                date: new Date().toLocaleDateString()
            }
        }
    },
    // getters
    getters: {
    },
    // actions
    actions: {
        addUser() {
            // 添加 新用户到 用户列表
            this.users.push(this.tempUser)
            // 清空 新用户字段
            this.tempUser = {
                id: '',
                name: '',
                gender: '',
                age: '',
                date: new Date().toLocaleDateString()
            }
        },
        delUser(id) {
            this.users = this.users.filter(item => item.id != id)
        },
        searchUser() {
            this.users = this.users.filter(item => item.name == this.searchName)
        }

    }
})

完整的 App.vue

<script setup>
import { storeToRefs } from "pinia";
import { useUserStore } from "./store/useUserStore";
const { addUser, delUser, searchUser } = useUserStore();
const { users, tempUser, searchName } = storeToRefs(useUserStore());
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />

  <div class="container">
    <table border="1">
      <tr>
        <td class="no_line">
          <label for="id">序号:</label>
          <input type="text" placeholder="请填写序号" v-model="tempUser.id" />
        </td>
        <td class="no_line">
          <label for="name">姓名:</label>
          <input type="text" placeholder="请填写姓名" v-model="tempUser.name" />
        </td>
        <td class="no_line">
          <label for="gender">性别:</label>
          <input
            type="text"
            placeholder="请填写性别"
            v-model="tempUser.gender"
          />
        </td>
        <td class="no_line">
          <label for="age">年龄:</label>
          <input type="text" placeholder="请填写年龄" v-model="tempUser.age" />
          <button @click="addUser()">添加</button>
        </td>
        <td class="no_line">
          <label for="search">搜索</label>
          <input type="text" placeholder="搜索人名" v-model="searchName" />
          <button @click="searchUser()">搜索</button>
        </td>
      </tr>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>年龄</th>
        <th>时间</th>
        <th>操作</th>
      </tr>
      <tr v-for="item in users" :key="item.id">
        <td>{{ item.id }}</td>
        <td>{{ item.name }}</td>
        <td>{{ item.gender }}</td>
        <td>{{ item.age }}</td>
        <td>{{ item.date }}</td>
        <td><a href="#" @click="delUser(item.id)">删除</a></td>
      </tr>
    </table>
  </div>
</template>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.container {
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-top: 20px;
}
input {
  width: 80px;
}
td {
  padding: 3px 25px;
}
.no_line {
  border: none;
}
</style>

Last Updated: 3/15/2024, 2:13:06 PM