Vue.js 搭建用户管理系统

目录

一、前言

二、搭建项目过程

2.1 配置json-server

2.2 新建vue项目

2.3 项目目录解析

2.4 初探组件,搭建导航

2.5 获取并展示用户信息

2.6 添加用户

2.7 弹窗及详情

2.7.1 弹窗 alert.vue组件

2.7.2 详情组件 customersdetails.vue

2.8 编辑和删除

2.8.1 编辑Edit. vue组件

2.8.2 删除用户信息

 2.9 实现搜索功能

三、总结


一、前言

通过编写一个简单的用户管理系统,实现用户信息的增删改查,熟悉Vue的开发流程。整个项目的实现基于Vue全家桶技术及bootstrap页面布局。

二、搭建项目过程

2.1 配置json-server

开始之前我们要做一个准备工作,在做项目中我们常常无法获取后端的数据,此时就要配置mock数据来模拟请求以及请求回来的过程。json-server是一个很好的可以替我们完成这一工作的工具。我们只需要提供一个json文件,或者写几行简单的js脚本就可以模拟出RESTful API的接口

  • 安装json-server
cnpm install -g json-server --save
  • 创建db.json文件

这是我们在项目中用到的数据

{
  "users": [
    {
      "name": "Alice",
      "phone": "333-444-555",
      "email": "canidy@ewsdsd.com",
      "education": "dsds",
      "graduationschool": "dsds",
      "profession": "dsds",
      "profile": "dsds",
      "id": "1"
    },
    {
      "name": "Back",
      "phone": "333-444-555",
      "email": "canidy@ewsdsd.com",
      "education": "dsds",
      "graduationschool": "dsds",
      "profession": "dsds",
      "profile": "dsds",
      "id": "2"
    },
    {
      "name": "json",
      "phone": "333-444-555",
      "email": "canidy@ewsdsd.com",
      "education": "dsds",
      "graduationschool": "dsds",
      "profession": "dsds",
      "profile": "dsds",
      "id": "3"
    },
    {
      "name": "cookie",
      "phone": "333-444-555",
      "email": "canidy@ewsdsd.com",
      "education": "dsds",
      "graduationschool": "dsds",
      "profession": "dsds",
      "profile": "dsds",
      "id": "4"
    },
    {
      "name": "小惠惠",
      "phone": "15829705916",
      "email": "1269146785@qq.com",
      "education": "博士",
      "graduationschool": "交通大学",
      "profession": "MBA",
      "profile": "真好看",
      "id": "5"
    }
  ]
  
}
  • 在浏览器中运行 JSON Server
json-server --watch db.json

如果我们每次查看json文件,都这样输一次就比较麻烦,所以我们进行改进,在package.json 文件中的"scripts"内容中添加

 "scripts": {
    "json": "json-server --watch db.json",
  },

这样我们就可以使用 cnpm run json 运行

关于json-server具体内容可参考https://www.npmjs.com/package/json-server

2.2 新建vue项目

  • 下载Node.js
  • 安装淘宝镜像
 npm install -g cnpm --registry=https://registry.npm.taobao.org
 cnpm install cnpm -g   //升级淘宝镜像
  • 安装脚手架
cnpm install –g vue-cli 
  • 开启新项目
vue init webpack-simple vcustomers
cd vcustomers
cnpm install
cnpm run dev

2.3 项目目录解析

2.4 初探组件,搭建导航

利用vue的页面组件化思想,将页面切换成几个部分,从而有利于页面的拼装以及代码的维护

  • App.vue组件

App.vue是我们的主组件,所有页面都是在App.vue下进行切换的,在主组件中搭建导航部分

<template>
  <div id="app">
  <nav class="navbar navbar-default">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">用户管理系统</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li><router-link to="/">主页</router-link></li>
            <li><router-link to="/about">关于我们</router-link></li>
          </ul>
            <ul class="nav navbar-nav navbar-right">
               <li><router-link to="/add">添加用户</router-link></li>
             </ul>
        </div>
      </div>
    </nav>
    <router-view></router-view>
  </div>
