最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vuex模塊化應(yīng)用實(shí)踐示例

 更新時(shí)間:2020年02月03日 11:02:29   作者:我是你班主任  
這篇文章主要介紹了Vuex模塊化應(yīng)用實(shí)踐示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Vuex作為Vue全家桶的成員之一,重要性肯定不用多說(shuō),正在做Vue項(xiàng)目的同學(xué),隨著項(xiàng)目需求、功能逐漸增加,用到Vuex也是早晚的事兒,作為一個(gè)前端,只能面對(duì)現(xiàn)實(shí):學(xué)不動(dòng)也得學(xué)!

這篇文章主要介紹Vuex在大型項(xiàng)目中的模塊化及持久化應(yīng)用實(shí)踐,下面正文開(kāi)始

Vuex的應(yīng)用場(chǎng)景

  • 多個(gè)組件視圖共享同一狀態(tài)時(shí)(如登錄狀態(tài)等)
  • 多個(gè)組件需要改變同一個(gè)狀態(tài)時(shí)
  • 多個(gè)組件需要互相傳遞參數(shù)且關(guān)系較為復(fù)雜,正常傳參方式變得難以維護(hù)時(shí)
  • 持久化存儲(chǔ)某些數(shù)據(jù)

所以我們把組件共享的狀態(tài)抽離出來(lái),不管組件間的關(guān)系如何,都通過(guò)Vuex來(lái)處理

組織store目錄

我們先按模塊化的方式組織store目錄,并在Vue根實(shí)例中注冊(cè)store,Vuex 通過(guò) store 選項(xiàng),提供了一種機(jī)制將狀態(tài)從根組件“注入”到每一個(gè)子組件中

src
├── ...
├── main.js
├── App.vue
└── store
  ├── index.js     # 我們組裝模塊并導(dǎo)出 store 的地方
  └── modules
    ├── product.js    # 產(chǎn)品模塊
    ├── windowInfo.js  # 窗口信息模塊
    └── user.js     # 登錄模塊

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import product from './modules/product'
import windowInfo from './modules/windowInfo'

Vue.use(Vuex)

export default new Vuex.Store({
 modules: {
  // 注冊(cè)modules中的模塊
  user,
  product,
  windowInfo
 }
})

src/main.js

import ...
import store from './store' // 添加這行

new Vue({
 el: '#app',
 router,
 store, // 注入到根實(shí)例
 template: '<App/>',
 components: { App }
})

store的屬性

state(狀態(tài)對(duì)象)
state中存放多頁(yè)面共享的狀態(tài)字段

getters
相當(dāng)于當(dāng)前模塊state的計(jì)算屬性

mutations
如果想更新state中的字段,提交mutations中定義的事件是唯一的方式(key為事件名,value是一個(gè)函數(shù)),但是這個(gè)事件函數(shù)必須是同步執(zhí)行的

actions
可以定義異步函數(shù),并在回調(diào)中提交mutation,就相當(dāng)于異步更新了state中的字段

vuex數(shù)據(jù)傳遞規(guī)則

使用方法

把窗口的高度和寬度存到Vuex中,并且每當(dāng)窗口被resize,state中的高度和寬度自動(dòng)更新

src/store/modules/windowInfo.js

import { MU_WIN_RESIZE } from '../../common/constants'
const windowInfo = {
 state: {
  // 初始化
  winHeight: 0,
  winWidth: 0
 },
 mutations: {
  // 這里把事件名統(tǒng)一抽離到constants.js統(tǒng)一管理,方便維護(hù),避免重復(fù)。
  // 當(dāng)然,你也可以不這么寫。。
  // mutation事件接受的第一個(gè)參數(shù)是當(dāng)前模塊的state對(duì)象
  // 第二個(gè)參數(shù)是提交事件時(shí)傳遞的附加參數(shù)
  [MU_WIN_RESIZE] (state, payload) {
   const { winWidth, winHeight } = payload
   state.winWidth = winWidth
   state.winHeight = winHeight
  }
 },
 actions: {},
 getters: {}
}

export default windowInfo

src/common/constants.js

export const MU_WIN_RESIZE = 'MU_WIN_RESIZE' // 更新窗口尺寸

下面打開(kāi)項(xiàng)目的根組件添加監(jiān)聽(tīng)resize事件和提交mutation事件邏輯

src/App.vue

<!--上面的template我就不往這兒放了-->
<script>
 import { _on, _off, getClientWidth, getClientHeight } from './common/dom'
 import { MU_WIN_RESIZE } from './common/constants'
 import { mapMutations } from 'vuex'

 export default {
  name: 'app',
  data () {
   return {}
  },
  mounted () {
   this.handleResize()
   // 這里對(duì)addEventListener方法做了IE兼容處理,就不貼出來(lái)了,反正事件監(jiān)聽(tīng)你們都會(huì)
   _on(window, 'resize', this.handleResize)
  },
  beforeDestroy () {
   _off(window, 'resize', this.handleResize)
  },
  methods: {
   // 對(duì)象展開(kāi)運(yùn)算符,不熟悉的同學(xué)該學(xué)學(xué)ES6了
   ...mapMutations({
    // 映射 this.winResize 為 this.$store.commit(MU_WIN_RESIZE)
    winResize: MU_WIN_RESIZE
   }),
   handleResize () {
    const winWidth = getClientWidth()
    const winHeight = getClientHeight()
    this.winResize({ winWidth, winHeight })
   }
  }
 }
</script>

到這一步,在拖動(dòng)窗口觸發(fā)‘resize'事件的時(shí)候,就會(huì)觸發(fā)‘MU_WIN_RESIZE'這個(gè)mutation事件并把窗口寬高寫入vuex,下面我們隨便找個(gè)頁(yè)面看能不能獲取到我們寫入的值

<template>
 <div class="row">窗口高:{{winHeight}} 窗口寬:{{winWidth}}</div>
</template>
<script>
 import { mapState } from 'vuex'
 export default {
  name: 'test',
  data () {
   return {}
  },
  computed: {
   // 把state寫入計(jì)算屬性
   // 如果使用mapGetters也是寫入計(jì)算屬性
   ...mapState({
    winHeight: state => state.windowInfo.winHeight,
    winWidth: state => state.windowInfo.winWidth
   })
  },
 }
</script>

有的時(shí)候我們會(huì)從后端獲取一些下拉框選項(xiàng)的靜態(tài)常量,而且很多頁(yè)面都能用到,這個(gè)時(shí)候用Vuex是比較好的選擇,涉及到后端獲取,就要用到可以使用異步的actions了

src/store/modules/product.js

import {MU_PRODUCT_UPDATE_CONSTANTS} from '../../common/constants'

const product = {
 state: {
  productConstants: []
 },
 mutations: {
  [MU_PRODUCT_UPDATE_CONSTANTS] (state, payload) {
   state.productConstants = payload
  }
 },
 actions: {
  // action函數(shù)第一個(gè)參數(shù)接受一個(gè)與 store 實(shí)例具有相同方法和屬性的 context 對(duì)象,
  // 因此你可以調(diào)用 context.commit 提交一個(gè) mutation,
  // 或者通過(guò) context.state 和 context.getters 來(lái)獲取 state 和 getters
  // 這里雖然能獲取到state,但是不建議直接修改state中的字段
  async getProductConstants ({ commit }, payload) {
   try {
    // 請(qǐng)求接口,如果需要參數(shù)可以通過(guò)payload傳遞
    const res = await this.$api.product.getConstants()
    commit(MU_PRODUCT_UPDATE_CONSTANTS, res)
   } catch (e) {
    console.error(e)
   }
  }
 },
 getters: {}
}

export default product

下面觸發(fā)這個(gè)getProductConstants事件,觸發(fā)這個(gè)action事件的位置需要注意一下,假設(shè)你有5個(gè)組件需要使用這個(gè)state,那就應(yīng)該在這5個(gè)組件共同的父組件中調(diào)用一次action(找不到就在根實(shí)例中調(diào)用),然后在各個(gè)子組件中通過(guò)mapState或mapGetters獲取state,千萬(wàn)不要每個(gè)組件使用前都調(diào)用一次action方法!

src/App.vue

<!--為了更直觀的展示action,把之前的代碼刪掉了-->
<script>
 import { mapActions } from 'vuex' // 注意是mapActions

 export default {
  name: 'app',
  data () {
   return {}
  },
  created () {
   // 觸發(fā)請(qǐng)求
   this.getProductConstants()
  }
  methods: {
   ...mapActions([
    // 映射 this.getProductConstants 為 this.$store.dispatch('getProductConstants')
    'getProductConstants'
   ])
  }
 }
</script>

mapGetters, mapMutations, mapActions,這幾個(gè)函數(shù)可以接受對(duì)象也可以接受數(shù)組作為參數(shù),如果你需要在組件中以別的名字調(diào)用該事件(像上面的mapMutations)就可以傳入對(duì)象,key為新命名,value是store中定義的名字;否則的話傳數(shù)組就好了。

那么問(wèn)題來(lái)了,既然是異步操作,我想在操作結(jié)束后干點(diǎn)兒別的怎么做呢?
很簡(jiǎn)單,調(diào)用action中的異步函數(shù)(this.$store.dispatch)返回的是一個(gè)Promise,如果你跟我一樣用的是async await:

<!--為了更直觀的展示action,把之前的代碼刪掉了-->
<script>
 import { mapActions } from 'vuex' // 注意是mapActions

 export default {
  name: 'app',
  data () {
   return {}
  },
  async created () {
   // 觸發(fā)請(qǐng)求
   await this.getProductConstants()
   // 接下來(lái)執(zhí)行的操作會(huì)等待上面函數(shù)完成才會(huì)執(zhí)行
  }
  methods: {
   ...mapActions([
    // 映射 this.getProductConstants 為 this.$store.dispatch('getProductConstants')
    'getProductConstants'
   ])
  }
 }
</script>

如果你用的不是async await那就麻煩一點(diǎn),在actions中定義事件的時(shí)候return一個(gè)new Promise,官方文檔中有一個(gè)例子

表單處理

當(dāng)你把從state中獲取的字段填在v-model中時(shí),如果用戶修改表單數(shù)據(jù),v-model會(huì)嘗試直接修改store中的數(shù)據(jù),這樣做會(huì)有兩個(gè)問(wèn)題:

  1. 破壞了vuex的數(shù)據(jù)傳遞規(guī)則,如果想修改state中的數(shù)據(jù)只能通過(guò)提交一個(gè)mutation
  2. 控制臺(tái)報(bào)錯(cuò):計(jì)算屬性沒(méi)有setter

官方提供了兩種解決方法,我更傾向于下面這種,給計(jì)算屬性添加setter,并在setter中提交mutation修改state:

<template>
 <input v-model="message">
</template>
<script>
  export default {
  name: 'app',
  data () {
   return {}
  },
  computed: {
   message: {
    get () {
     return this.$store.state.test.message
    },
    set (value) {
     this.$store.commit('updateMessage', value)
    }
   }
  }
  methods: {}
 }
</script>

Vuex持久化

推薦插件vuex-persist

安裝插件:

npm install --save vuex-persist

引入、配置、加載插件:
src/store/persist.js

import VuexPersistence from 'vuex-persist'

const persist = new VuexPersistence({
 // 其他參數(shù)看文檔
 storage: window.sessionStorage
})
export default persist.plugin

src/store/index.js

import ...
import persist from './persist'

Vue.use(Vuex)

export default new Vuex.Store({
 modules: {
  user,
  product,
  windowInfo
 },
 plugins: [persist]
})

現(xiàn)在刷新瀏覽器數(shù)據(jù)也不會(huì)重置了!

總結(jié)

