美文网首页
Vuexms项目文档

Vuexms项目文档

作者: YiFanCode | 来源:发表于2019-01-04 21:07 被阅读0次

    1.起步

    1.1.前言

    这篇文档是跟随腾讯课堂课程:前端教程vuex实现管理系统,给自己写的课堂随笔,仅作记录作用。建议先去vuex官网了解一些基本知识再开始。

    本文档可能会出现数据对不上的问题,原因是视频中有不断更改数据,所以后面会对之前的数据库或者页面元素作出调整。然后我自己尝试解决了部分工具版本上的问题,很多地方记录的不详尽,推荐看视频。

    主要用到的工具/包有:vue, vuex, npm, nodemon, mysql, element-ui, axios

    1.2.初始化项目

    1. 打开项目位置文件夹,在地址栏输入cmd打开当前目录的控制台,输入以下代码:

      vue init webpack vuexms
      
      控制台显示图
    2. 继续在控制台输入指令以安装相关包:

      cd vuexms
      npm i
      
      初始完成的文件目录
    3. 试着运行我们的初始项目:

      npm run dev
      
      显示

    控制台表明我们的项目运行在了http://localhost:8080,打开就能看到默认的初始界面。

    1.3.个性化

    • 打开vuexms\src\App.vue,这是我们项目的路由出口,同时删掉<template>中的img标签和<style>中的所有内容:
    <!-- 这是默认的主页面logo图 -->
    <img src="./assets/logo.png"> 
    
    • 打开vuexms\src\components\HelloWorld.vue,这是路由指示的主界面,删除<template>中的标签。同时,将文件名改为我们需要的login.vue,然后更改src\router\index.js中的相关代码。

      import Vue from 'vue'
      import Router from 'vue-router'
      
      // 引入组件
      import login from '@/components/login'
      
      // 注册路由
      Vue.use(Router)
      
      // 导出路由
      export default new Router({
        routes: [
          {
            path: '/login',
            name: 'login',
            component: login
          }
        ]
      })
      

    2.实现登录页

    2.1.使用Element

    官网地址:Element

    1. 切换回控制台,Ctrl+C暂时停止服务器。

      npm i element-ui -S
      
    2. 找到src目录 下的main.js,添加以下代码

      // 引入
      import ElementUI from 'element-ui';
      import 'element-ui/lib/theme-chalk/index.css';
      
      // 注册
      Vue.use(ElementUI);
      
    3. 测试是否注册成功,在login.vue中加入以下代码,重启服务器:npm run dev,如果页面中正常加载出了按钮表示注册成功。

      <el-button>按钮</el-button>
      

    2.2.使用组件

    1. element-ui官网找到合适的表单登录组件,分别将里面的HTML代码和Javascript代码放到对应页面,我们这里是login.vue

    2. 我们会加入css代码让页面更加美观,在这之前应该重置样式来避免一些错误。可以在static中新建css文件夹,然后放入合适的reset.css,然后再在index.html中引入:

      <!-- reset.css -->
      <link rel="stylesheet" href="./static/css/reset.css">
      
    3. 自定义数据和样式。


      登陆窗口

    2.3.axios

    安装:

    npm i axios -S
    

    main.js中引入:

    // 引入 axios
    import axios from 'axios'
    // 挂载到 Vue 的原型上
    Vue.prototype.axios = axios
    

    login.vue中检测:

    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
           // 确认是否能打印出信息   
           console.log(this.axios)
         } else {
           console.log('error submit!!');
           return false;
         }
      });
    },
    

    向后台发送数据并得到响应:

    this.axios.post('/api/checklogin', {
      username: _this.loginForm.username,
      password: _this.loginForm.password
    })
    .then(response => {
      console.log('接收后端响应的数据')
    })
    

    2.4.express搭建服务器

    实现登录,需要从服务器获取数据,所以我用 express 搭建了一个。

    1. 确保全局安装了 express,4.X 后的版本需要安装 express-generator。

      npm install -g express
      npm install -g express-generator
      

      在环境变量中添加 path: <u>C:\Users\admin\AppData\Roaming\npm</u>。

    2. 项目同级目录打开cmd工具:

      express server -e
      cd server
      npm install
      
    3. 打开 server 中的 app.js 添加:

      // 监听端口
      app.listen(888, () => {
        console.log('888端口的服务器已经启动...')
      })
      

      在 server\routes\index.js 中设置:

      // 接收请求
      router.post('/checklogin', (req, res) => {
        // 接收用户名和密码
        let { username, password} = req.body;
        console.log(username, password)
        // 发送响应
        res.send('服务器数据')
      })
      

      因为是跨域请求,在 vuexms\config\index.js 中设置:

      proxyTable: {
        '/api': {
          target: 'http://localhost:888', // 接口的域名
          changeOrigin: true, // 如果是跨域请求,需要配置此项
          pathRewrite: {
            '/api': ''
          }
        }
      }
      
      • 项目控制台重启项目npm run dev

      • 服务器控制台启动服务器node app

      • 打开项目页面,输入帐号密码提交后检查服务器控制台和网页响应数据:

        服务端收到数据 服务器数据

      至此说明项目和服务器已经联通了,接下来需要比对数据库进行登录验证。

    2.5.连接数据库

    首先我们需要创建一个数据库,在 计算机 -> 管理 -> 服务 中启动 mysql,新开一个 cmd 控制台窗口:

    1. 连接mysql

      mysql -hlocalhost -uroot -proot
      
    2. 新建数据库

      show databases;
      create database vuexms;
      use vuexms;
      
    3. 新建表

      create table users (
        id int primary key auto_increment,
        username varchar(50),
        password varchar(50),
        realname varchar(50),
        age int,
        idType varchar(50)
      );
      desc users;
      
    4. 插入数据

      insert into users(username, password, realname, age, idType) value('xiaoyao', '123456', '李逍遥', '20', '00001');
      insert into users(username, password, realname, age, idType) value('linger', '123456', '赵灵儿', '18', '00002');
      select * from users;
      

    然后通过 node 连接数据库:

    1. 在服务器控制台安装mysql包

      npm i mysql -S
      
    2. 在 server\routes 路径下新建 conn.js 文件:

      // 引入mysql
      var mysql = require('mysql')
      
      // 创建连接
      var connection = mysql.createConnection({
        host     : 'localhost',
        user     : 'root',
        password : '123456',
        database : 'vuexms'
      });
      
      // 暴露出去
      module.exports = connection
      
    3. 在同路径的 index.js 中:

      // 引入连接数据库模块
      const connection = require('./conn')
      
      // 连接数据
      connection.connect(() => {
        console.log('数据库连接成功!')
      })
      
      router.post('/checklogin', (req, res) => {
        ...  
        // 执行sql查询
        const sqlStr = `select * from users where username='${username}' and password='${password}'`
        connection.query(sqlStr, (err, data) => {
          if(err) {
            console.log(err)
          }else {
            res.send(data)
          }
        })
      })
      
    4. 重启服务器,会显示数据库连接成功。提交表单,在 Response 中可以看到发送回来的 data:

      数据库连接成功 得到数据
    1. 渲染页面,在 login.vue 中

      .then(response => {
        if(response.data.length) {
          console.log('接收后端响应的数据', response.data[0].username)
          _this.$message({
            message: '恭喜你,登录成功!',
            type: 'success'
          })
        }else {
          _this.$message.error('请检查用户名或密码')
        }
      })
      

    3.保存登录数据

    3.1.vue异步加载组件

    继续在 login.vue 中

    .then(response => {
      if(...){
        ...
        // 跳转到首页
        _this.$router.push('/index')
      }
      ...
    })
    
    

    那么我们需要在 vuexms\src\components 增加一个页面组件 index.vue

    <template>
      <h1>index</h1>
    </template>
    ...
    

    在路由中配置,并将引入的方式改为异步加载

    // 引入组件
    // import login from '@/components/login'
    // import index from '@/components/index'
    
    // 异步加载
    const login = () => import('@/components/login')
    const index = () => import('@/components/index')
    
    export default new Router({
      routes: [
        ...
        {
          path: '/',
          name: 'index',
          component: index
        }
      ]
    })
    

    3.2存入登录用户数据

    1. 安装 vuex 包,在项目控制台:

      npm i vuex -S
      
    2. 在 src 目录下新建 vuex 文件夹然后新建 store.js 文件:

      // 引入 vuex
      import Vue from 'vue'
      import Vuex from 'vuex'
      
      // 注册 vue
      Vue.use(Vuex)
      
      // 状态
      const state = {
        userinfo: JSON.parse(localStorage.getItem('userinfo'))
      }
      // mutations 用于操作 state
      const mutations = {
        // 保存用户数据
        SAVE_USERINFO (state, userinfo) {
      
          // 把用户数据放到本地存储实现持久化
          localStorage.setItem('userinfo', JSON.stringify(userinfo))
      
          state.userinfo = userinfo
          console.log('赋值后的用户信息:' , state.userinfo)
        }
      }
      
      // 创建 store 仓库暴露出去
      export default new Vuex.Store({
        state,
        mutations
      })
      
    3. 在 src\main.js 中

      ...
      import store from './vuex/store'
      ...
      new Vue({
        ...
        store,
      })
      
    4. login.vue

      .then(response => {
        if(...){
          ...
          // 把当前用户数据存入 state
          _this.$store.commit('SAVE_USERINFO', response.data[0])
          ...
          _this.$router.push('/')
        }
        ...
      })
      
    5. index.vue 主页调用

      <template>
        ...
          <p>用户信息:{{ $store.state.userinfo }}</p>
        ...
      </template>
      
    得到数据

    4.主页

    4.1.样式

    在 element 中选个喜欢的 container 组件样式粘贴到 components\index.vue 组件中,进行修改调整

    主页样式

    4.2.路由跳转

    简单添加几个其余的页面组件,例如:userlist.vue, useradd.vue, passwordedit.vue。重要的是实现路由跳转,而在 element-ui 中有 router 属性可以帮助我们节省步骤。

    首先,确定需要进行跳转的样式模块,也就是页面左侧的导航栏,在元素中加入 router 属性:

    <el-menu :default-openeds="['1']" router>
    

    然后试着点击导航栏目录,网页地址会加上 el-menu-item 元素的 index 属性的值。

    然后,在 router\index.js 中:

    // 引入
    const home = () => import('@/components/home')
    const userlist = () => import('@/components/userlist')
    const useradd = () => import('@/components/useradd')
    const passwordedit = () => import('@/components/passwordedit')
    ...
    routes: [
      ...
      {
        path: '/',
        redirect: '/home',
        name: 'index',
        component: index,
        children: [
          {
            path: '/home',
            name: 'home',
            component: home
          },        
          {
            path: '/userlist',
            name: 'userlist',
            component: userlist
          },
          {
            path: '/useradd',
            name: 'useradd',
            component: useradd
          },
          {
            path: '/passwordedit',
            name: 'passwordedit',
            component: passwordedit
          },
    ]
    

    4.3.获取state数据

    想要在默认页面得到展示当前用户的一些数据,就要从 state 中获取,vuex 提供了一种更加简单的方式来帮助我们获取到数据,在 components\home.vue 中:

    // 引入 mapState
    import {mapState} from 'vuex'
    
    export default {
      computed: {
        // 辅助函数 获取 state 数据
        ...mapState({
          // userinfo: this.$store.state.userinfo
          userinfo: state => state.userinfo
        })
      }
    }
    

    5.用户列表页

    5.1.触发actions异步获取数据

    在 vuexms\src\vuex\store.js 中发起请求:

    // 引入 axios
    import axios from 'axios'
    ...
    const state = {
      ...
      userList: []
    }
    const mutations = {
      ...
      // 获取全局的用户数据
      GET_USERLIST (state, userList) {
        state.userList = userList
      }
    }
    // 定义 actions 异步的主要是 commit mutations,由 mutations 来改变状态
    const actions = {
      GET_USERLIST({ commit }) {
        // 使用 Promise,其他页面可以通过 .then 的方式来保证页面渲染前得到数据
        return new Promise((resolve, reject) => { 
          axios.get('/api/getuserlist').then(response => {
            // console.log('获取用户数据列表', response.data)
            commit('GET_USERLIST', response.data)
            resolve()
          })
        })
      }
    }
    export default new Vuex.Store({
      state,
      mutations,
      actions
    })
    

    在服务端 server\routes\index.js 响应:

    // 接收获取用户列表的请求
    router.get('/getuserlist', (req, res) => {
      // 查询数据库 把当前素有用户数据返回给前端
      const sqlStr = 'select * from users'
      connection.query(sqlStr, (err, data) => {
        if(err) {
          throw err
        }else {
          res.send(data)
        }
      })
    }) 
    

    检查是否传回数据,在 vuexms\src\components\userlist.vue 中:

    created() {
        this.$store.dispatch('GET_USERLIST').then(() => {
        console.log(this.$store.state.userList)
      })
    }
    
    拿到数据

    5.2.渲染页面

    继续操作 userlist.vue 文件:

    // 引入辅助函数
    import {mapState, mapActions} from 'vuex'
    
    // 删除之前的假数据
    data() {
      return {
        tableData: []
      }
    },
    created() {
      // 以下方式冗长不擅于管理
      // this.$store.dispatch('GET_USERLIST').then(() => {
      //   // console.log(this.$store.state.userList)
      //   // 把全局的 userlist 赋值给 tableData
      //   // this.tableData = this.$store.state.userList
      // })
      this.getUserList().then(() => {
        this.tableData = this.userList
      })
    },
    methods: {
      ...mapActions({
        getUserList: 'GET_USERLIST'
      }),
    },
    computed: {
      ...mapState({
        userList: state => state.userList
      })
    }
    
    渲染用户列表

    5.3.过滤

    为了使用 getters 属性,在复制本页面用户列表添加到下方,并改为目标用户表,我们做过滤出年龄大于20岁的用户列表这个操作:

    data() {
      return {
        tableData: [],
        newtableData: []
      };
    },
    created() {
      this.getUserList().then(() => {
        ...
        this.newtableData = this.userList.filter(v => v.age > 20)
      });
    }
    

    把需要获取的数据定义成全局的,但是效果不变,在 vuex\store.js 中:

    // 定义全局共享属性 getter
    const getters = {
      vipUsers: state => state.userList.filter(v => v.age > 20)
    }
    
    export default new Vuex.Store({
      ...
      getters
    })
    

    回到 userlist.vue 文件:

    created() {
      this.getUserList().then(() => {
        ...
        // this.newtableData = this.userList.filter(v => v.age > 20)
        this.newtableData = this.$store.getters.vipUsers
      });
    }
    

    使用 mapGetters 辅助函数使编写更简洁:

    import { mapState, mapActions, mapGetters} from "vuex";
    ...
    created() {
      this.getUserList().then(() => {
        ...
        this.newtableData = this.vipUsers
      });
    }
    ...
    computed: {
      ...mapGetters(['vipUsers']),
      ...
    }
    
    目标用户

    到此,对 vuex 的重要属性就基本都使用了,也搭好了一个简单的管理系统模板。

    我有意将它具化成较详尽的资产管理系统,等完成以后发布出来。

    相关文章

      网友评论

          本文标题:Vuexms项目文档

          本文链接:https://www.haomeiwen.com/subject/nvakrqtx.html