</template>

<script>
import customers from "./Components/Customers.vue";
import about from "./Components/About.vue";
export default {
  name: "app",
  components: {
    customers: customers,
    about: about
  },
  data() {
    return {
      msg: "我是App组件"
    };
  }
};
</script>

<style lang="scss">
</style>

 

  • 安装及封装路由

具体就不介绍啦,在之前的博客中有详细的路由配置,传参,封装的文章

import Vue from "vue";
import vueRouter from "vue-router"
// 引入组件
import customers from "../Components/Customers.vue";
import about from "../Components/About.vue";
import add from "../Components/add.vue";
import detail from "../Components/Customersdetail.vue";
import edit from "../Components/Edit.vue"
//使用路由
Vue.use(vueRouter)
///配置路由
const routes=[
{
    path:'/',
    component:customers
},
{
    path:'/about',
    component:about
},
{
    path:'/add',
    component:add
},
{
    path:'/detail/:id',
    component:detail
},
{
    path:'/edit/:id',
    component:edit
},
]
//实例化路由
var router=new vueRouter({
    routes:routes
})
//暴露路由
export default router;
  • vue-resource请求数据

在main.js中引入使用vue-resource,要记得先安装哦 cnpm install vue-resource --save

// 1.使用路由模块化封装
import Vue from 'vue'
import App from './App.vue'

//导入vue-resource
import vueResource from 'vue-resource'
//使用resource
Vue.use(vueResource)

//导入路由
import router from ".//Router/Router.js"

//实例挂载路由
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

2.5 获取并展示用户信息

使用vue-resource提供的this.$http.get(url)方法来获取用户信息,通过循环遍历绑定,将数据显示在界面中

<template>
  <div id="customers" class="container">
   <!--弹窗组件 -->   <!-- :message  父组件给子组件传值 -->
    <alert v-if="content" :message="content"></alert>
    
    <h1 class="page-header">用户管理系统</h1>
  <!--v-model 数据双向绑定 -->
    <input type="text" class="form-control" placeholder="搜索" v-model="search">
    <table class="table table-striped">
      <thead>
        <tr>
          <th>姓名</th>
          <th>电话</th>
          <th>邮箱</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
    <!--循环遍历数组 绑定信息 -->
        <tr v-for="(customer,index) in filterBy(customers,search)" :key="index">
          <td>{{customer.name}}</td>
          <td>{{customer.phone}}</td>
          <td>{{customer.email}}</td>
          <td>

            <router-link class="btn btn-default" :to="'/detail/'+customer.id">详情</router-link>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import alert from "./Alert.vue";
import detail from "./Customersdetail.vue";
export default {
  components: {
    alert: alert,
    detail: detail
  },
  data() {
    //这里存放数据
    return {
      msg: "我是customers组件",
      customers: [],
      content: "",
      search: ""
    };
  },
  methods: {
    filterBy(customers, value) {
      return customers.filter(function(customer) {
        return customer.name.match(value);
        //有就返回,没有就不显示    什么都不输就显示所有
        //filter()过滤 只能用于数组
      });
    },
      //获取用户信息
    fetchCustomers() {
      this.$http.get("http://localhost:3000/users").then(res => {
        this.customers = res.body;
      });
    }
  },

  // 页面加载以后直接调用函数   挂载数据,绑定事件等等
  created() {
    if (this.$route.query.content) {
      this.content = this.$route.query.content;
    }
    this.fetchCustomers();
  },
//信息更新以后,再重新获取用户信息进行绑定
  updated() {
    this.fetchCustomers();
  },

  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {}
};
</script>
<style lang='scss'>
</style>

2.6 添加用户

v-model实现数据双向绑定

使用vue-resource 提供的this.$http.post(url,[data])方法来请求添加数据

