使用vue+elementUI+vuex+axios+json-server实现的一个简单用户表格数据的增删改查。效果图如下:
在上一节中已经介绍了vuex如何应用的,需要了解的请去这里。
这一章中,主要介绍实际使用vuex在项目开发中是如何运用的。
本章除了讲解vuex的实战应用外,还将项目中使用到的其他技术也相应的讲解一下。
elementUI
安装:yarn add element-ui(或者npm install element-ui --save-dev)
Element-Ul是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是Mint UI 。
它提供了非常丰富的组件,可以大大提升开发效率。
引入element-ui
import Vue from 'vue'
import App from './App.vue'
import store from './store';
import router from './router'
import Element from 'element-ui' // 引入element-ui
import locale from 'element-ui/lib/locale/lang/en' // 默认语言包是中文
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(Element, { locale }) // 装载到vue上
Vue.config.productionTip = false
/**
* 创建和挂载根实例。
* 记得要通过 router 配置参数注入路由,
* 从而让整个应用都有路由功能
*/
new Vue({
el: '#app',
store,
router,
components: { App },
template: ' '
})
想要知道elementUI具体怎么使用的请查看官网。
axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
注意axios是基于promise实现的,也就是它可以实现.then的链式操作。在实战中就用到了这样的操作。如何使用axios请看这里。
根据上一节vuex 四大核心介绍及实践已经搭建了实现逻辑前的所有工作准备,接下来就是实现具体的逻辑过程。
首先是表格,使用el-table组件,其中的操作有:data数据是由search方法返回的,通过筛选查询的条件改变界面展示的数据,这儿的查询方法并没有使用到vuex,然后是操作时间格式的改变,以及编辑、删除的方法逻辑实现。
<el-table
:data="search()"
stripe
:header-cell-style="{
'background-color': 'rgb(233, 228, 228)',
'border-bottom': '1px solid #409EFF'
}"
border>
<el-table-column prop="id" label="编号">el-table-column>
<el-table-column prop="name" label="姓名" :show-overflow-tooltip="true">el-table-column>
<el-table-column prop="address" label="地址">el-table-column>
<el-table-column prop="date" label="操作时间">
<template slot-scope="scope">
<span>{{timestampToTime(scope.row.date)}}span>
template>
el-table-column>
<el-table-column label="操作">
<template slot-scope="item">
<el-button @click="open(item.row)" type="text">编辑el-button>
<el-button @click="del(item.row.id)" type="text" size="small">删除el-button>
template>
el-table-column>
el-table>
查询输入框实现,利用v-moel绑定value,需要实现添加方法的逻辑
<el-row type="flex" style="margin-bottom: 30px;">
<el-col :span="6">
<el-input placeholder="请输入内容" v-model="value" clearable v-focus v-color="'#409EFF'">
<el-button slot="append" type="primary" icon="el-icon-search">el-button>
el-input>
el-col>
<el-col :span="4" :offset="14">
<el-button type="success" icon="el-icon-plus" @click="open()">添加el-button>
el-col>
el-row>
search方法实现,value为查询条件,list为计算属性(user数组)
search: function() {
let value = this.value;
if (!value) return this.list;
var newList = [];
this.list.forEach(item => {
if (item.name.indexOf(value) != -1) {
newList.push(item);
}
});
return newList;
}
弹出框的逻辑实现,使用组件el-dialog,需实现确定方法的逻辑
<el-dialog title="人员信息" :visible.sync="modelFormVisble" width="400px">
<el-form :model="form">
<el-form-item label="姓名" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off">el-input>
el-form-item>
<el-form-item label="地址" :label-width="formLabelWidth">
<el-input v-model="form.address" autocomplete="off">el-input>
el-form-item>
el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="onOk()">确 定el-button>
<el-button @click="modelFormVisble = false">取 消el-button>
div>
el-dialog>
open方法实现,将弹出框状态modelFormVisble 改为true展示弹出框,这儿有value的传值,如果是点击修改则会传值并将值赋值给form对象,如果是点击的新增则将form的属性都设置为""
open: function(value) {
this.modelFormVisble = true;
if(!value){
this.form.id = this.form.name = this.form.address = "";
return;
}
let form = {
id: value.id,
name: value.name,
address: value.address
}
this.form = form
}
操作时间格式转换,将Date类型的数据转化为字符串格式的时间,时间格式结果如效果图所示
timestampToTime(timestamp) {
var date = new Date(timestamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear() + "-";
var M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
var h = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
var m = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
var s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return Y + M + D + h + m + s;
}
界面实现和相关需要实现的逻辑已经罗列出来。需要实现的方法逻辑有获取、新增、编辑以及删除。
逻辑实现
1. 获取
list设置为计算属性,当在getter中定义的user改变时就将list更新。然后界面初始化时,定义在state中的user是空数组,所以需要用到一个生命周期钩子mounted在界面渲染时去获取到user数组的数据。getUserList是在vue中的method定义的方法,它是通过store dispatch去触发action函数。
mounted: function(){
this.getUserList();
},
computed:{ // 通过计算属性获取
list(){
return this.$store.getters.user;
}
},
methods: {
getUserList: function(){
this.$store.dispatch('getUserAction')
},
...
}
action定义的获取方法,在.then中触发mutation方法,来提交(commit)去改变store中的状态,response.data为返回来的最新值
let axios = require('axios') // 导入axios
export const getUserAction = function(context){
axios.get('/user')
.then(function (response) {
console.log('调用action的方法');
context.commit('getUserList', response.data);
})
.catch(function (error) {
console.log(error);
});
}
mutation中的方法,将返回来的最新user数据赋值给state中的user对象,这时计算属性监测到getter的变化从而去获取新的数据渲染界面。
const mutation = {
// user方法逻辑
getUserList: (state, user) => {
state.user = user
},
...
}
export default mutation;
2. 编辑、修改
当在弹出框点击确定时触发onOK函数,具体实现如下:
onOk(){
if (!this.form.name) {
this.$message({
message: "名字不能为空!",
type: "warning"
});
return;
}
this.modelFormVisble = false;
var user = {
id: this.form.id,
name: this.form.name,
address: this.form.address,
date: new Date()
}
if(this.form.id){ // 修改
this.$store.dispatch('updateUserAction' ,user).then(() => {
this.getUserList();
});
}else{ // 新增
let len = this.list.length;
let id = 1;
if(len > 0){
id = this.list[len - 1].id + 1;
}
user.id = id;
this.$store.dispatch('addUserAction' ,user).then(() => {
this.getUserList();
});
}
}
通过判断form对象中id是否存在来确定新增还是修改,dispatch不同的action函数。注意触发action后将会改变数据,在这儿的实现是使用.then的形式刷新数据,减少了mutation的逻辑实现。所以在action中注释了commit这部分的代码。如果想要了解mutation的实现请去这里。
新增、修改action方法
export const addUserAction = function(context, user){
axios.post('/user',user)
.then(function (response) {
console.log(response, '新增之后的返回值');
// context.commit('addUser', response.data);
})
.catch(function (error) {
console.log(error);
});
}
export const updateUserAction = function(context, user){
axios.put('/user/'+ user.id, user)
.then(function (response) {
console.log(response, '修改之后的返回值');
// context.commit('updateUser', user);
})
.catch(function (error) {
console.log(error);
});
}
3. 删除
最后一个则是删除方法的逻辑实现。
vue method中定义删除方法
del: function(id) {
this.$store.dispatch('deleteUserAction', id).then(() => {
this.getUserList();
});
}
通过dispatch分发删除的action方法
export const deleteUserAction = function(context, id){
axios.delete('/user/'+ id)
.then(function (response) {
console.log('调用action的方法');
console.log(response, '删除之后的返回值');
// context.commit('deleteUser', id);
})
.catch(function (error) {
console.log(error);
});
}
至此,所有的逻辑方法全部实现完毕,再来看一下效果图,是不是很有成就感O(∩_∩)O哈哈~
vuex 四大核心介绍及实践
深入浅出 Vue.js 学习笔记–生命周期
Element组件
Axios中文说明
GitHub源码地址