欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何手寫一個(gè)簡易的 Vuex

 更新時(shí)間:2020年10月10日 10:12:03   作者:jacky-summer  
這篇文章主要介紹了如何手寫一個(gè)簡易的 Vuex,幫助大家更好的理解和學(xué)習(xí)vue,感興趣的朋友可以了解下

前言

本文適合使用過 Vuex 的人閱讀,來了解下怎么自己實(shí)現(xiàn)一個(gè) Vuex。

基本骨架

這是本項(xiàng)目的src/store/index.js文件,看看一般 vuex 的使用

import Vue from 'vue'
import Vuex from './myvuex' // 引入自己寫的 vuex
import * as getters from './getters'
import * as actions from './actions'
import state from './state'
import mutations from './mutations'

Vue.use(Vuex) // Vue.use(plugin)方法使用vuex插件

// vuex 導(dǎo)出一個(gè)類叫Store,并傳入對象作為參數(shù)
export default new Vuex.Store({
 state,
 mutations,
 actions,
 getters,
})

Vue.use的用法:

安裝 Vue.js 插件。如果插件是一個(gè)對象,必須提供 install 方法。如果插件是一個(gè)函數(shù),它會被作為 install 方法。install 方法調(diào)用時(shí),會將 Vue 作為參數(shù)傳入。這個(gè)方法的第一個(gè)參數(shù)是 Vue 構(gòu)造器,第二個(gè)參數(shù)是一個(gè)可選的選項(xiàng)對象。

  • 該方法需要在調(diào)用 new Vue() 之前被調(diào)用。
  • 當(dāng) install 方法被同一個(gè)插件多次調(diào)用,插件將只會被安裝一次。

即是我們需要在./myvuex.js中導(dǎo)出 install方法,同時(shí)導(dǎo)出一個(gè)類Store,于是第一步可以寫出代碼:

let Vue = null

class Store {
 constructor(options) {}
}

function install(_Vue) {
 Vue = _Vue // 上面Store類需要能獲取到Vue
}

export default {
 Store,
 install,
}

install 方法

當(dāng)我們使用 vuex 的時(shí)候,每一個(gè)組件上面都有一個(gè)this.$store屬性,里面包含了 state,mutations, actions, getters 等,所以我們也需要在每個(gè)組件上都掛載一個(gè)$store 屬性,要讓每一個(gè)組件都能獲取到,這里我們使用Vue.mixin(mixin),用法介紹如下:

全局注冊一個(gè)混入,影響注冊之后所有創(chuàng)建的每個(gè) Vue 實(shí)例??梢允褂没烊胂蚪M件注入自定義的行為,它將影響每一個(gè)之后創(chuàng)建的 Vue 實(shí)例。

function install(_Vue) {
 Vue = _Vue // install方法調(diào)用時(shí),會將Vue作為參數(shù)傳入(上面Store類需要用到Vue)
 // 實(shí)現(xiàn)每一個(gè)組件,都能通過this調(diào)用$store
 Vue.mixin({
  beforeCreate() {
   // 通過this.$options可以獲取new Vue({參數(shù)}) 傳遞的參數(shù)
   if (this.$options && this.$options.store) {
    // 證明這個(gè)this是根實(shí)例,也就是new Vue產(chǎn)生的那個(gè)實(shí)例
    this.$store = this.$options.store
   } else if (this.$parent && this.$parent.$store) {
    // 子組件獲取父組件的$store屬性
    this.$store = this.$parent.$store
   }
  },
 })
}

state

由于 Vuex 是基于 Vue 的響應(yīng)式原理基礎(chǔ),所以我們要讓數(shù)據(jù)改變可刷新視圖,則需要創(chuàng)建一個(gè) vue 實(shí)例

class Store {
 // options 即是 Vuex.Store({})傳入的參數(shù)
 constructor(options) {
  // vuex 的核心就是借用了vue的實(shí)例,因?yàn)関ue的實(shí)例數(shù)據(jù)變化,會刷新視圖
  let vm = new Vue({
   data: {
    state: options.state,
   },
  })
  // state
  this.state = vm.state
 }
}

commit

我們使用 vuex 改變數(shù)據(jù)時(shí),是觸發(fā) commit 方法,即是這樣使用的:

this.$store.commit('eventName', '參數(shù)' );

所以我們要實(shí)現(xiàn)一個(gè)commit方法,把 Store 構(gòu)造函數(shù)傳入的 mutations 做下處理

