Vue3 中的 Vue-Router 和 VueX詳解
Vue3 中的 Vue-Router 和 VueX
先使用 vue create 指令來創(chuàng)建 vue 工程項目,并選擇自定義,將 Router 和 VueX 勾上。
勾上以后看主入口 main.js,可以看到項目自動幫我們注冊了 vue-router 和 VueX。
// main.js createApp(App).use(store).use(router).mount('#app')
1. Vue-Router 路由的理解和使用
路由是指根據 url 的不同,展示不同的內容。
查看 src 文件夾里的 router,這就是來處理路由的地方。
其中,index.js 有關鍵的代碼
const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue') } ]
定義了兩個路由項。當訪問根目錄,就加載 HomeView 這個組件。如果訪問 /about
,則懶加載 AboutView 這個組件。
import(...)
是異步加載路由的方法。因為如果一口氣全部組件加載出來,主頁的加載的性能將會很低,為了提高組件的加載性能,使用懶加載按需加載,等進入 /about 或其他的頁面再加載響應部分的代碼。但是異步加載代碼也有相應的問題,就是去其他的頁面可能會有卡頓(其實就是加載的時間分攤了)。
因此,vue-router 就是根據 url 不同來顯示不同組件的特性。
現在查看根組件 App.vue,上面有關鍵的代碼:
<template> <nav> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </nav> <router-view/> </template>
router-link 是跳轉路由的標簽,點擊后就會跳轉到相應的路由。
router-view 負責展示當前路由對應的組件內容。例如上面的代碼,當跳轉到根路徑上時,router 會進行搜索,當搜索到匹配項時,便顯示相應的組件 HomeView。
2. VueX 語法詳解
在文首就看到了,注冊了 VueX,接下來看 src 的 store 目錄,這里邊的 index.js 可以看到以下內容,稍后會講。
export default createStore({ state: { }, getters: { }, mutations: { }, actions: { }, modules: { } })
2.1 VueX 是什么
VueX 是數據管理框架。之前的數據傳遞都是父子之間的傳遞,雖然也有 provider 之類的方法進行跨級傳遞,但是可維護性也不會特別高。
VueX 提供了一個全局都可以使用的數據管理倉庫,不用考慮父子傳值之類的問題,并且可以跨頁面?zhèn)鬟f數據。提高了可維護性。
使用方法
提供數據:在 store 里的 state 里定義一些數據
// VueX 創(chuàng)建了一個全局唯一的倉庫,用來存放全局的數據 export default createStore({ state: { name: "John", }, getters: { }, mutations: { }, actions: { }, modules: { } })
在需要用數據的地方通過 this.$store
獲取即可
<template> <div>{{ myName }}</div> </template> <script> export default { name: "LoginView", computed: { myName() { return this.$store.state.name; }, }, }; </script>
2.2 VueX 數據修改流程
講一下 VueX 的修改規(guī)范,因為全局的數據是不能隨意更改的,因此 VueX 有一套機制流程,并不能直接用賦值的方法進行修改。
修改流程
在組件里提交一個 action 到 store,dispatch 的第一個參數是 action 名稱,后面可自定義參數。
// LoginView.vue <template> <div>{{ myName }}</div> <button @click="handleClick">click</button> </template> <script> export default { name: "LoginView", computed: { myName() { return this.$store.state.name; }, }, methods: { handleClick() { // 1. 想改變數據,VueX 要求第一步,必須派發(fā)一個 action,action 名稱為 actions 里的方法名 this.$store.dispatch("change"); }, }, }; </script>
store 感知到 action,執(zhí)行 actions 下面對應的方法
actions 對應的方法 commit 信息后傳遞給 mutations。commit 的信息為 mutations 里的方法名。
mutations 里對應的方法執(zhí)行修改數據的操作。
import { createStore } from "vuex"; // VueX 創(chuàng)建了一個全局唯一的倉庫,用來存放全局的數據 export default createStore({ state: { name: "John", }, getters: { }, mutations: { // 4. 接收到 commit 信息后,觸發(fā)對應的 mutation change(state) { // 5. 在 mutation 里修改數據 state.name = "Modified Name"; }, }, actions: { // 2. 接收到 action 后執(zhí)行相應的方法 change(store) { // 3. commit 后發(fā)送給 mutations store.commit("change"); }, }, modules: {}, });
從上面的流程來看,VueX 創(chuàng)建了一個全局唯一的倉庫,用來存放全局的數據,同時里面設置了一系列的數據操作流程。
這流程下來有點麻煩啊,為啥不直接 commit 過去呢?同步代碼看起來是如此,但是如果有異步操作的話,這些步驟就很有必要了。
注意mutations 和 actions 里的方法第一個參數各不相同。
actions 里面第一個參數是 store,因為需要用 store.commit 方法來提交給 mutations。
mutations 里邊的方法第一個參數是 state,因為 store 是用來修改 store 里 state 的方法。
可見,vue 官方在代碼層面都是推薦分離的。
其他細則 mutations 里面只允許寫同步代碼,不許寫異步代碼actions 里面允許寫異步操作
優(yōu)點在于,將兩種功能分離,mutations 里做數據的改變,actions 里做主要的邏輯書寫,維護的時候會更加方便。
getter 是啥
store 里的數據有時候并不能直接拿來用,還需要經過一些小處理。一般就會想,在組件內處理不就完事了?但是呢,萬一有很多的組件都有著需求呢,挨個寫就不合適。getter 就相當于 store 里的 computed 屬性,對 state 進行了一定的處理。
使用方法:
設置 getter
getter 接收兩個參數,然后返回一個值。
state,必選,是 store 里的數據getters,可選,是 store 里的所有 getters
例如,我要計算得到大寫后的 name:
// store/index.js getters: { upperCasedName: (state) => { return state.name.toUpperCase(); } },
組件獲取 store 里的 getter
<template> <div>{{ upperCasedName }}</div> <button @click="handleClick">click</button> </template> <script> export default { name: "LoginView", computed: { upperCasedName() { return this.$store.getters.upperCasedName; }, }, methods: { handleClick() { // 1. 想改變數據,VueX 要求第一步,必須派發(fā)一個 action this.$store.dispatch("change"); }, }, }; </script>
通過 computed 獲取到 getter 后,點擊按鈕改變了 store 里的 name,上邊顯示的仍然是大寫的,因為獲取的是全部字母大寫后的 name。
2.3 Composition API 使用 VueX
composition API 使用 useStore 獲取 store 即可。
<template> <div>{{ name }}</div> </template> <script> import { useStore } from "vuex"; export default { name: "LoginView", setup() { const store = useStore(); const name = store.state.name; return { name, }; }, }; </script>
用 toRefs 解構的方法也行:
<template> <div>{{ name }}</div> <button @click="handleClick">Click</button> </template> <script> import { toRefs } from "@vue/reactivity"; import { useStore } from "vuex"; export default { name: "LoginView", setup() { const store = useStore(); const { name } = toRefs(store.state); const handleClick = () => { store.commit("changeName"); }; return { name, handleClick, }; }, }; </script>
到此這篇關于Vue3 中的 Vue-Router 和 VueX的文章就介紹到這了,更多相關Vue3 中的 Vue-Router 和 VueX內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!