前言
我们将会选择使用一些 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'
- import 'element-ui/lib/theme-chalk/index.css'
- 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
- })
- },
这是时候, 数据是请求到了, 但是页面并为展示, 这就关系到 vue 的生命周期. 如果对 vue 生命周期不是很了解的话, 可以官网仔细看一遍,
我们只需要在 created 这个生命周期钩子中, 调用我们请求数据的方法就可以把数据展示到页面中. 这样我们就完成第一步了, 页面数据请求展示
created: 在模板渲染成 HTML 前调用, 即通常初始化某些属性值, 然后再渲染成视图.
- 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 通过点击父组件的添加按钮触发子组件弹出框
dialogAdd 是我们在父组件定义的的, 需要传递给子组件,
<el-button type="primary" size="small" icon="el-icon-edit-outline" @click="hanldeAdd()"> 添加 </el-button>
在 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>
this.$emit('update'); 子组件数据发生改变了, 父组件视图却没有更新, 这时候通过子创父, this.$emit, 想父组件发送子组件传递的方法,
- <AddUser :dialogAdd="dialogAdd" @update="getUserInfo">
- </AddUser>
- @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
- 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 引入
import moment from 'moment'
我们定义一个全局过滤的 filter, 无论在那个组件都可以使用, 主要调用 moment
- // 获取年份
- 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, 在过程中有些说的不是很好, 请见谅, 如果喜欢, 请多多关注
来源: https://www.cnblogs.com/zhoulifeng/p/9900564.html