<template>
  <div id="add" class="container">
     <alert v-if="content" :message="content"></alert>
    <form v-on:submit="addCustomer">
      <div class="well">
        <h4>用户信息</h4>
        <div class="form-groups">
          <lable>姓名</lable>
          <input type="text" class="form-control" placeholder="name" v-model="customer.name">
        </div>
        <div class="form-group">
          <lable>电话</lable>
          <input type="text" class="form-control" placeholder="phone" v-model="customer.phone">
        </div>
        <div class="form-group">
          <lable>邮箱</lable>
          <input type="text" class="form-control" placeholder="email" v-model="customer.email">
        </div>
        <div class="form-group">
          <lable>学历</lable>
          <input
            type="text"
            class="form-control"
            placeholder="education"
            v-model="customer.education"
          >
        </div>
        <div class="form-group">
          <lable>毕业学校</lable>
          <input
            type="text"
            class="form-control"
            placeholder="graduationschool"
            v-model="customer.graduationschool"
          >
        </div>
        <div class="form-group">
          <lable>职业</lable>
          <input
            type="text"
            class="form-control"
            placeholder="profession"
            v-model="customer.profession"
          >
        </div>
        <div class="form-group">
          <lable>个人简介</lable>
          <textarea class="form-control" rows="10" placeholder="profile" v-model="customer.profile"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">添加</button>
        <span class="pull-right">
         <router-link  class="btn btn-primary" to="/">返回</router-link>
        </span>
      </div>
    </form>
  </div>
</template>

<script>
import alert from "./Alert.vue"

export default {
  components: {
    alert:alert
  },
  data() {
    //这里存放数据
    return {
      msg: "我是add组件",
      customer: {},
      content:""
    };
  },
  methods: {
    addCustomer(e) {
      //  判断这三项内容是否有值 
      if (!this.customer.name || !this.customer.phone || !this.customer.email) {
        this.content="请添加对应的信息!";
      } else {
         //定义对象 设置对象属性
        let newCuetomer = {
          name: this.customer.name,
          phone: this.customer.phone,
          email: this.customer.email,
          education: this.customer.education,
          graduationschool: this.customer.graduationschool,
          profession: this.customer.profession,
          profile: this.customer.profile
        };


        //使用vue-resource post请求 添加数据
        this.$http.post("http://localhost:3000/users",newCuetomer).then(res => {
          this.$router.push({path:"/",query:{content:"用户信息添加成功!"}})
          //路由的编程式导航
          //子组件给父组件传值
        });
      }
      e.preventDefault();
      //阻止表单提交默认事件
     
    },
    //生命周期 - 挂载完成(可以访问DOM元素)
    mounted() {},
  }
};
</script>
<style lang='scss'>
</style>

js阻止表单提交的默认行为

有时候我们在表单进行提交前需要进行表单验证,如果验证不通过,那么就需要阻止表单提交的默认行为,我们介绍俩种方式:
        第一种方式就是在按钮上绑定click事件,return false就会阻止默认行为
        第二种通过submit事件,通过调用event.preventDefault();方法来阻止默认行为。
 

2.7 弹窗及详情

2.7.1 弹窗 alert.vue组件

  • 在父组件中调用alert.vue组件,用v-if判断是否有值,若有值则显示弹窗
<alert v-if="content" :message="content"></alert>
<!-- :message  父组件给子组件传值 -->
  • 在父组件中定义变量content ,来接收从其他组件传的值,
  created() {
    if (this.$route.query.content) {
      this.content = this.$route.query.content;
    }
    this.fetchCustomers();
  },
<template>
  <div class="alert alert-warning alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
    <!-- 弹窗输出的内容-->
     {{message}}
  </div>
</template>

<script>
export default {
  props: ["message"],
  name: "",
  components: {},
  data() {
    //这里存放数据
    return {
      alert: "用户信息添加成功!"
    };
  },
  methods: {},
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {}
};
</script>
<style lang='scss'>
</style>

2.7.2 详情组件 customersdetails.vue

