利用vuex ,开发一个登录功能
在一个大型项目中肯定是要用到vuex的,今天使用vuex,做一个用户登录,登陆后获取审批列表的功能.这两块分为两个模块所用到的数据分别放在login-store文件夹,approver-store文件夹下;
以下如果有不合理或者错误的地方,也希望各位老司机不吝赐教,有机会多交流。
话不多说,开始!
一、安装vuex:
cnpm install vuex -S
二、构建核心仓库 store (根据项目模块构建)
在项目的src
文件夹下新建一个store
文件夹,并且分别在其中新建login-store文件夹,approver-store文件夹以及index.js文件,
再分别在login和approver文件夹下新建actions.js
mutations.js
mutations-types.jsgetters.js
ndex.js等文件
如下:
approver-store和login-store文件夹下的index.js放入一下代码:
/*****************approver-store下的index.js****************/
import actions from './actions'
import getters from './getters'
import mutations from './mutations'
export const approverModule = {
state: {},
actions: actions,
getters: getters,
mutations: mutations
}
/*****************login-store下的index.js****************/
import actions from './actions'
import getters from './getters'
import mutations from './mutations'
export const loginModule = {
state: {},
actions: actions,
getters: getters,
mutations: mutations
}
然后在store文件夹下的index.js文件加入以下代码:
/*
* actions:在methods里面的方法
* getter 在computed里面的方法
* mutation 中间量,不应该在外面去操作它
*
* */
import Vue from 'vue'
import Vuex from 'vuex'
import {loginModule} from './login-store'
import {approverModule} from './approver-store'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
loginModule: loginModule,
approverModule:approverModule
}
})
export default store
在main.js中使用:
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
三.准备就绪,我们开始做登陆功能(关于登录的都放在login-store下面)
1.我们要新建一些假数据,来创建一个接口.
在根目录下新建mock文件夹,里面新建json文件
json文件内容如下:
{
"info": [
{
"id": "4579a806-5ebd-4508-b787-b096510fe571",
"AccountData": "fanjiaopenid01",
"name": "貂蝉2",
"password": "diaochan",
"MobilePhone": "18032556552",
"CustomerType": 1,
"Gender": 1,
"self": true
}
...
]
}
启动命令 : json-server ./mock/data.json
如果没有安装 json-server,要先全局安装:npm install json-server -g,
然后再启动:会出现如下界面,就算启动成功了.(具体用法请看:https://blog.****.net/sllailcp/article/details/79249784)
在浏览器中输入http://localhost:3000/info:可以看到数据
然后在components文件夹下新建login.vue,添加代码
<input type="text" v-model="username" placeholder="请输入姓名" /><br/>
<input type="text" v-model="password" placeholder="请输入年龄" /><br/>
<a href="javascript:;" @click="loginbtn">登录</a>
login-store/mutations-types.js中新建变量 :
export const UPDATEUSER = "UPDATEUSER"; // 更新当前账户
login-store/mutations.js中加入以下代码:
import { UPDATEUSER} from './mutations-types'
export default {
// 更新当前用户
[UPDATEUSER] (state, opt) {
console.log(opt)
state.userInfo.id = opt.id;
state.userInfo.name = opt.name;
state.userInfo.AccountData = opt.AccountData;
state.userInfo.password = opt.password;
state.userInfo.MobilePhone = opt.MobilePhone;
state.userInfo.CustomerType = opt.CustomerType;
state.userInfo.Gender = opt.Gender;
}
}
login-store/actions
.js中加入以下代码:
import axios from 'axios';
export default {
// 登录
LoginAsync ({ commit, state }, opt) {
if (!opt.username) {opt.username = state.loginInfo.username;}
if (!opt.password) {opt.password = state.loginInfo.password;}
if(!opt.username || !opt.password){alert('账号密码不可以为空!');return;}
return new Promise((resolve, reject) => {
axios.get('http://localhost:3000/info',{
params:{"name": opt.username, "password": opt.password,}
}).then(function (response) {
resolve(response.data);
localStorage.setItem('token',response.data[0].id)
commit('UPDATEUSER',response.data[0])
}).catch(function (error) {
reject(error);
});
})
}
}
login-store/index.js中定义state:
...
export const loginModule = {
state: {
loginInfo:{
username:'',
password:''
},
userInfo:{
"id":"","AccountData":"","name":"","password":"","MobilePhone":"","CustomerType":1,"Gender":1
}
},
...
}
在login.vue中使用:
import { mapActions,mapGetters } from 'vuex'
export default {
name: "login",
data() {
return {
username:'',
password: ''
}
},
computed:{
...mapGetters(['getUserInfo','getLoginInfo'])
},
methods:{
loginbtn(){
this.$store.dispatch('LoginAsync',{username:this.username,password:this.password}).then((res)=>{
if(res.length === 0){
alert('账号密码错误');
return;
}
if(this.$route.query.redirect){
this.$router.push({path:this.$route.query.redirect});
}else{
this.$router.push({path:'/index'});
}
}).catch((err)=>{console.log(err)})
},
...mapActions([
'LoginAsync'
]),
}
}
最后在router/index.js中加上路由守卫:
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (localStorage.getItem('token')) { // store获取当前的token是否存在
next();
}
else {
alert('请重新登陆');
next({
path: '/',
query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
}else {
next();
}
})
此时我们就利用vuex就完成了登录功能;
四.登录完成后,获取列表(关于审批人的都放在approver-store文件夹下)
approver-store/actions
.js加入如下代码
import {STOREEDITCUSTOMER,ADDAPPROVERTYPE} from "./mutations-types";
export default {
setstoreEditCustomerAsync({ commit, state }, opt){
commit('STOREEDITCUSTOMER',opt)
},
setstoreAddApproverTypeAsync({ commit, state }, opt){
commit('ADDAPPROVERTYPE',opt)
}
}
approver-store/getters
.js加入如下代码
export default {
getstoreEditCustomerGetter: state => state.storeEditCustomer, // 获取页面上显示的乘客
getstoreaddApproverTypeGetter: state => state.addApproverType, // 新增或者修改
}
approver-store/mutations-types.js加入如下代码
export const STOREEDITCUSTOMER = "STOREEDITCUSTOMER"; // 修改乘客
export const ADDAPPROVERTYPE = "ADDAPPROVERTYPE"; // 修改乘客
approver-store/mutations.js加入如下代码
import { STOREEDITCUSTOMER ,ADDAPPROVERTYPE} from './mutations-types'
export default {
[STOREEDITCUSTOMER] (state, opt){ // opt是一个{ }
state.storeEditCustomer = opt;
},
[ADDAPPROVERTYPE] (state, opt){ // opt是一个number
state.addApproverType = opt;
}
}
approver-store/index.js的state如下代码:
...
export const approverModule = {
state: {
storeEditCustomer:{
name:'',
MobilePhone:''
}
},
...
}
在list.vue里面加入代码:
<button @click="$router.push({name:'detail'})">新增员工</button>
<table>
<tr>
<th>姓名</th>
<th>手机号码</th>
<th>id</th>
<th>账户</th>
<th>操作</th>
</tr>
<tr v-for="item of list">
<td><span class="l">{{item.name}}</span></td>
<td><span class="l">{{item.MobilePhone}}</span></td>
<td><span class="l">{{item.id}}</span></td>
<td><span class="l">{{item.AccountData}}</span></td>
<td><span @click="$router.push({name:'detail',query:{id:item.id}})">编辑</span> <span @click="topDelete(item)">删除</span></td>
</tr>
</table>
<script>
import axios from 'axios';
import { mapGetters } from "vuex";
export default {
name: "list",
data() {
return {
list: []
}
},
computed:{ ...mapGetters(['getstoreEditCustomerGetter','getstoreaddApproverTypeGetter'])
},
created() {
this.init();
},
methods: {
topDelete(item){ // 删除
if(confirm(`是否彻底删除 ${item.name}`)){
axios.delete('http://localhost:3000/info/'+item.id).then( (res) => {
console.log(res)
this.init();
}).catch(function (error) {
});
}
},
init() {
axios.get('http://localhost:3000/info').then( (res)=> {
this.list = res.data;
}).catch( (error) =>{
});
}
}
}
</script>
此时打开list页面就可以看到列表数据啦.
效果图如下(完整代码请移步:https://github.com/slailcp/vuex-demo):