日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vuex4学习笔记

發(fā)布時間:2024/7/5 vue 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vuex4学习笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、Vuex的狀態(tài)管理

二、Vuex的安裝

我們這里使用的是vuex4.x,安裝的時候需要添加 next 指定版本;

npm install vuex@next

三、創(chuàng)建Store

每一個Vuex應(yīng)用的核心就是store(倉庫):

  • store本質(zhì)上是一個容器,它包含著你的應(yīng)用中大部分的狀態(tài)(state);

Vuex和單純的全局對象有什么區(qū)別呢?
第一:Vuex的狀態(tài)存儲是響應(yīng)式的

  • 當(dāng)Vue組件從store中讀取狀態(tài)的時候,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會被更新;
    第二:你不能直接改變store中的狀態(tài)
  • 改變store中的狀態(tài)的唯一途徑就顯示提交 (commit) mutation;
  • 這樣使得我們可以方便的跟蹤每一個狀態(tài)的變化,從而讓我們能夠通過一些工具幫助我們更好的管理應(yīng)用的狀態(tài);

使用步驟:

  • 創(chuàng)建Store對象;

  • 在app中通過插件安裝;

計數(shù)器案例:


四、組件中使用store

在組件中使用store,我們按照如下的方式:

  • 在模板中使用;
  • 在options api中使用,比如computed;
  • 在setup中使用;

五、組件獲取狀態(tài)

在前面我們已經(jīng)學(xué)習(xí)過如何在組件中獲取狀態(tài)了。
當(dāng)然,如果覺得那種方式有點繁瑣(表達(dá)式過長),我們可以使用計算屬性:

但是,如果我們有很多個狀態(tài)都需要獲取話,可以使用mapState的輔助函數(shù):

  • mapState的方式一:對象類型;
  • mapState的方式二:數(shù)組類型;
  • 也可以使用展開運算符和來原有的computed混合在一起;

六、在setup中使用mapState

在setup中如果我們單個獲取裝是非常簡單的:

  • 通過useStore拿到store后去獲取某個狀態(tài)即可;

  • 但是如果我們需要使用 mapState 的功能呢?

默認(rèn)情況下,Vuex并沒有提供非常方便的使用mapState的方式,這里我們進(jìn)行了一個函數(shù)的封裝:


useState.js:

import {computed} from "vue"; import {mapState, useStore} from "vuex";export function useState(mapper) {const store = useStore()const storeStateFns = mapState(mapper) // {name: function, age: function}const storeState = {} // {name: ref, age: ref}Object.keys(storeStateFns).forEach((fnKey) => {const fn = storeStateFns[fnKey].bind({$store: store})storeState[fnKey] = computed(fn)})return storeState }

七、getters的基本使用

某些屬性我們可能需要經(jīng)過變化后來使用,這個時候可以使用getters:

getters可以接收第二個參數(shù):


getters的返回函數(shù)

getters中的函數(shù)本身,可以返回一個函數(shù),那么在使用的地方相當(dāng)于可以調(diào)用這個函數(shù):

mapGetters的輔助函數(shù)

這里我們也可以使用mapGetters的輔助函數(shù)。

在setup中使用:

封裝useGetters.js:

import {computed} from "vue"; import {mapGetters, useStore} from "vuex";export function useGetters(mapper) {const store = useStore()const storeStateFns = mapGetters(mapper) // {name: function, age: function}const storeState = {} // {name: ref, age: ref}Object.keys(storeStateFns).forEach((fnKey) => {const fn = storeStateFns[fnKey].bind({$store: store})storeState[fnKey] = computed(fn)})console.log(storeStateFns)console.log(storeState)return storeState }

將前面封裝的useState和useGetters進(jìn)行再次封裝:



八、Mutation基本使用

更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation:

Mutation攜帶數(shù)據(jù)

很多時候我們在提交mutation的時候,會攜帶一些數(shù)據(jù),這個時候我們可以使用參數(shù):

  • payload為對象類型:
  • 對象風(fēng)格的提交方式:
  • Mutation常量類型

    定義常量:mutation-types.js

    定義mutation:

    提交mutation:

    mapMutations輔助函數(shù)

    我們也可以借助于輔助函數(shù),幫助我們快速映射到對應(yīng)的方法中:


    在setup中使用也是一樣的:

    mutation重要原則

    一條重要的原則就是要記住 mutation 必須是同步函數(shù)

    • 這是因為devtool工具會記錄mutation的日記;
    • 每一條mutation被記錄,devtools都需要捕捉到前一狀態(tài)和后一狀態(tài)的快照;
    • 但是在mutation中執(zhí)行異步操作,就無法追蹤到數(shù)據(jù)的變化;
    • 所以Vuex的重要原則中要求 mutation必須是同步函數(shù);

    九、actions的基本使用

    Action類似于mutation,不同在于:

    • Action提交的是mutation,而不是直接變更狀態(tài);
    • Action可以包含任意異步操作;

    這里有一個非常重要的參數(shù)context:

    • context是一個和store實例均有相同方法和屬性的context對象;

    • 所以我們可以從其中獲取到commit方法來提交一個mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters;

    • 但是為什么它不是store對象呢?這個等到講Modules時再具體來說

    actions的輔助函數(shù)

    action也有對應(yīng)的輔助函數(shù):

    • 對象類型的寫法;
    • 數(shù)組類型的寫法;


    actions的異步操作

    Action 通常是異步的,那么如何知道 action 什么時候結(jié)束呢?

    • 我們可以通過讓action返回Promise,在Promise的then中來處理完成后的操作;

    十、module的基本使用

    什么是Module?

    • 由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會集中到一個比較大的對象,當(dāng)應(yīng)用變得非常復(fù)雜時,store 對象就有可能變得相當(dāng)臃腫;
    • 為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module);
    • 每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊;


    module的命名空間

    默認(rèn)情況下,模塊內(nèi)部的action和mutation仍然是注冊在全局的命名空間中的:

    • 這樣使得多個模塊能夠?qū)ν粋€ action 或 mutation 作出響應(yīng);
    • Getter 同樣也默認(rèn)注冊在全局命名空間;

    未使用命名空間時:


    如果我們希望模塊具有更高的封裝度和復(fù)用性,可以添加 namespaced: true 的方式使其成為帶命名空間的模塊:

    • 當(dāng)模塊被注冊后,它的所有 getter、action 及 mutation 都會自動根據(jù)模塊注冊的路徑調(diào)整命名;

    加了命名空間后:

    module的局部狀態(tài)

    對于模塊內(nèi)部的 mutation 和 getter,接收的第一個參數(shù)是模塊的局部狀態(tài)對象:

    module修改或派發(fā)根組件

    如果我們希望在home的action中修改root中的state,那么有如下的方式:

    module的輔助函數(shù)

    如果輔助函數(shù)有三種使用方法:

    • 方式一:通過完整的模塊空間名稱來查找;

    • 方式二:第一個參數(shù)傳入模塊空間名稱,后面寫上要使用的屬性;

    • 方式三:通過 createNamespacedHelpers 生成一個模塊的輔助函數(shù);

  • 在options api 中使用:
  • <template><div><h2>Root當(dāng)前計數(shù):{{$store.state.rootCounter}}</h2><h2>Home當(dāng)前計數(shù):{{$store.state.home.homeCounter}}</h2><h2>User當(dāng)前計數(shù):{{$store.state.user.userCounter}}</h2><hr><h2>{{homeCounter}}</h2><h2>{{doubleHomeCounter}}</h2><button @click="increment">home+1</button><button @click="incrementAction">home+1</button></div> </template> <script> // import {mapActions, mapGetters, mapMutations, mapState} from "vuex"; import {createNamespacedHelpers} from "vuex"; const {mapState, mapGetters, mapMutations, mapActions} = createNamespacedHelpers('home') export default {computed: {// 1.寫法一/*...mapState({homeCounter: state => state.home.homeCounter}),...mapGetters({doubleHomeCounter: 'home/doubleHomeCounter'})*/// 2.寫法二/*...mapState('home', ['homeCounter']),...mapGetters('home', ['doubleHomeCounter'])*/// 3.寫法三...mapState(['homeCounter']),...mapGetters(['doubleHomeCounter'])},methods: {// 1.寫法一/*...mapMutations({increment: 'home/increment'}),...mapActions({incrementAction: 'home/incrementAction'})*/// 2.寫法二/*...mapMutations('home', ["increment"]),...mapActions('home', ["incrementAction"])*/// 3.寫法三...mapMutations(["increment"]),...mapActions(["incrementAction"])} } </script><style scoped></style>
  • 在composition api中使用:

  • <template><div><h2>Root當(dāng)前計數(shù):{{$store.state.rootCounter}}</h2><h2>Home當(dāng)前計數(shù):{{$store.state.home.homeCounter}}</h2><h2>User當(dāng)前計數(shù):{{$store.state.user.userCounter}}</h2><hr><h2>{{homeCounter}}</h2><h2>{{doubleHomeCounter}}</h2><button @click="increment">home+1</button><button @click="incrementAction">home+1</button></div> </template> <script> import {createNamespacedHelpers} from "vuex"; const {mapMutations, mapActions} = createNamespacedHelpers('home')// 自定義hook import {useState} from "./hooks/useState"; import {useGetters} from "./hooks/useGetters";export default {setup() {const state = useState('home',['homeCounter'])const getters = useGetters('home', ['doubleHomeCounter'])const mutations = mapMutations(['increment'])const actions = mapActions(['incrementAction'])return {...state,...getters,...mutations,...actions}} } </script><style scoped></style>

    useMapper.js:

    import {computed} from "vue"; import {useStore} from "vuex";export function useMapper(mapper, mapFn) {const store = useStore()const storeStateFns = mapFn(mapper) // {name: function, age: function}const storeState = {} // {name: ref, age: ref}Object.keys(storeStateFns).forEach((fnKey) => {const fn = storeStateFns[fnKey].bind({$store: store})storeState[fnKey] = computed(fn)})console.log(storeStateFns)console.log(storeState)return storeState }

    useState.js:

    import {createNamespacedHelpers, mapState} from "vuex"; import {useMapper} from "./useMapper";export function useState(moduleName, mapper) {let mapperFn = mapStateif (typeof moduleName === 'string' && moduleName.length > 0) {mapperFn = createNamespacedHelpers(moduleName).mapState} else{mapperFn = moduleName}return useMapper(mapper, mapperFn) }

    useGetters.js:

    import {createNamespacedHelpers, mapGetters} from "vuex"; import {useMapper} from "./useMapper";export function useGetters(moduleName, mapper) {let mapperFn = mapGettersif (typeof moduleName === 'string' && moduleName.length > 0) {// 處理這種情況:useGetters('home', ['increment'])mapperFn = createNamespacedHelpers(moduleName).mapGetters} else {mapperFn = moduleName // 處理這種情況:useGetters(['increment'])}return useMapper(mapper, mapperFn) }

    十一、nexttick

    官方解釋:將回調(diào)推遲到下一個 DOM 更新周期之后執(zhí)行。在更改了一些數(shù)據(jù)以等待 DOM 更新后立即使用它。

    比如我們有下面的需求:

    • 點擊一個按鈕,我們會修改在h2中顯示的message;
    • message被修改后,獲取h2的高度;

    實現(xiàn)上面的案例我們有三種方式:

    • 方式一:在點擊按鈕后立即獲取到h2的高度(錯誤的做法)

    • 方式二:在updated生命周期函數(shù)中獲取h2的高度(但是頁面其他數(shù)據(jù)更新,也會執(zhí)行該操作

    • 方式三:使用nexttick函數(shù);

    nexttick是如何做到的呢?

    總結(jié)

    以上是生活随笔為你收集整理的Vuex4学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。