这个组件中有用户的详细信息以及编辑和删除功能

在父组件customers.vue中跳转详情路由时要传递用户id,并且在配置详情路由是也要绑定id

//customers.vue组件循环绑定数据   filterBy()是一个方法
<tbody>
        <tr v-for="(customer,index) in filterBy(customers,search)" :key="index">
          <td>{{customer.name}}</td>
          <td>{{customer.phone}}</td>
          <td>{{customer.email}}</td>
          <td>
            <router-link class="btn btn-default" :to="'/detail/'+customer.id">详情</router-link>
          </td>
        </tr>
      </tbody>
//配置路由
{
    path:'/detail/:id',
    component:detail
},
<template>
  <div class="details container">
    <router-link to="/" class="btn btn-default">返回</router-link>
    <h1 class="page-header">
      {{customers.name}}
      <span class="pull-right">
        <router-link class="btn btn-primary" :to="'/edit/'+customers.id">编辑</router-link>
        <button class="btn btn-danger" @click="deleteCustomer(customers.id)">删除</button>
      </span>
    </h1>

    <ul class="list-group">
      <li class="list-group-item">
        <span class="glyphicon glyphicon-user"> {{customers.phone}}</span>
      </li>
      <li class="list-group-item">
        <span class="glyphicon glyphicon-envelope"> {{customers.email}}</span>
      </li>
    </ul>
    <ul class="list-group">
      <li class="list-group-item">
        <span class="glyphicon glyphicon-star"> {{customers.education}}</span>
      </li>
      <li class="list-group-item">
        <span class="glyphicon glyphicon-cloud"> {{customers.graduationschool}}</span>
      </li>
      <li class="list-group-item">
        <span class="glyphicon glyphicon-th-list"> {{customers.profession}}</span>
      </li>
      <li class="list-group-item">
        <span class="glyphicon glyphicon-cloud"> {{customers.profile}}</span>
      </li>
    </ul>
  </div>
</template>

<script>
import edit from "./Edit.vue";
export default {
  name: "detail",
  components: {
    edit: edit
  },
  data() {
    //这里存放数据
    return {
      msg: "我是detail组件",
      customers: ""
    };
  },
  methods: {

  //获取用户的详细信息
    fetchCustomers(id) {
      this.$http.get("http://localhost:3000/users/" + id).then(res => {
        this.customers = res.body;
      });
    },
    deleteCustomer(id) {
      this.$http.delete("http://localhost:3000/users/" + id).then(res => {
        this.$router.push({
          path: "/",
          query: { content: "成功删除用户信息!" }
        });
      });
    }
  },
  created() {
  //接收路由跳转时传的id值
    this.fetchCustomers(this.$route.params.id);
  },
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {}
};
</script>
<style lang='scss'>
</style>

2.8 编辑和删除

2.8.1 编辑Edit. vue组件

编辑用户信息与添加用户信息相类似,只需要注意id的问题,必须要传入id值来确认要修改信息的用户。

使用vue-resource put(url,[data])请求 修改数据,并且在路由中使用params来接收用户id

<template>
  <div id="edit" class="container">
    <alert v-if="content" :message="content"></alert>
    <h1 class="page-header">编辑用户</h1>
    <form v-on:submit="updateCustomer">
      <div class="well">
        <h4>用户信息</h4>
        <div class="form-groups">
          <lable>姓名</lable>
          <input type="text" class="form-control" placeholder="name" v-model="customer.name">
        </div>
        <div class="form-group">
          <lable>电话</lable>
          <input type="text" class="form-control" placeholder="phone" v-model="customer.phone">
        </div>
        <div class="form-group">
          <lable>邮箱</lable>
          <input type="text" class="form-control" placeholder="email" v-model="customer.email">
        </div>
        <div class="form-group">
          <lable>学历</lable>
          <input type="text" class="form-control" placeholder="education" v-model="customer.education">
        </div>
        <div class="form-group">
          <lable>毕业学校</lable>
          <input type="text" class="form-control" placeholder="graduationschool" v-model="customer.graduationschool">
        </div>
        <div class="form-group">
          <lable>职业</lable>
          <input type="text" class="form-control" placeholder="profession" v-model="customer.profession">
        </div>
        <div class="form-group">
          <lable>个人简介</lable>
          <textarea class="form-control" rows="10" placeholder="profile" v-model="customer.profile"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">确认</button>
        <span class="pull-right">
          <router-link class="btn btn-primary" to="/">返回</router-link>
        </span>
      </div>
    </form>
  </div>
