前言
我们将会选择使用一些 vue 周边的库vue-cli, vue-router,axios,moment,Element-ui搭建一个前端项目案例,后端数据接口,会使用json-server快速搭建一个本地的服务,方便对数据的增删改查,
利用以上技术我们会搭建一个vue案例,效果展示图:
以上就是我们最终要实现的全部效果,我会一块一块的讲解,关于脚手架安装和json-server搭建,在本次博客中,不会讲解,如果想看的话,在小编的博客中,也有讲解关于脚手架搭建和json-server搭建,如果想学习的话,可以看一下。
1.项目结构展示
左边第一个是前端项目结构,第二个为json-server服务端
2.页面搭建
在本次案例中,小编采用Element-ui快速搭建前端页面,以提高效率。如果不了解的话,可以去官网看一下
2.1安装element-ui
通过npm install element-ui -S 安装前端ul框架,安装完之后,并在main.js引入
import
ElementUI from
'element-ui'
<br>
import
'element-ui/lib/theme-chalk/index.css'
<br><br>Vue.use(ElementUI)
2.2页面布局UserInfo.vue
直接通过element-ui中table布局,把整体建构页面布局完成,
<h1>用户信息管理界面</h1> <el-row> <el-col :span= "20" :push= '2' > <div> <el-form :inline= "true" > <el-form-item style= "float: left" label= "查询用户信息:" > <el-input v-model= "keyUser" placeholder= "查询所需要的内容......" ></el-input> </el-form-item> <el-form-item style= "float: right" > <el-button type= "primary" size= "small" icon= "el-icon-edit-outline" @click= "hanldeAdd()" >添加</el-button> </el-form-item> </el-form> </div> <div class = "table" > <el-table :data= "searchUserinfo(keyUser)" border style= "width: 100%" > <el-table-column type= "index" label= "序号" align= "center" width= "60" > </el-table-column> <el-table-column label= "日期" align= "center" width= "120" > <template slot-scope= "scope" > <span>{{ scope.row.date | moment}}</span> </template> </el-table-column> <el-table-column label= "姓名" align= "center" width= "100" > <template slot-scope= "scope" > <span>{{ scope.row.name }}</span> </template> </el-table-column> <el-table-column label= "邮箱" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.email }}</span> </template> </el-table-column> <el-table-column label= "标题" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.title }}</span> </template> </el-table-column> <el-table-column label= "评价" align= "center" width= "200" > <template slot-scope= "scope" > <span>{{ scope.row.evaluate }}</span> </template> </el-table-column> <el-table-column label= "状态" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.state }}</span> </template> </el-table-column> <el-table-column label= "操作" fixed= "right" > <template slot-scope= "scope" > <el-button size= "mini" @click= "handleEdit(scope.$index, scope.row)" >编辑</el-button> <el-button size= "mini" type= "danger" @click= "handleDelete(scope.$index, scope.row)" >删除</el-button> </template> </el-table-column> </el-table> </div> </el-col> </el-row> |
2.3页面数据获取并展示
通过axios请求本地搭建的服务数据,把得到的数据展示到页面当中。
也是通过cnpm install axios --save安装并在main.js中引入
import axios from 'axios' Vue.prototype.$axios = axios |
我们需要在方法methods中定义一个getUserInfo方法,用于请求数据
date () { return { tableData: [], 用于存放数据 } }
getUserInfo() { this .$axios.get( 'http://localhost:3000/data' ).then(res => { this .tableData = res.data }) }, |
1 | 这是时候,数据是请求到了,但是页面并为展示,这就关系到vue的生命周期。如果对vue生命周期不是很了解的话,可以官网仔细看一遍, |
1 | 我们只需要在created这个生命周期钩子中,调用我们请求数据的方法就可以把数据展示到页面中。这样我们就完成第一步了,页面数据请求展示<br>created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。 |
123 | created(){ this .getUserInfo() }, |
3.添加数据
刚才我们已经完成第一步,把后台的数据展示到前端页面中,接下来我们对数据进行添加,页面全部都是用element搭建
3.1页面结构搭建,把AddUserInfo.vue组件当成一个子组件,在父组件中引入这个子组件,点击添加按钮,弹出这个添加对话框
<template> <div class = "hello" > <el-dialog title= "添加用户信息" :visible.sync= "dialogAdd.show" > <el-form :model= "formDate" ref= "formdong" label-width= "100px" :rules= "formrules" > <el-form-item label= "日期" prop= "date" > <el-date-picker v-model= "formDate.date" type= "date" placeholder= "选择日期" > </el-date-picker> </el-form-item> <el-form-item label= "姓名" prop= "name" > <el-input v-model= "formDate.name" ></el-input> </el-form-item> <el-form-item label= "邮箱" prop= "email" > <el-input v-model= "formDate.email" ></el-input> </el-form-item> <el-form-item label= "标题" prop= "title" > <el-input v-model= "formDate.title" ></el-input> </el-form-item> <el-form-item label= "评价" prop= "evaluate" > <el-input v-model= "formDate.evaluate" ></el-input> </el-form-item> <el-form-item label= "状态" prop= "state" > <el-input v-model= "formDate.state" ></el-input> </el-form-item> </el-form> <div slot= "footer" class = "dialog-footer" > <el-button @click= "dialogAdd.show = false" >取 消</el-button> <el-button type= "primary" @click= "dialogFormAdd('formdong')" >确 定</el-button> </div> </el-dialog> </div> </template> |
3.2我们在父组件UserInfo中引入子组件AddUserInfo.vue,
3.<AddUser :dialogAdd="dialogAdd" @update="getUserInfo"></AddUser> //使用这个组件,1. import AddUser from './AddUserInfo.vue' //引入组件 2. components:{ //注册 AddUser, }
3.3通过点击父组件的添加按钮触发子组件弹出框
1 | dialogAdd是我们在父组件定义的的,需要传递给子组件, |
<el-button type= "primary" size= "small" icon= "el-icon-edit-outline" @click= "hanldeAdd()" >添加</el-button><br> 在data定义用于是否弹出添加弹出框,默认 false 不弹出,只有点击添加按钮的时候才弹出弹出框 dialogAdd:{ show: false }, methods方法中 hanldeAdd(){ //添加 this .dialogAdd.show = true ; //弹出对话框 }, |
3.4子组件需要接受父组件传递的方法.并请求数据。实现添加
<script> export default { name: 'AddUser' , props:{ dialogAdd:Object }, data () { return { formDate:{ date: '' , name: '' , email: '' , title: '' , evaluate: '' , state: '' }, formrules:{ date:[{required: true ,message: "日期不能为空" ,trigger: "blur" }], name:[{required: true ,message: "用户名不能为空" ,trigger: "blur" }], email:[{required: true ,message: "邮箱不能为空" ,trigger: "blur" }], } } }, methods:{ dialogFormAdd(formdong) { this .$refs[formdong].validate((valid) => { if (valid) { this .$axios.post( 'http://localhost:3000/data' , this .formDate).then(res => { this .$message({ type: "success" , message: "添加信息成功" }) this .dialogAdd.show = false ; this .$emit( 'update' ); }) this .formDate = "" } else { console.log( 'error submit!!' ); return false ; } }) } } } </script> |
1 | <span style= "font-size: 14px" > this .$emit( 'update' ); 子组件数据发生改变了,父组件视图却没有更新,这时候通过子创父, this .$emit,想父组件发送子组件传递的方法,</span> |
1 | <AddUser :dialogAdd= "dialogAdd" @update= "getUserInfo" ></AddUser> |
1 | @update= "getUserInfo" //接受子组件传递过来的方法去更新视图 |
4.实现删除
<el-button size= "mini" type= "danger" @click= "handleDelete(scope.$index, scope.row)" >删除</el-button> |
删除数据需要根据id去删除,使用es6模板字符串进行拼接
handleDelete(index,row) { // 删除用户信息 this .$axios. delete (`http: //localhost:3000/data/${row.id}`).then(res =>{ this .$message({ type: "success" , message: "删除信息成功" }) this .getUserInfo() //删除数据,更新视图 }) }, |
5.实现编辑功能
在这里添加弹出框内容和编辑弹出框内容一模一样,可以选择进行封装,封装成一个组件,添加和编辑共同使用这一个组件,根据自定义一个字段来判断点击 的是添加还是编辑按钮。在本次案例中,没有封装,如果想封装的话,可以自己尝试封装组件,来提高效率。
5.1页面搭建EditUser.vue组件,也是当做一个子组件,在父组件中去引入这个子组件,并把获取的数据展示到页面中。
<template> <div class = "hello" > <el-dialog title= "编辑用户信息" :visible.sync= "dialogEdit.show" > <el-form :model= "form" ref= "formEdit" label-width= "100px" :rules= "formrules" > <el-form-item label= "日期" prop= "date" > <el-date-picker v-model= "form.date" type= "date" placeholder= "选择日期" > </el-date-picker> </el-form-item> <el-form-item label= "姓名" prop= "name" > <el-input v-model= "form.name" ></el-input> </el-form-item> <el-form-item label= "邮箱" prop= "email" > <el-input v-model= "form.email" ></el-input> </el-form-item> <el-form-item label= "标题" prop= "title" > <el-input v-model= "form.title" ></el-input> </el-form-item> <el-form-item label= "评价" prop= "evaluate" > <el-input v-model= "form.evaluate" ></el-input> </el-form-item> <el-form-item label= "状态" prop= "state" > <el-input v-model= "form.state" ></el-input> </el-form-item> </el-form> <div slot= "footer" class = "dialog-footer" > <el-button @click= "dialogEdit.show = false" >取 消</el-button> <el-button type= "primary" @click= "dialogFormEdit('formEdit')" >确 定</el-button> </div> </el-dialog> </div> </template> |
在父组件中定义好需要传递的数据字段
dialogAdd:{ //编辑弹出框,默认是false show: false }, form:{ //编辑信息 date: '' , name: '' , email: '' , title: '' , evaluate: '' , state: '' }, |
5.2也是在方法中点击编辑按钮,在编辑中,点击拿一行,需要获取那一行的字段数据,并把获取的数据传递给子组件显示到弹出框中,需要肯据row,来获取每一行的数据。
<el-button size= "mini" @click= "handleEdit(scope.$index, scope.row)" >编辑</el-button> <el-button<br> handleEdit(index,row){ //编辑 this .dialogEdit.show = true ; //显示弹 this .form = { date:row.date, name:row.name, email:row.email, title:row.title, evaluate:row.evaluate, state:row.state, id:row.id } }, |
当我门打印row的是,就是点击哪一行的编辑按钮,对应的数据就好打印出来,这时候我们只需要把得到的数据传递给子组件就行
5.3父组件得到的数据,子组件通过props接受,和添加数据几乎一样
<script> export default { name: 'HelloWorld' , props:{ dialogEdit:Object, form:Object }, data () { return { formrules:{ date:[{required: true ,message: "日期不能为空" ,trigger: "blur" }], name:[{required: true ,message: "用户名不能为空" ,trigger: "blur" }], email:[{required: true ,message: "邮箱不能为空" ,trigger: "blur" }], } } }, methods:{ dialogFormEdit(formEdit) { this .$refs[formEdit].validate((valid) => { if (valid) { this .$axios.put(`http: //localhost:3000/data/${this.form.id}`,this.form).then(res => { this .$message({ type: "success" , message: "编辑信息成功" }) console.log(res) this .dialogEdit.show = false ; this .$emit( 'updateEdit' ) //更新父组件数据视图 }) } else { console.log( 'error submit!!' ); return false ; } }) } } } </script> |
6查询数据
<el-form-item style= "float: left" label= "查询用户信息:" > <el-input v-model= "keyUser" placeholder= "查询所需要的内容......" ></el-input> </el-form-item> |
6.1需要定义一个查询方法,通过filter对数组进行过滤,并返回一个新的数据,最后通过es6中includes方法,判断查询的条件是否包含,includes如果包含就返回true,如果不包含就返回false
searchUserinfo(keyUser) { return this .tableData.filter((user) => { if (user.name.includes(keyUser)) { return user } }) } |
把定义好的方法,绑定到data,因为这个方法会返回一个新的数组
7.时间格式化
写到这个案例已经基本写完了,还是一些细节需要修改,比如我我们添加日期,页面显示并不是我们想要的。我门只想要右边的效果.
这时候推荐一个日期格式化插件moment.js,可以快速帮我们解决这个问题
7.1通过npm install moment --save下载
在main.js引入
1 | import moment from 'moment' |
我们定义一个全局过滤的filter,无论在那个组件都可以使用,主要调用moment
12345 | //获取年份 Vue.filter( 'moment' , function (value, formatString) { formatString = formatString || 'YYYY-MM-DD HH:mm:ss' ; return moment(value).format( "YYYY-MM-DD" ); // value可以是普通日期 20170723 }); |
8.全部代码
8.1UserInfo.vue组件代码
<template> <div class = "info" > <h1>用户信息管理界面</h1> <el-row> <el-col :span= "20" :push= '2' > <div> <el-form :inline= "true" > <el-form-item style= "float: left" label= "查询用户信息:" > <el-input v-model= "keyUser" placeholder= "查询所需要的内容......" ></el-input> </el-form-item> <el-form-item style= "float: right" > <el-button type= "primary" size= "small" icon= "el-icon-edit-outline" @click= "hanldeAdd()" >添加</el-button> </el-form-item> </el-form> </div> <div class = "table" > <el-table :data= "searchUserinfo(keyUser)" border style= "width: 100%" > <el-table-column type= "index" label= "序号" align= "center" width= "60" > </el-table-column> <el-table-column label= "日期" align= "center" width= "120" > <template slot-scope= "scope" > <span>{{ scope.row.date | moment}}</span> </template> </el-table-column> <el-table-column label= "姓名" align= "center" width= "100" > <template slot-scope= "scope" > <span>{{ scope.row.name }}</span> </template> </el-table-column> <el-table-column label= "邮箱" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.email }}</span> </template> </el-table-column> <el-table-column label= "标题" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.title }}</span> </template> </el-table-column> <el-table-column label= "评价" align= "center" width= "200" > <template slot-scope= "scope" > <span>{{ scope.row.evaluate }}</span> </template> </el-table-column> <el-table-column label= "状态" align= "center" width= "160" > <template slot-scope= "scope" > <span>{{ scope.row.state }}</span> </template> </el-table-column> <el-table-column label= "操作" fixed= "right" > <template slot-scope= "scope" > <el-button size= "mini" @click= "handleEdit(scope.$index, scope.row)" >编辑</el-button> <el-button size= "mini" type= "danger" @click= "handleDelete(scope.$index, scope.row)" >删除</el-button> </template> </el-table-column> </el-table> </div> </el-col> </el-row> <AddUser :dialogAdd= "dialogAdd" @update= "getUserInfo" ></AddUser> <EditUser :dialogEdit= "dialogEdit" :form= "form" @updateEdit= "getUserInfo" ></EditUser> </div> </template> <script> import AddUser from './AddUser.vue' import EditUser from './EditUser.vue' export default { name: 'info' , data () { return { tableData:[], dialogEdit:{ show: false , }, dialogAdd:{ show: false }, keyUser: "" , form:{ //编辑信息 date: '' , name: '' , email: '' , title: '' , evaluate: '' , state: '' }, } }, methods:{ getUserInfo() { this .$axios.get( 'http://localhost:3000/data' ).then(res => { console.log(res) this .tableData = res.data }) }, hanldeAdd(){ //添加 this .dialogAdd.show = true ; }, handleEdit(index,row){ //编辑 this .dialogEdit.show = true ; //显示弹 this .form = { date:row.date, name:row.name, email:row.email, title:row.title, evaluate:row.evaluate, state:row.state, id:row.id } console.log(row) }, handleDelete(index,row) { // 删除用户信息 this .$axios. delete (`http: //localhost:3000/data/${row.id}`).then(res =>{ this .$message({ type: "success" , message: "删除信息成功" }) this .getUserInfo() //删除数据,更新视图 }) }, searchUserinfo(keyUser) { return this .tableData.filter((user) => { if (user.name.includes(keyUser)) { return user } }) } }, created(){ this .getUserInfo() }, components:{ AddUser, EditUser } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h1{ font-size: 30px; color: #333; text-align: center; margin: 0 auto; padding-bottom: 5px; border-bottom: 2px solid #409EFF; width: 300px } </style> |
8.2AddUserInfo.vue组件
<template> <div class = "hello" > <el-dialog title= "添加用户信息" :visible.sync= "dialogAdd.show" > <el-form :model= "formDate" ref= "formdong" label-width= "100px" :rules= "formrules" > <el-form-item label= "日期" prop= "date" > <el-date-picker v-model= "formDate.date" type= "date" placeholder= "选择日期" > </el-date-picker> </el-form-item> <el-form-item label= "姓名" prop= "name" > <el-input v-model= "formDate.name" ></el-input> </el-form-item> <el-form-item label= "邮箱" prop= "email" > <el-input v-model= "formDate.email" ></el-input> </el-form-item> <el-form-item label= "标题" prop= "title" > <el-input v-model= "formDate.title" ></el-input> </el-form-item> <el-form-item label= "评价" prop= "evaluate" > <el-input v-model= "formDate.evaluate" ></el-input> </el-form-item> <el-form-item label= "状态" prop= "state" > <el-input v-model= "formDate.state" ></el-input> </el-form-item> </el-form> <div slot= "footer" class = "dialog-footer" > <el-button @click= "dialogAdd.show = false" >取 消</el-button> <el-button type= "primary" @click= "dialogFormAdd('formdong')" >确 定</el-button> </div> </el-dialog> </div> </template> <script> export default { name: 'AddUser' , props:{ dialogAdd:Object }, data () { return { formDate:{ date: '' , name: '' , email: '' , title: '' , evaluate: '' , state: '' }, formrules:{ date:[{required: true ,message: "日期不能为空" ,trigger: "blur" }], name:[{required: true ,message: "用户名不能为空" ,trigger: "blur" }], email:[{required: true ,message: "邮箱不能为空" ,trigger: "blur" }], } } }, methods:{ dialogFormAdd(formdong) { this .$refs[formdong].validate((valid) => { if (valid) { this .$axios.post( 'http://localhost:3000/data' , this .formDate).then(res => { this .$message({ type: "success" , message: "添加信息成功" }) this .dialogAdd.show = false ; this .$emit( 'update' ); }) this .formDate = "" } else { console.log( 'error submit!!' ); return false ; } }) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style> |
8.3EditUser.vue编辑组件
<template> <div class = "hello" > <el-dialog title= "编辑用户信息" :visible.sync= "dialogEdit.show" > <el-form :model= "form" ref= "formEdit" label-width= "100px" :rules= "formrules" > <el-form-item label= "日期" prop= "date" > <el-date-picker v-model= "form.date" type= "date" placeholder= "选择日期" > </el-date-picker> </el-form-item> <el-form-item label= "姓名" prop= "name" > <el-input v-model= "form.name" ></el-input> </el-form-item> <el-form-item label= "邮箱" prop= "email" > <el-input v-model= "form.email" ></el-input> </el-form-item> <el-form-item label= "标题" prop= "title" > <el-input v-model= "form.title" ></el-input> </el-form-item> <el-form-item label= "评价" prop= "evaluate" > <el-input v-model= "form.evaluate" ></el-input> </el-form-item> <el-form-item label= "状态" prop= "state" > <el-input v-model= "form.state" ></el-input> </el-form-item> </el-form> <div slot= "footer" class = "dialog-footer" > <el-button @click= "dialogEdit.show = false" >取 消</el-button> <el-button type= "primary" @click= "dialogFormEdit('formEdit')" >确 定</el-button> </div> </el-dialog> </div> </template> <script> export default { name: 'HelloWorld' , props:{ dialogEdit:Object, form:Object }, data () { return { formrules:{ date:[{required: true ,message: "日期不能为空" ,trigger: "blur" }], name:[{required: true ,message: "用户名不能为空" ,trigger: "blur" }], email:[{required: true ,message: "邮箱不能为空" ,trigger: "blur" }], } } }, methods:{ dialogFormEdit(formEdit) { this .$refs[formEdit].validate((valid) => { if (valid) { this .$axios.put(`http: //localhost:3000/data/${this.form.id}`,this.form).then(res => { this .$message({ type: "success" , message: "编辑信息成功" }) console.log(res) this .dialogEdit.show = false ; this .$emit( 'updateEdit' ) }) } else { console.log( 'error submit!!' ); return false ; } }) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style> |
以上这次全部的案例deom,在过程中有些说的不是很好,请见谅,如果喜欢,请多多关注
共同学习,写下你的评论
评论加载中...
作者其他优质文章