前言
我想寫一系列關於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官方中文文檔