Vuexms项目文档

2019-01-04  本文已影响0人  YiFanCode

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.个性化

<!-- 这是默认的主页面logo图 -->
<img src="./assets/logo.png"> 

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 的重要属性就基本都使用了,也搭好了一个简单的管理系统模板。

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

上一篇 下一篇

猜你喜欢

热点阅读