class Store {
 constructor(options) {
  // 實(shí)現(xiàn) state ...

  // mutations
  this.mutations = {} // 存儲傳進(jìn)來的mutations
  let mutations = options.mutations || {}
  // 循環(huán)取出事件名進(jìn)行處理(mutations[事件名]: 執(zhí)行方法)
  Object.keys(mutations).forEach(key => {
   this.mutations[key] = params => {
    mutations[key].call(this, this.state, params) // 修正this指向
   }
  })
 }

 commit = (key, params) => {
  // key為要觸發(fā)的事件名
  this.mutations[key](params)
 }
}

dispatch

跟上面的 commit 流程同理

class Store {
 constructor(options = {}) {
  // ...

  // actions
  this.actions = {}
  let actions = options.actions || {}
  Object.keys(actions).forEach(key => {
   this.actions[key] = params => {
    actions[key].call(this, this, params)
   }
  })
 }

 dispatch = (type, payload) => {
  this.actions[type](payload)
 }
}

getters

getters 實(shí)際就是返回 state 的值,在使用的時(shí)候是放在 computed 屬性,每一個(gè) getter 都是函數(shù)形式;

getters 是需要雙向綁定的。但不需要雙向綁定所有的 getters,只需要綁定項(xiàng)目中事件使用的 getters。

這里使用Object.defineProperty()方法,它會直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性,并返回此對象。

class Store {
 constructor(options = {}) {
  // ...

  // getters
  this.getters = {}
  let getters = options.getters || {}
  Object.keys(getters).forEach(key => {
   Object.defineProperty(this.getters, key, {
    get: () => {
     return getters[key].call(this, this.state)
    },
   })
  })
 }
}

到此為止,已經(jīng)可以使用我們自己寫的 vuex 做一些基本操作了,但只能通過this.$store.xx的形式調(diào)用,故需要再實(shí)現(xiàn)方法。

map 輔助函數(shù)

先來說說 mapState

沒有 map 輔助函數(shù)之前這樣使用:

computed: {
 count () {
  return this.$store.state.count
 }
}

當(dāng)映射的計(jì)算屬性的名稱與 state 的子節(jié)點(diǎn)名稱相同時(shí),給 mapState 傳一個(gè)字符串?dāng)?shù)組。

computed: {
 // 使用對象展開運(yùn)算符將此對象混入到外部對象中
 ...mapState(['count'])
}

我們這里簡單就只實(shí)現(xiàn)數(shù)組的情況

export const mapState = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function() {
   return this.$store.state[item]
  }
 })
 return obj
}

之后幾個(gè) map 輔助函數(shù)都是類似

  • mapGetters
export const mapGetters = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function() {
   return this.$store.getters[item]
  }
 })
 return obj
}
  • mapMutations
export const mapMutations = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function(params) {
   return this.$store.commit(item, params)
  }
 })
 return obj
}
  • mapActions
export const mapActions = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function(payload) {
   return this.$store.dispatch(item, payload)
  }
 })
 return obj
}

完整代碼

let Vue = null

class Store {
 constructor(options) {
  // vuex 的核心就是借用了vue的實(shí)例,因?yàn)関ue的實(shí)例數(shù)據(jù)變化,會刷新視圖
  let vm = new Vue({
   data: {
    state: options.state,
   },
  })
  // state
  this.state = vm.state

  // mutations
  this.mutations = {} // 存儲傳進(jìn)來的mutations
  let mutations = options.mutations || {}
  Object.keys(mutations).forEach(key => {
   this.mutations[key] = params => {
    mutations[key].call(this, this.state, params)
   }
  })

  // actions
  this.actions = {}
  let actions = options.actions || {}
  Object.keys(actions).forEach(key => {
   this.actions[key] = params => {
    actions[key].call(this, this, params)
   }
  })

  // getters
  this.getters = {}
  let getters = options.getters || {}
  Object.keys(getters).forEach(key => {
   Object.defineProperty(this.getters, key, {
    get: () => {
     return getters[key].call(this, this.state)
    },
   })
  })
 }

 commit = (key, params) => {
  this.mutations[key](params)
 }

 dispatch = (type, payload) => {
  this.actions[type](payload)
 }
}

export const mapState = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function() {
   return this.$store.state[item]
  }
 })
 return obj
}

export const mapGetters = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function() {
   return this.$store.getters[item]
  }
 })
 return obj
}

export const mapMutations = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function(params) {
   return this.$store.commit(item, params)
  }
 })
 return obj
}

export const mapActions = args => {
 let obj = {}
 args.forEach(item => {
  obj[item] = function(payload) {
   return this.$store.dispatch(item, payload)
  }
 })
 return obj
}

