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

Vue Getters和mapGetters的原理及使用示例詳解

 更新時(shí)間:2024年08月14日 10:14:11   作者:繁依Fanyi  
Vuex的核心概念包括state、mutations、actions、getters和modules,今天,我們要深入探討其中一個(gè)關(guān)鍵部分:getters,以及它的相關(guān)輔助函數(shù)mapGetters,感興趣的朋友跟隨小編一起看看吧

在Vue.js的狀態(tài)管理中,Vuex是一個(gè)非常重要的工具,它幫助開發(fā)者集中管理應(yīng)用的狀態(tài)。Vuex的核心概念包括state、mutations、actions、getters和modules。今天,我們要深入探討其中一個(gè)關(guān)鍵部分:getters,以及它的相關(guān)輔助函數(shù)mapGetters。通過詳細(xì)介紹getters的原理和實(shí)現(xiàn)過程,希望能幫助你更好地理解和使用它們。

什么是Vue Getters?

Vuex中的getters可以被視為store的計(jì)算屬性。就像Vue組件中的計(jì)算屬性一樣,getters的返回值會(huì)基于其依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生變化時(shí)才會(huì)重新計(jì)算。這使得getters非常適合用于從store中的state派生出一些狀態(tài)。

基本使用

首先,讓我們看一個(gè)簡(jiǎn)單的例子:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Learn Vue', done: true },
      { id: 2, text: 'Learn Vuex', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    }
  }
})

在上面的代碼中,我們定義了一個(gè)doneTodos的getter,它會(huì)返回所有已完成的任務(wù)。同時(shí),我們還定義了一個(gè)doneTodosCount的getter,它依賴于doneTodos,返回已完成任務(wù)的數(shù)量。

訪問Getters

你可以通過store.getters來訪問getters:

store.getters.doneTodos // -> [{ id: 1, text: 'Learn Vue', done: true }]
store.getters.doneTodosCount // -> 1

在組件中使用Getters

在Vue組件中,你可以使用this.$store.getters來訪問getters:

computed: {
  doneTodos () {
    return this.$store.getters.doneTodos
  }
}

這雖然工作正常,但對(duì)于多個(gè)getters的訪問會(huì)顯得有些冗長(zhǎng)。為了解決這個(gè)問題,我們可以使用mapGetters輔助函數(shù)。

使用mapGetters

mapGetters是一個(gè)輔助函數(shù),它可以幫助我們將store中的getter映射到局部計(jì)算屬性。它可以極大地簡(jiǎn)化在組件中使用getters的代碼量。

基本使用

首先,我們需要在組件中導(dǎo)入mapGetters

import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters([
      'doneTodos',
      'doneTodosCount'
    ])
  }
}

現(xiàn)在,我們可以直接在模板中使用這些計(jì)算屬性:

<template>
  <div>
    <p>Done Todos: {{ doneTodos }}</p>
    <p>Done Todos Count: {{ doneTodosCount }}</p>
  </div>
</template>

別名

有時(shí)候,我們可能想要為映射的計(jì)算屬性指定別名。這時(shí)可以使用對(duì)象形式的參數(shù):

computed: {
  ...mapGetters({
    completedTasks: 'doneTodos',
    completedTasksCount: 'doneTodosCount'
  })
}

這樣,我們就可以在模板中使用別名:

<template>
  <div>
    <p>Completed Tasks: {{ completedTasks }}</p>
    <p>Completed Tasks Count: {{ completedTasksCount }}</p>
  </div>
</template>

Getters的原理和實(shí)現(xiàn)

為了更深入地理解getters的工作原理,我們需要了解Vuex的內(nèi)部實(shí)現(xiàn)。Vuex是基于Vue的響應(yīng)系統(tǒng)構(gòu)建的,因此getters的實(shí)現(xiàn)與Vue的計(jì)算屬性有很多相似之處。

創(chuàng)建Getters

當(dāng)我們創(chuàng)建一個(gè)store時(shí),Vuex會(huì)遍歷我們定義的所有g(shù)etters,并為每一個(gè)getter創(chuàng)建一個(gè)計(jì)算屬性。這些計(jì)算屬性的結(jié)果會(huì)被緩存,只有當(dāng)它們的依賴(即state或者其他getters)發(fā)生變化時(shí)才會(huì)重新計(jì)算。

class Store {
  constructor (options = {}) {
    // ...
    const store = this
    const { getters } = options
    this.getters = {}
    Object.keys(getters).forEach(key => {
      const fn = getters[key]
      Object.defineProperty(store.getters, key, {
        get: () => fn(store.state, store.getters)
      })
    })
    // ...
  }
}

在上面的代碼中,我們可以看到Vuex通過Object.defineProperty為每一個(gè)getter定義了一個(gè)屬性,這個(gè)屬性的getter函數(shù)會(huì)返回計(jì)算后的結(jié)果。

響應(yīng)式系統(tǒng)

Vuex的state是響應(yīng)式的,這意味著當(dāng)我們改變state中的數(shù)據(jù)時(shí),所有依賴于這些數(shù)據(jù)的getters都會(huì)自動(dòng)更新。Vuex通過Vue的Vue.observable方法將state變成響應(yīng)式對(duì)象。

const state = Vue.observable({
  todos: [
    { id: 1, text: 'Learn Vue', done: true },
    { id: 2, text: 'Learn Vuex', done: false }
  ]
})

這樣,當(dāng)我們改變state中的todos時(shí),所有依賴于todos的getters(例如doneTodosdoneTodosCount)都會(huì)自動(dòng)重新計(jì)算,并觸發(fā)相關(guān)的視圖更新。

深入理解mapGetters

mapGetters是Vuex提供的一個(gè)非常有用的輔助函數(shù),它的實(shí)現(xiàn)也相對(duì)簡(jiǎn)單。mapGetters的主要作用是將store中的getters映射到組件的計(jì)算屬性。

mapGetters的實(shí)現(xiàn)

我們來看看mapGetters的實(shí)現(xiàn):

export function mapGetters (getters) {
  const res = {}
  normalizeMap(getters).forEach(({ key, val }) => {
    res[key] = function mappedGetter () {
      return this.$store.getters[val]
    }
  })
  return res
}

在上面的代碼中,mapGetters首先通過normalizeMap函數(shù)將傳入的參數(shù)規(guī)范化為一個(gè)數(shù)組,然后遍歷這個(gè)數(shù)組,為每一個(gè)getter創(chuàng)建一個(gè)計(jì)算屬性。這些計(jì)算屬性的getter函數(shù)會(huì)返回this.$store.getters中的對(duì)應(yīng)值。

使用normalizeMap

normalizeMap函數(shù)的作用是將傳入的參數(shù)(可以是數(shù)組或?qū)ο螅┮?guī)范化為一個(gè)標(biāo)準(zhǔn)的對(duì)象數(shù)組:

function normalizeMap (map) {
  if (!isValidMap(map)) {
    return []
  }
  return Array.isArray(map)
    ? map.map(key => ({ key, val: key }))
    : Object.keys(map).map(key => ({ key, val: map[key] }))
}

如果傳入的是一個(gè)數(shù)組,normalizeMap會(huì)將每一個(gè)數(shù)組元素轉(zhuǎn)化為一個(gè)對(duì)象,鍵和值相同;如果傳入的是一個(gè)對(duì)象,normalizeMap會(huì)將每一個(gè)鍵值對(duì)轉(zhuǎn)化為一個(gè)對(duì)象,鍵和值分別對(duì)應(yīng)原對(duì)象的鍵和值。

Getters和mapGetters的實(shí)際應(yīng)用

在實(shí)際項(xiàng)目中,getters和mapGetters可以幫助我們更好地組織和管理應(yīng)用狀態(tài)。讓我們通過一個(gè)稍微復(fù)雜的例子來進(jìn)一步理解它們的實(shí)際應(yīng)用。

例子:Todo應(yīng)用

假設(shè)我們?cè)陂_發(fā)一個(gè)Todo應(yīng)用,這個(gè)應(yīng)用需要展示所有任務(wù)、已完成任務(wù)、未完成任務(wù)以及任務(wù)的數(shù)量。我們可以通過getters來實(shí)現(xiàn)這些功能。

