Heim  >  Artikel  >  Web-Frontend  >  Vuex 2.0 über Vue.js 2.0 Die Wissensdatenbank, die Sie aktualisieren müssen

Vuex 2.0 über Vue.js 2.0 Die Wissensdatenbank, die Sie aktualisieren müssen

高洛峰
高洛峰Original
2016-12-03 13:22:241359Durchsuche

Anwendungsstruktur

Tatsächlich unterliegt Vuex keinen Einschränkungen hinsichtlich der Organisation Ihrer Codestruktur. Im Gegenteil, es erzwingt eine Reihe übergeordneter Prinzipien:

1. Ebene Der Status wird im Store zentralisiert.

2. Die einzige Möglichkeit, den Status zu ändern, besteht darin, Mutationen einzureichen, was eine synchrone Transaktion ist.

3. Asynchrone Logik sollte in Aktion gekapselt sein.

Solange Sie diese Regeln befolgen, liegt es an Ihnen, wie Sie Ihr Projekt strukturieren. Wenn Ihre Store-Datei sehr groß ist, teilen Sie sie einfach in Aktions-, Mutations- und Getter-Dateien auf.

Für etwas komplexere Anwendungen müssen wir möglicherweise Module verwenden. Das Folgende ist eine einfache Projektstruktur:

├── index.html
├── main.js
├── api
│ └── ... # API hier starten Anfrage
├── Komponenten
│ ├── App.vue
│ └── ...
└── Store
├── index.js
├── Actions.js ├── Actions.js ├── Mutationen.js # Wurzelmutationen
└── Module
├── Cart.js # Cart-Modul └── Produkte .js # Produktmodul


Weitere Informationen finden Sie unter Beispiel für einen Einkaufswagen.

Module

Aufgrund der Verwendung eines einzelnen Statusbaums ist der gesamte Status der Anwendung in einem großen Objekt enthalten. Da jedoch der Umfang unserer Anwendung weiter zunahm, wurde dieser Store sehr aufgebläht.

Um dieses Problem zu lösen, ermöglicht uns Vuex, den Store in Module zu unterteilen. Jedes Modul enthält seinen eigenen Status, seine eigene Mutation, seine eigene Aktion und seinen eigenen Getter, sogar verschachtelte Module. So ist es organisiert:

const moduleA = {
 state: { ... },
 mutations: { ... },
 actions: { ... },
 getters: { ... }
}
 
const moduleB = {
 state: { ... },
 mutations: { ... },
 actions: { ... }
}
 
const store = new Vuex.Store({
 modules: {
 a: moduleA,
 b: moduleB
 }
})
 
store.state.a // -> moduleA's state
store.state.b // -> moduleB's state

Modul lokaler Status

Der erste Parameter, den die Mutations- und Getter-Methoden des Moduls empfangen, ist der lokale Status des Moduls.

const moduleA = {
 state: { count: 0 },
 mutations: {
 increment: (state) {
  // state 是模块本地的状态。
  state.count++
 }
 },
 
 getters: {
 doubleCount (state) {
  return state.count * 2
 }
 }
}

In ähnlicher Weise macht context.state in den Aktionen des Moduls den lokalen Status und context.rootState den Root-Status verfügbar.

const moduleA = {
 // ...
 actions: {
 incrementIfOdd ({ state, commit }) {
  if (state.count % 2 === 1) {
  commit('increment')
  }
 }
 }
}

In den Gettern des Moduls wird der Root-Status auch als dritter Parameter offengelegt.

const moduleA = {
 // ...
 getters: {
 sumWithRootCount (state, getters, rootState) {
  return state.count + rootState.count
 }
 }
}

Namespace

Bitte beachten Sie, dass die Aktionen, Mutationen und Getter innerhalb des Moduls weiterhin im globalen Namespace registriert sind – diesem This ermöglicht es mehreren Modulen, auf denselben Mutations-/Aktionstyp zu reagieren. Sie können dem Modulnamen ein Präfix oder Suffix hinzufügen, um den Namespace festzulegen und Namenskonflikte zu vermeiden. Wenn Ihr Vuex-Modul wiederverwendbar ist und die Ausführungsumgebung unbekannt ist, sollten Sie dies tun. Entfernung, wir möchten ein Todos-Modul erstellen:

// types.js
 
// 定义 getter、 action 和 mutation 的常量名称
// 并且在模块名称上加上 `todos` 前缀
export const DONE_COUNT = 'todos/DONE_COUNT'
export const FETCH_ALL = 'todos/FETCH_ALL'
export const TOGGLE_DONE = 'todos/TOGGLE_DONE'
// modules/todos.js
import * as types from '../types'
 
// 用带前缀的名称来定义 getters, actions and mutations
const todosModule = {
 state: { todos: [] },
 
 getters: {
 [types.DONE_COUNT] (state) {
  // ...
 }
 },
 
 actions: {
 [types.FETCH_ALL] (context, payload) {
  // ...
 }
 },
 
 mutations: {
 [types.TOGGLE_DONE] (state, payload) {
  // ...
 }
 }
}

Dynamisches Modul registrieren

Sie können zum Erstellen die Methode store.registerModule verwenden Im Store registrieren. Dann ein Modul registrieren:

store.registerModule('myModule', {
 // ...
})

Der Wert „store.state.myModule“ des Moduls wird als Status des Moduls angezeigt.

Andere Vue-Plug-Ins können ein Modul an den Anwendungsspeicher anhängen und dann die Statusverwaltungsfunktion von Vuex durch dynamische Registrierung nutzen. Beispielsweise integriert die Bibliothek vuex-router-sync vue-router und vuex, indem sie den Routing-Status der Anwendung in einem dynamisch registrierten Modul verwaltet.

Sie können auch store.unregisterModule(moduleName) verwenden, um dynamisch registrierte Module zu entfernen. Sie können diese Methode jedoch nicht zum Entfernen statischer Module verwenden (d. h. Module, die beim Erstellen des Speichers deklariert wurden).

Plugins

Der Store von Vuex erhält die Plugins-Option, die Hooks für jede Mutation verfügbar macht. Ein Vuex-Plugin ist eine einfache Methode, die sotre als einzigen Parameter akzeptiert:

const myPlugin = store => {
 // 当 store 在被初始化完成时被调用
 store.subscribe((mutation, state) => {
 // mutation 之后被调用
 // mutation 的格式为 {type, payload}。
 })
}

und es dann wie folgt verwendet:

const store = new Vuex.Store({
 // ...
 plugins: [myPlugin]
})

Mutationen innerhalb von Plugins übermitteln

Plugins können den Status nicht direkt ändern – genau wie Ihre Komponenten können sie nur durch Mutationen ausgelöst werden.

Durch die Übermittlung von Mutationen kann das Plug-in verwendet werden, um die Datenquelle mit dem Store zu synchronisieren. Zum Beispiel, um die Websocket-Datenquelle mit dem Store zu synchronisieren (dies ist nur ein Beispiel zur Veranschaulichung der Verwendung, in der Praxis werden der Methode createPlugin weitere Optionen angehängt, um komplexe Aufgaben abzuschließen).

export default function createWebSocketPlugin (socket) {
 return store => {
 socket.on('data', data => {
  store.commit('receiveData', data)
 })
 store.subscribe(mutation => {
  if (mutation.type === 'UPDATE_DATA') {
  socket.emit('update', mutation.payload)
  }
 })
 }
}

const plugin = createWebSocketPlugin(socket)
 
const store = new Vuex.Store({
 state,
 mutations,
 plugins: [plugin]
})

Status-Snapshot generieren

Manchmal möchte das Plug-in den Status „ Snapshot“ und Statusänderungen vor und nach der Änderung. Um diese Funktionen zu implementieren, ist eine tiefe Kopie des Statusobjekts erforderlich:

const myPluginWithSnapshot = store => {
 let prevState = _.cloneDeep(store.state)
 store.subscribe((mutation, state) => {
 let nextState = _.cloneDeep(state)
 
 // 对比 prevState 和 nextState...
 
 // 保存状态,用于下一次 mutation
 prevState = nextState
 })
}

** Plug-Ins, die Status-Snapshots generieren, können nur sein Wird während der Entwicklungsphase mit Webpack oder Browserify verwendet, lassen Sie das Build-Tool für uns erledigen:

const store = new Vuex.Store({
 // ...
 plugins: process.env.NODE_ENV !== 'production'
 ? [myPluginWithSnapshot]
 : []
})

Das Plug-in ist standardmäßig aktiviert . Für die Auslieferung an die Produktion müssen Sie DefinePlugin von Webpack oder Envify von Browserify verwenden, um „process.env.NODE_ENV !== 'produktion'“ in „false“ zu konvertieren.

Integriertes Logger-Plug-in

如果你正在使用 vue-devtools,你可能不需要。

Vuex 带来一个日志插件用于一般的调试:

import createLogger from 'vuex/dist/logger'
 
const store = new Vuex.Store({
 plugins: [createLogger()]
})

   

createLogger 方法有几个配置项:

const logger = createLogger({
 collapsed: false, // 自动展开记录 mutation
 transformer (state) {
 // 在记录之前前进行转换
 // 例如,只返回指定的子树
 return state.subTree
 },
 mutationTransformer (mutation) {
 // mutation 格式 { type, payload }
 // 我们可以按照想要的方式进行格式化
 return mutation.type
 }
})

   

日志插件还可以直接通过 3f1c4e4b6b16bbbd69b2ee476dc4f83a 标签, 然后它会提供全局方法 createVuexLogger 。

要注意,logger 插件会生成状态快照,所以仅在开发环境使用。

严格模式

要启用严格模式,只需在创建 Vuex store 的时候简单地传入 strict: true。

const store = new Vuex.Store({
 // ...
 strict: true
})

   

在严格模式下,只要 Vuex 状态在 mutation 方法外被修改就会抛出错误。这确保了所有状态修改都会明确的被调试工具跟踪。

开发阶段 vs. 发布阶段

不要在发布阶段开启严格模式! 严格模式会对状态树进行深度监测来检测不合适的修改 —— 确保在发布阶段关闭它避免性能损耗。
跟处理插件的情况类似,我们可以让构建工具来处理:

const store = new Vuex.Store({
 // ...
 strict: process.env.NODE_ENV !== 'production'
})

   


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn