Vuex es suficiente para entender esto en combate real.

Tabla de contenido

 

1. Instalación

1.1. Agregar dependencia

1.2. Introducido en el proyecto

1.3. Ejemplos

main.js

store.js

flightInfo.js (gestión de estado modular)

type.js (nombre de mutaciones constantes)

2. Uso

2.1. Expresar

2.1.1. Definir estado

2.1.2. Estado de importación

2.2. Adquiridor

2.2.1. Definir un captador

2.2.2. Importar el captador

2.3. Mutación

2.3.1. Definición de mutación

2.3.2. Desencadenante de la mutación

2.3.3. Llevar parámetros al disparar

2.3.4. Usar constantes para definir tipos de eventos de mutación

2.3.5. La mutación debe ser una función sincrónica

2.4. Acción

2.4.1. Acción de registro

2.4.2. Distribuir acción


1. Instalación

1.1. Agregar dependencia

npm install vuex --save

  Vuex confía en Promise. Si el navegador que admite no implementa Promise, puede usar una biblioteca polyfill, como  es6-promise .

npm install es6-promise --save

1.2. Introducido en el proyecto

Tome la última arquitectura vue-cli3 como ejemplo, agréguela a src / main.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

De manera más general, generalmente hay un archivo js de administración de estado dedicado, como store.js

Solo store.js se introduce en main.js. Y agregue la parte citada anteriormente en store.js. En el futuro, la gestión de estado relacionada se realizará en store.js.

1.3. Ejemplos

Primero pegue algunos ejemplos de combate real para comprender el uso intuitivo

main.js

Consulte la parte main.js del artículo "El combate real del enrutador Vue para comprender esto es suficiente ".

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import flightInfo from './modules/flightInfo'
Vue.use(Vuex)

export default new Vuex.Store({

  modules: {
    flightInfo
  },
  state: {

  },
  mutations: {

  },
  actions: {

  }
})

flightInfo.js (gestión de estado modular)

import * as types from '../type'

const state = {
  flightInfo: []
}

const getters = {
  getflightInfo: state => state.flightInfo
}

const actions = {
  saveFlightInfo ({ commit }, data) {
    return new Promise(resolve => {
      commit(types.FLIGHTINFO, data)
      resolve(data)
    })
  }
}

const mutations = {
  [types.FLIGHTINFO] (state, data) {
    state.flightInfo = data
    localStorage.setItem('flightInfo', JSON.stringify(state.flightInfo))
  }
}

export default {
  state,
  actions,
  getters,
  mutations
}

type.js (nombre de mutaciones constantes)

export const FLIGHTINFO = 'FLIGHTINFO'

La organización del directorio de cada archivo js mencionado anteriormente es la siguiente:

src

------ main.js

------ Tienda

------------ store.js

------------ type.js

------------ módulo

------------------ flightInfo.js

 

2. Uso

Principios de la gestión estatal de vuex

 

2.1. Expresar

Vuex usa un único árbol de estado, lo que también significa que cada aplicación solo contendrá una instancia de tienda.

2.1.1. Definir estado

const store = new Vuex.Store({
  state: {
    count: 0
  }
})

2.1.2. Estado de importación

  • Método 1: Calcular atributos (los objetos de la tienda se importan por separado)

Dado que el almacenamiento de estado de Vuex responde, la forma más fácil de leer el estado de la instancia de la tienda es devolver un cierto estado en el atributo calculado:

const Counter = {
  template: `<div>{
   
   { count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

Desventajas: cada componente que necesita usar el estado requiere una importación frecuente de la tienda

  • Método 2: cálculo de atributos (importación global de objetos de tienda)

Vuex proporciona un mecanismo para inyectar el estado desde el componente raíz en cada componente secundario a través de la opción de tienda (debe llamar a Vue.use (Vuex) ):

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

Al registrar la opción de tienda en la instancia raíz, la instancia de la tienda se inyectará en todos los componentes secundarios del componente raíz, y se puede acceder a los componentes secundarios a través de este. $ Store. Actualicemos la implementación de Counter:

const Counter = {
  template: `<div>{
   
   { count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

Desventajas: cuando un componente necesita obtener varios estados, declarar estos estados como propiedades calculadas será algo repetitivo y redundante. 

  • Método 3: función auxiliar mapState (importación global de objeto de tienda)
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

import { mapState } from 'vuex';

const store = new Vuex.Store({
    state: {
        count: 3
    }
});
new Vue({ 
    el: '#app',
    store,
    data() {
        return {
            localCount: 4
        }
    },
    computed: mapState({
        count: state => state.count,
        // 传字符串参数 'count' 等同于 `state => state.count`
        countAlias: 'count',
        // 为了能够使用 `this` 获取局部状态,必须使用常规函数(相对于箭头函数)
        countPlusLocalState (state) {
            return state.count + this.localCount
        }
    })
});

Cuando el nombre del atributo calculado mapeado es el mismo que el nombre del nodo secundario del estado, también podemos pasar una matriz de cadenas a mapState.

computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])

Método 4: función auxiliar mapState + expansor de objetos (importación global de objetos de tienda)

La función mapState devuelve un objeto. ¿Cómo podemos mezclarlo con propiedades computacionales locales?

computed: {
  localComputed () { // ...  },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

2.2. Adquiridor

¿A veces necesitamos derivar algún estado del estado en la tienda?

Vuex nos permite definir "getter" en la tienda (se puede pensar en un atributo calculado de la tienda). Al igual que una propiedad calculada, el valor de retorno de un captador se almacenará en caché de acuerdo con sus dependencias y se volverá a calcular solo cuando su valor dependiente haya cambiado.

2.2.1. Definir un captador

Getter acepta el estado como su primer parámetro:

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

Getter también puede aceptar otros getters como segundo parámetro:

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}

2.2.2. Importar el captador

1. Por atributos

Getter se expondrá como objeto store.getters, puede acceder a estos valores en forma de propiedades

Método 1: introducir el objeto de la tienda por separado (importar store.js a través de la importación)

store.getters.doneTodos

Método 2: inyectar globalmente el objeto de la tienda (a través de la opción de tienda en Vue)

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

2. Método de paso

Camino 3

Pasar parámetros al getter se logra dejando que el getter devuelva una función. Es muy útil cuando consulta la matriz en la tienda.

getters: {
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

Tenga en cuenta que cuando se accede al getter a través del método, se llamará cada vez y el resultado no se almacenará en caché.

Método 4: función auxiliar mapGetters + expansor de objetos (importación global de objetos de tienda)

La función auxiliar mapGetters simplemente asigna los captadores en la tienda a las propiedades calculadas locales:

import { mapGetters } from 'vuex'

export default {
  computed: {
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

Si desea dar otro nombre a una propiedad de captador, use la forma de objeto:

mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})

 

2.3. Mutación

2.3.1. Definición de mutación

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

2.3.2. Desencadenante de la mutación

Camino 1

store.commit('increment')

Modo 2: mapMutations identificador de función de promotor secundario + objeto + tienda expande los objetos de importación global

mport { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

 

2.3.3. Llevar parámetros al disparar

Los parámetros son tipos primitivos

mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

El parámetro es el tipo de objeto

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {amount: 10})

2.3.4. Usar constantes para definir tipos de eventos de mutación

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state) {
      // mutate state
    }
  }
})

2.3.5. La mutación debe ser una función sincrónica

 

2.4. Acción

La acción es similar a la mutación, excepto que:

  • La acción presenta una mutación en lugar de cambiar directamente el estado.
  • La acción puede contener cualquier operación asincrónica.

2.4.1. Acción de registro

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

La función Action acepta un objeto de contexto con los mismos métodos y propiedades que la instancia de la tienda, por lo que puede llamar a context.commit para enviar una mutación u obtener state y getters a través de context.state y context.getters.

Use la desestructuración de parámetros de ES2015   para simplificar el código (especialmente cuando necesitamos llamarlo  commit muchas veces):

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

2.4.2. Distribuir acción

Método 1: los objetos de la tienda se importan por separado + sin carga

store.dispatch('increment')

 Método 2: los objetos de la tienda se importan por separado + carga

store.dispatch('incrementAsync', {amount: 10})

Método 3: almacenar objeto global importación + carga

this.$store.dispatch('incrementAsync', {amount: 10})

Modo 4: mapActions identificador de función de promotor secundario + objeto + tienda expande los objetos de importación global

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

 

 

Supongo que te gusta

Origin blog.csdn.net/u014225733/article/details/95334034
Recomendado
Clasificación