首先,我們定義store的state和getters:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Learn Vue', done: true },
      { id: 2, text: 'Learn Vuex', done: false },
      { id: 3, text: 'Build something awesome', done: false }
    ]
  },
  getters: {
    allTodos: state => state.todos,
    doneTodos: state => state.todos.filter(todo => todo.done),
    undoneTodos: state => state.todos.filter(todo => !todo.done),
    totalTodosCount: state => state.todos.length,
    doneTodosCount: (state, getters) => getters.doneTodos.length,
    undoneTodosCount: (state, getters) => getters.undoneTodos.length
  }
})

然后,在組件中使用這些getters:

import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters([
      'allTodos',
      'doneTodos',
      'undoneTodos',
      'totalTodosCount',
      'doneTodosCount',
      'undoneTodosCount'
    ])
  }
}

在模板中展示任務(wù)和統(tǒng)計(jì)信息:

<template>
  <div>
    <h1>Todo List</h1>
    <p>Total Todos: {{ totalTodosCount }}</p>
    <p>Done Todos: {{ doneTodosCount }}</p>
    <p>Undone Todos: {{ undoneTodosCount }}</p>
    <h2>All Todos</h2>
    <ul>
      <li v-for="todo in allTodos" :key="todo.id">{{ todo.text }}</li>
    </ul>
    <h2>Done Todos</h2>
    <ul>
      <li v-for="todo in doneTodos" :key="todo.id">{{ todo.text }}</li>
    </ul>
    <h2>Undone Todos</h2>
    <ul>
      <li v-for="todo in undoneTodos" :key="todo.id">{{ todo.text }}</li>
    </ul>
  </div>
</template>

通過這種方式,我們可以清晰地展示所有任務(wù)、已完成任務(wù)和未完成任務(wù),以及相關(guān)的統(tǒng)計(jì)信息。而且,這些數(shù)據(jù)都是通過getters從state派生出來的,當(dāng)state中的任務(wù)列表發(fā)生變化時(shí),視圖會(huì)自動(dòng)更新。

優(yōu)化和最佳實(shí)踐

在實(shí)際開發(fā)中,除了正確使用getters和mapGetters,我們還可以采取一些優(yōu)化和最佳實(shí)踐來提升代碼的可維護(hù)性和性能。

避免不必要的計(jì)算

雖然getters的結(jié)果會(huì)被緩存,但在設(shè)計(jì)getters時(shí)仍然要注意避免不必要的計(jì)算。例如,如果一個(gè)getter依賴于另一個(gè)getter,我們應(yīng)該盡量減少重復(fù)計(jì)算。

模塊化

對(duì)于大型應(yīng)用,我們可以將store拆分成多個(gè)模塊,每個(gè)模塊都有自己的state、mutations、actions和getters。這樣可以使代碼更清晰,更易于管理。

const moduleA = {
  state: () => ({
    todos: []
  }),
  getters: {
    doneTodos: state => state.todos.filter(todo => todo.done)
  },
  mutations: {
    // ...
  },
  actions: {
    // ...
  }
}
const store = new Vuex.Store({
  modules: {
    a: moduleA
  }
})

在組件中使用模塊的getters:

computed: {
  ...mapGetters('a', [
    'doneTodos'
  ])
}

異步操作

雖然getters不應(yīng)該包含異步操作,但我們可以在actions中進(jìn)行異步操作,然后通過mutations更新state,從而觸發(fā)getters的重新計(jì)算。

const store = new Vuex.Store({
  state: {
    todos: []
  },
  getters: {
    doneTodos: state => state.todos.filter(todo => todo.done)
  },
  mutations: {
    setTodos (state, todos) {
      state.todos = todos
    }
  },
  actions: {
    fetchTodos ({ commit }) {
      // 假設(shè)我們有一個(gè)API調(diào)用來獲取todos
      fetchTodosFromAPI().then(todos => {
        commit('setTodos', todos)
      })
    }
  }
})

性能優(yōu)化

在高性能需求的應(yīng)用中,我們可以利用Vuex的插件系統(tǒng)來優(yōu)化getters的性能。例如,我們可以編寫一個(gè)插件來對(duì)getters的結(jié)果進(jìn)行緩存,從而避免頻繁的計(jì)算。