以上就是vuex比較常規(guī)的操作了,第一次看官方文檔的我是懵逼的、無(wú)助的,但是用了一段時(shí)間vuex再重新看文檔的時(shí)候會(huì)有很多收獲。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JavaScript迭代器的含義及用法

    JavaScript迭代器的含義及用法

    這篇文章主要介紹了JavaScript迭代器的含義及用法,迭代器就是為實(shí)現(xiàn)對(duì)不同集合進(jìn)行統(tǒng)一遍歷操作的一種機(jī)制,只要給需要遍歷的數(shù)據(jù)結(jié)構(gòu)部署Iterator接口,通過(guò)調(diào)用該接口,或者使用消耗該接口的API實(shí)現(xiàn)遍歷操作。,需要的朋友可以參考下
    2019-06-06
  • js實(shí)現(xiàn)動(dòng)態(tài)改變r(jià)adio狀態(tài)的方法

    js實(shí)現(xiàn)動(dòng)態(tài)改變r(jià)adio狀態(tài)的方法

    下面小編就為大家分享一篇js實(shí)現(xiàn)動(dòng)態(tài)改變r(jià)adio狀態(tài)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • js 輸入框 正則表達(dá)式(菜鳥(niǎo)必看教程)

    js 輸入框 正則表達(dá)式(菜鳥(niǎo)必看教程)

    下面小編就為大家?guī)?lái)一篇js輸入框使用正則表達(dá)式校驗(yàn)輸入內(nèi)容的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • JS遍歷數(shù)組及打印數(shù)組實(shí)例分析

    JS遍歷數(shù)組及打印數(shù)組實(shí)例分析

    這篇文章主要介紹了JS遍歷數(shù)組及打印數(shù)組的方法,結(jié)合實(shí)例形式分析JavaScript數(shù)組的遍歷與打印輸出相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • 詳解JavaScript邏輯Not運(yùn)算符

    詳解JavaScript邏輯Not運(yùn)算符

    這篇文章主要介紹了JavaScript邏輯Not運(yùn)算符,邏輯NOT運(yùn)算符與C和Java中的邏輯 NOT 運(yùn)算符相同,都由感嘆號(hào)(!)表示,想要深入了解邏輯Not運(yùn)算符的朋友可以參考一下
    2015-12-12
  • Javascript中document.referrer隱藏來(lái)源的方法

    Javascript中document.referrer隱藏來(lái)源的方法

    這篇文章主要介紹了Javascript中document.referrer隱藏來(lái)源的方法,文中通過(guò)一個(gè)實(shí)例給大家介紹了實(shí)現(xiàn)的方法,有需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • 詳解Javascript中new()到底做了些什么?

    詳解Javascript中new()到底做了些什么?

    javascript中,new操作符的工作原理是什么?它是怎樣改變構(gòu)造函數(shù)的返回值和this指向的?下面這篇文章就來(lái)給大家介紹了關(guān)于Javascript中new()到底做了些什么的相關(guān)資料,需要的朋友可以參考下。
    2018-03-03
  • JavaScript定義簡(jiǎn)單的頁(yè)面復(fù)選框?qū)崿F(xiàn)全選操作

    JavaScript定義簡(jiǎn)單的頁(yè)面復(fù)選框?qū)崿F(xiàn)全選操作

    本文主要介紹了JavaScript定義簡(jiǎn)單的頁(yè)面復(fù)選框?qū)崿F(xiàn)全選操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • JSONP基礎(chǔ)知識(shí)詳解

    JSONP基礎(chǔ)知識(shí)詳解

    JSONP是JSON with padding(填充式JSON或參數(shù)式JSON)的簡(jiǎn)寫,是應(yīng)用JSON的一種新方法,常用于務(wù)器與客戶端跨源通信,在后來(lái)的Web服務(wù)中非常流行。本文將詳細(xì)介紹JSONP,下面跟著小編一起來(lái)看下吧
    2017-03-03
  • JavaScript數(shù)組方法實(shí)例詳解

    JavaScript數(shù)組方法實(shí)例詳解

    本文將通過(guò)實(shí)例為大家詳細(xì)介紹JavaScript中的數(shù)組的所有方法。文中的示例代碼講解詳細(xì),對(duì)我們深入了解JavaScript數(shù)組有一定的幫助,需要的可以參考一下
    2021-12-12

最新評(píng)論

尤溪县| 宝应县| 石棉县| 乌兰县| 建昌县| 科尔| 沁水县| 泸州市| 赤峰市| 高邮市| 河津市| 武定县| 革吉县| 元谋县| 兴山县| 惠安县| 栖霞市| 贵港市| 神农架林区| 临颍县| 余姚市| 峨边| 定结县| 璧山县| 福州市| 望都县| 康马县| 连云港市| 宝应县| 霍城县| 宜川县| 瑞安市| 灵台县| 安徽省| 通渭县| 繁昌县| 富川| 东源县| 门头沟区| 汝南县| 和硕县|