</template>

<script>
import alert from "./Alert.vue"
export default {
  name: "edit",
  components: {
    alert:alert
  },
  data() {
    //这里存放数据
    return {
      msg: "我是edit组件",
      customer: {},
      content:""
    };
  },
 methods: {
     fetchCustomers(id) {
      this.$http.get("http://localhost:3000/users/"+id).then(res => {
        this.customer = res.body;
      });
    },
    updateCustomer(e) {
      //   console.log(123);
      if (!this.customer.name || !this.customer.phone || !this.customer.email) {
       this.content="请正确修改信息!";
      } else {
        let newCuetomer = {
          name: this.customer.name,
          phone: this.customer.phone,
          email: this.customer.email,
          education: this.customer.education,
          graduationschool: this.customer.graduationschool,
          profession: this.customer.profession,
          profile: this.customer.profile
        };


        //使用vue-resource put(url,[data])请求 修改数据
        this.$http.put("http://localhost:3000/users/"+this.$route.params.id,newCuetomer).then(res => {
          this.$router.push({path:"/",query:{content:"用户信息更新成功!"}})
          //子组件给父组件传值
        });
      }
      e.preventDefault();
      //阻止默认事件
    }
  },
  mounted() {},
    created(){
        this.fetchCustomers(this.$route.params.id)
    }

};
</script>
<style lang='scss'>
</style>

2.8.2 删除用户信息

在customers.vue 组件中添加删除按钮,并绑定点击事件,传入要删除用户的id值

<button class="btn btn-danger" @click="deleteCustomer(customers.id)">删除</button>
 deleteCustomer(id) {
      this.$http.delete("http://localhost:3000/users/" + id).then(res => {
        this.$router.push({
          path: "/",
          query: { content: "成功删除用户信息!" }
        });
      });
    }

 2.9 实现搜索功能

实现的效果是边搜索边显示 

在customers.vue 组件中添加搜索文本框,并且使用v-model实现数据双向,要在data中定义 search:"" 为空

 <input type="text" class="form-control" placeholder="搜索" v-model="search">

 在绑定数据时要循环遍历,filterBy()方法用来过滤用户信息

 <tbody>
        <tr v-for="(customer,index) in filterBy(customers,search)" :key="index">
          <td>{{customer.name}}</td>
          <td>{{customer.phone}}</td>
          <td>{{customer.email}}</td>
          <td>
            <router-link class="btn btn-default" :to="'/detail/'+customer.id">详情</router-link>
          </td>
        </tr>
/tbody>

使用ES6的filter()和match()方法来过滤匹配用户信息,如果有符合搜索框内的内容就返回,没有就什么都不显示;若搜索框中什么都不输入则显示所有 。

注意:filter只能用于数组,所有将customers定义为数组

   filterBy(customers, value) {
      return customers.filter(function(customer) {
        return customer.name.match(value);
        //filter只能用于数组
      });
    },

三、总结

这个项目从完成到写博客用了俩天半的时间。第一次接触json-server,学会使用模拟数据,实现前后端分离。搭配vue-resource可以实现数据的增删改查,这是最大的收货超开心!

回顾vue的基础知识点,包括路由的封装、传值以及编程式路由的写法,子父组件之间传值,理解掌握vue的生命周期函数等知识点。

使用bootstrap框架不用花费大量的时间画页面,缩短做项目的时间,可以用更多的时间来学习vue。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值