Vuex入门简单示例(二)
前言
我想写一系列关于Vuex的入门文章,我是看着vuex官网文档,结合自己从零搭建的vue项目来实践vuex的知识。
Vuex入门系列:
-
Vuex入门简单示例(二)
本文涉及知识点:
- vue cli3快速构建项目
- 安装并使用vue-router
- 安装并使用vuex
- router beforeEach 导航守卫实现登录判断
- 关闭console.log Eslint检查
- vuex之state
- vuex之mutation
用vue cli3构建一个简单的项目
vue create vuex-login
Please pick a preset 选择默认 default (babel, eslint)
回车,自动安装,完成后
cd vuex-login
安装vue-router
yarn add vue-router
安装vuex
yarn add vuex
运行项目,看看初始化的页面
yarn run serve
这样子就ok,继续...
整理下代码
- 删掉src/components里面的HelloWorld.vue文件
- 删除App.vue中引用HelloWorld.vue组件的相关代码
在App.vue添加<router-view />标签
src/App.vue
<template> <div id="app"> <router-view /> </div> </template> <script> export default { name: 'app' } </script> <style> </style>
在src/components下新建两个vue文件
src/components/Home.vue
<template> <div class="home">
首页 </div> </template> <script> export default { name: 'Home' } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
src/components/login.vue
<template> <div class="login">
登录页 </div> </template> <script> export default { name: 'Login' } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
等下路由会用到这两个页面
使用vue-router和vuex
vue-router和vuex都安装了,现在开始写router和store,为了简单方便,我就直接写在main.js里面了。
1.引用vue-router和vuex
src/main.js
import VueRouter from 'vue-router' //导入依赖 import Vuex from 'vuex' //导入依赖 Vue.use(VueRouter) //使用依赖 Vue.use(Vuex) //使用依赖
2.导入页面组件
src/main.js
// 页面组件 import Home from '@/components/Home' import Login from '@/components/Login'
3.编写路由代码
src/main.js
const router = new VueRouter({ routes: [ { path: '/', component: Home }, { path: '/login', component: Login } ] })
在Vue实例添加router
src/main.js
new Vue({ router, render: h => h(App), }).$mount('#app')
4.编写store代码
src/main.js
const store = new Vuex.Store({ state: { isLogin: false } })
知识点讲解
- state是状态对象
- mutations是更改状态对象状态的方法(后面会用到)
先写一个isLogin状态,默认值false
在Vue实例添加store
src/main.js
new Vue({ router, store, render: h => h(App), }).$mount('#app')
到这里,项目基本搭建完成。
接下来,我们实现一个这样的效果,根据isLogin状态的值来判断页面的跳转。
先用写死的isLogin的值来实现一个简单固定版,后面再改成用store来实现的真实版本。
这里用到路由拦截(导航守卫)方法
路由拦截(导航守卫)
首先,改造一下路由的代码,给它们加上name和meta等属性
src/main.js
const router = new VueRouter({ routes: [ { path: '/', name: 'home', component: Home, meta: { auth: true } }, { path: '/login', name: 'login', component: Login, meta: { auth: true } } ] })
auth: true 表示此路由需要验证
然后,用router.beforeEach拦截路由
src/main.js
// const store... /* 路由拦截:检查是否登录,未登录则跳到登录页 */ router.beforeEach((to, _, next) => { console.log(to); // 过滤需要验证的路由 if (to.matched.some( m => m.meta.auth)) { // 这一个判断非常重要,没有的话会导致栈溢出报错 if (to.name == 'login') { next() } else { if (store.state.isLogin == true) { next() } else { next('/login') } } } else { next() } })
关闭console.log eslint检查
此处为了调试代码,写了console.log,eslint检查默认console.log是会报错的。
要关闭这一项检查,修改package.json文件,在eslintConfig里面的rules里面加上 "no-console": "off"
现在页面根据isLogin来跳转应该是没有问题了。你可以手动修改isLogin的值来试试。
接下来想想如何动态修改isLogin,这里会用到更多vuex的知识
先说说如何在Vue组件中获得Vuex状态
在Home.vue和Login.vue文件都加上$store.state.isLogin来实时显示isLogin的值
src/components/Login.vue(src/components/Home.vue同样)
<template> <div class="login"> 登录状态:{{$store.state.isLogin}} <br> 登录页 </div> </template>
我们把isLogin的默认值设为false, 默认都会跳到登录页。
我们给登录页加一个按钮
src/components/Login.vue
<template> <div class="login"> 登录状态:{{$store.state.isLogin}} <br/> <button @click="LoginHandle">登录</button> </div> </template>
点击按钮修改isLogin的值,并跳转到首页
src/components/Login.vue
<script> export default { name: 'Login', methods: { LoginHandle () { this.$store.commit('changeLogin', true) this.$router.push('/') } } } </script>
浏览器预览下试试
这里贴一下Mutation的概念
更改Vuex的store中的状态的唯一方法是提交mutation.Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。
到这里应该就明白了vuex中两个基本的概念,state和mutation,更多知识点在用到的时候再说吧。
现在,我们把登录页丰富一下。加上用户名和密码。点登录后保存起来。
src/components/Login.vue
<template> <div class="login"> 登录状态:{{$store.state.isLogin}} <br/> <div> <input v-model="username" type="text" placeholder="用户名"> <br> <input v-model="password" type="password" placeholder="密码"> <br> <button @click="LoginHandle">登录</button> </div> </div> </template>
// ... data () { return { username: '', password: '' } }, // ...
修改store对象,添加username和password状态,以及修改状态的方法。
src/main.js
const store = new Vuex.Store({ state: { isLogin: false, //登录状态 username: '', //用户名 password: '' //密码 }, mutations: { // 修改登录状态 changeLogin(state, data) { state.isLogin = data }, // 修改用户名状态 changeUsername(state, data) { state.username = data }, // 修改密码状态 changePassword(state, data) { state.password = data } } })
再次回到Login.vue完善登录函数
src/components/Login.vue
// ... methods: { LoginHandle () { // 表单验证 if (!this.username || !this.password ) return; // 修改isLogin状态 this.$store.commit('changeLogin', true) // 修改username状态 this.$store.commit('changeUsername', this.username) // 修改password状态 this.$store.commit('changePassword', this.password) this.$router.push('/') // 跳到首页 } } // ...
修改Home.vue,显示用户名
src/components/Home.vue
<template> <div class="home"> 登录状态:{{$store.state.isLogin}} <br> {{$store.state.username}},你好! <br> 首页 </div> </template>
在vue的计算属性computed中获取store中的数据,也能实现同样的效果。
src/components/Home.vue修改如下:
<template> <div class="home"> 登录状态:{{isLogin}} <br> {{username}},你好! <br> 首页 </div> </template> <script> export default { name: 'Home', computed: { isLogin () { return this.$store.state.isLogin }, username () { return this.$store.state.username } } } </script>
最终登录页效果:
登录后首页:
至此,基本完成了用户名和密码的存储过程。
说明一下,这个示例没有任何样式。凑活看吧。
后记
现在看这些东西都很简单的样子,感觉都没必要写出来。但事实上也是绕了很多圈子,最后才明白的。
我尽量写得简单易懂可执行,希望对和我之前一样的新手有所帮助。
于我而言,就当作对知识的梳理吧。
参考文档:Vuex官方中文文档