function createGettersCachePlugin () {
  return store => {
    const cache = {}
    store.subscribe((mutation, state) => {
      // 在每次mutation后清除緩存
      Object.keys(cache).forEach(key => delete cache[key])
    })
    store._wrappedGetters = Object.keys(store._wrappedGetters).reduce((wrappedGetters, key) => {
      const getter = store._wrappedGetters[key]
      wrappedGetters[key] = (state, getters) => {
        if (!cache[key]) {
          cache[key] = getter(state, getters)
        }
        return cache[key]
      }
      return wrappedGetters
    }, {})
  }
}
const store = new Vuex.Store({
  // ...
  plugins: [createGettersCachePlugin()]
})

這個(gè)插件在每次mutation后清除緩存,并對(duì)getters的結(jié)果進(jìn)行緩存,從而減少不必要的計(jì)算。

總結(jié)

Vuex的getters和mapGetters是非常強(qiáng)大的工具,它們可以幫助我們從store中的state派生出新的狀態(tài),并在組件中方便地使用這些狀態(tài)。在實(shí)際開發(fā)中,我們可以通過合理使用getters和mapGetters,提高代碼的可維護(hù)性和性能。同時(shí),我們還可以采用一些優(yōu)化和最佳實(shí)踐,使我們的應(yīng)用更加健壯和高效。

希望通過本文的詳細(xì)介紹,你能夠?qū)uex的getters和mapGetters有更深入的理解,并在實(shí)際項(xiàng)目中更好地應(yīng)用它們。祝你在Vue.js的世界中編程愉快!

到此這篇關(guān)于Vue Getters和mapGetters的原理及使用示例詳解的文章就介紹到這了,更多相關(guān)Vue Getters和mapGetters使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue實(shí)現(xiàn)PopupWindow組件詳解

    Vue實(shí)現(xiàn)PopupWindow組件詳解

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)PopupWindow組件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • vue 解決addRoutes多次添加路由重復(fù)的操作

    vue 解決addRoutes多次添加路由重復(fù)的操作

    這篇文章主要介紹了vue 解決addRoutes多次添加路由重復(fù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • elementui之封裝下載模板和導(dǎo)入文件組件方式

    elementui之封裝下載模板和導(dǎo)入文件組件方式

    這篇文章主要介紹了關(guān)于elementui之封裝下載模板和導(dǎo)入文件組件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vuejs在解析時(shí)出現(xiàn)閃爍的原因及防止閃爍的方法

    vuejs在解析時(shí)出現(xiàn)閃爍的原因及防止閃爍的方法

    這篇文章主要介紹了vuejs在解析時(shí)出現(xiàn)閃爍的原因及防止閃爍的方法,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-09-09
  • 自定義Vue中的v-module雙向綁定的實(shí)現(xiàn)

    自定義Vue中的v-module雙向綁定的實(shí)現(xiàn)

    這篇文章主要介紹了自定義Vue中的v-module雙向綁定的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue下載二進(jìn)制流圖片操作

    vue下載二進(jìn)制流圖片操作

    這篇文章主要介紹了vue下載二進(jìn)制流圖片操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 解決Vue + Echarts 使用markLine標(biāo)線(precision精度問題)

    解決Vue + Echarts 使用markLine標(biāo)線(precision精度問題)

    這篇文章主要介紹了解決Vue + Echarts 使用markLine標(biāo)線(precision精度問題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • vue?perfect-scrollbar(特定框架里使用非該框架定制庫/插件)

    vue?perfect-scrollbar(特定框架里使用非該框架定制庫/插件)

    這篇文章主要為大家介紹了vue?perfect-scrollbar在特定框架里使用一款并非為該框架定制的庫/插件如何實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2023-05-05
  • 深入淺出vue圖片路徑的實(shí)現(xiàn)

    深入淺出vue圖片路徑的實(shí)現(xiàn)

    這篇文章主要介紹了深入淺出vue圖片路徑的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • vue3.x?的shallowReactive?與?shallowRef?使用場(chǎng)景分析

    vue3.x?的shallowReactive?與?shallowRef?使用場(chǎng)景分析

    在Vue3.x中,`shallowReactive`和`shallowRef`是用于創(chuàng)建淺層響應(yīng)式數(shù)據(jù)的API,它們與`reactive`和`ref`類似,本文介紹vue3.x??shallowReactive?與?shallowRef的使用場(chǎng)景,感興趣的朋友一起看看吧
    2025-02-02

最新評(píng)論