function install(_Vue) {
 Vue = _Vue // install方法調(diào)用時(shí),會將Vue作為參數(shù)傳入(上面Store類需要用到Vue)
 // 實(shí)現(xiàn)每一個(gè)組件,都能通過this調(diào)用$store
 Vue.mixin({
  beforeCreate() {
   // 通過this.$options可以獲取new Vue({參數(shù)}) 傳遞的參數(shù)
   if (this.$options && this.$options.store) {
    // 證明這個(gè)this是根實(shí)例,也就是new Vue產(chǎn)生的那個(gè)實(shí)例
    this.$store = this.$options.store
   } else if (this.$parent && this.$parent.$store) {
    // 子組件獲取父組件的$store屬性
    this.$store = this.$parent.$store
   }
  },
 })
}

export default {
 Store,
 install,
}

以上就是如何手寫一個(gè)簡易的 Vuex的詳細(xì)內(nèi)容,更多關(guān)于手寫 vuex的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • BuildAdmin elementPlus自定義表頭添加tooltip方法示例

    BuildAdmin elementPlus自定義表頭添加tooltip方法示例

    這篇文章主要介紹了BuildAdmin elementPlus 自定義表頭,添加tooltip實(shí)現(xiàn)方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Vue進(jìn)階之利用transition標(biāo)簽實(shí)現(xiàn)頁面跳轉(zhuǎn)動畫

    Vue進(jìn)階之利用transition標(biāo)簽實(shí)現(xiàn)頁面跳轉(zhuǎn)動畫

    這篇文章主要為大家詳細(xì)介紹了Vue如何利用transition標(biāo)簽實(shí)現(xiàn)頁面跳轉(zhuǎn)動畫,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起一下
    2023-08-08
  • WebStorm啟動vue項(xiàng)目報(bào)錯代碼:1080?throw?err解決辦法

    WebStorm啟動vue項(xiàng)目報(bào)錯代碼:1080?throw?err解決辦法

    在使用webstorm新建vue項(xiàng)目時(shí)常會遇到一些報(bào)錯,下面這篇文章主要給大家介紹了關(guān)于WebStorm啟動vue項(xiàng)目報(bào)錯代碼:1080?throw?err的解決辦法,文中將解決辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 如何在vue 中使用柱狀圖 并自修改配置

    如何在vue 中使用柱狀圖 并自修改配置

    這篇文章主要介紹了如何在vue 中使用柱狀圖 并自修改配置,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-01-01
  • 如何使用vue開發(fā)公眾號網(wǎng)頁

    如何使用vue開發(fā)公眾號網(wǎng)頁

    因?yàn)轫?xiàng)目需要,近期做了一個(gè)公眾號網(wǎng)頁開發(fā)。在此期間也踩了一些坑,解決這些坑之后,準(zhǔn)備對這個(gè)項(xiàng)目進(jìn)行復(fù)盤。記錄下項(xiàng)目從開發(fā)到上線所解決的問題,并對使用vue進(jìn)行公眾號開發(fā)的步驟進(jìn)行一個(gè)總結(jié)。方便以后有問題進(jìn)行查閱。希望對你有所幫助
    2021-05-05
  • uniapp使用webview內(nèi)嵌H5的注意事項(xiàng)詳解

    uniapp使用webview內(nèi)嵌H5的注意事項(xiàng)詳解

    在移動應(yīng)用開發(fā)中,uniApp框架提供了一種跨平臺的解決方案,允許開發(fā)者使用一套代碼來構(gòu)建iOS、Android等多平臺的應(yīng)用,這篇文章主要給大家介紹了關(guān)于uniapp使用webview內(nèi)嵌H5的注意事項(xiàng),需要的朋友可以參考下
    2024-07-07
  • 基于vue-cli npm run build之后vendor.js文件過大的解決方法

    基于vue-cli npm run build之后vendor.js文件過大的解決方法

    今天小編就為大家分享一篇基于vue-cli npm run build之后vendor.js文件過大的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 基于Vue.js的表格分頁組件

    基于Vue.js的表格分頁組件

    這篇文章主要為大家詳細(xì)介紹了基于Vue.js的表格分頁組件使用方法,了解了Vue.js的特點(diǎn),感興趣的朋友可以參考一下
    2016-05-05
  • vue-cli創(chuàng)建的項(xiàng)目中的gitHooks原理解析

    vue-cli創(chuàng)建的項(xiàng)目中的gitHooks原理解析

    這篇文章主要介紹了vue-cli創(chuàng)建的項(xiàng)目中的gitHooks原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 基于Vue+element-ui 的Table二次封裝的實(shí)現(xiàn)

    基于Vue+element-ui 的Table二次封裝的實(shí)現(xiàn)

    這篇文章主要介紹了基于Vue+element-ui 的Table二次封裝的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論