关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
应用结构
实际上,Vuex 在怎么组织你的代码结构上面没有任何限制,相反,它强制规定了一系列高级的原则:
1、应用级的状态集中放在 store 中。
2、改变状态的唯一方式是提交mutations,这是个同步的事务。
3、异步逻辑应该封装在action 中。
只要你遵循这些规则,怎么构建你的项目的结构就取决于你了。如果你的 store 文件非常大,仅仅拆分成 action、mutation 和 getter 多个文件即可。
对于稍微复杂点的应用,我们可能都需要用到模块。下面是一个简单的项目架构:
├── index.html
├── main.js
├── api
│ └── ... # 这里发起 API 请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 组合 modules 、export store
├── actions.js # 根 action
├── mutations.js # 根 mutations
└── modules
├── cart.js # cart 模块
└── products.js # products 模块
关于更多,查看 购物车实例。
Modules
由于使用了单一状态树,应用的所有状态都包含在一个大对象内。但是,随着我们应用规模的不断增长,这个Store变得非常臃肿。
为了解决这个问题,Vuex 允许我们把 store 分 module(模块)。每一个模块包含各自的状态、mutation、action 和 getter,甚至是嵌套模块, 如下就是它的组织方式:
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
模块本地状态
模块的 mutations 和 getters方法第一个接收参数是模块的本地状态。
const moduleA = { state: { count: 0 }, mutations: { increment: (state) { // state 是模块本地的状态。 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } } }
相似地,在模块的 actions 中,context.state 暴露的是本地状态, context.rootState暴露的才是根状态。
const moduleA = { // ... actions: { incrementIfOdd ({ state, commit }) { if (state.count % 2 === 1) { commit('increment') } } } }
在模块的 getters 内,根状态也会作为第三个参数暴露。
const moduleA = { // ... getters: { sumWithRootCount (state, getters, rootState) { return state.count + rootState.count } } }
命名空间
要注意,模块内的 actions、mutations 以及 getters 依然注册在全局命名空间内 —— 这就会让多个模块响应同一种 mutation/action 类型。你可以在模块的名称中加入前缀或者后缀来设定命名空间,从而避免命名冲突。如果你的 Vuex 模块是一个可复用的,执行环境也未知的,那你就应该这么干了。距离,我们想要创建一个 todos 模块:
// 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) { // ... } } }
注册动态模块
你可以用 store.registerModule 方法在 store 创建之后注册一个模块:
store.registerModule('myModule', { // ... })
模块的 store.state.myModule 暴露为模块的状态。
其他的 Vue 插件可以为应用的 store 附加一个模块,然后通过动态注册就可以使用 Vuex 的状态管理功能了。例如,vuex-router-sync 库,通过在一个动态注册的模块中管理应用的路由状态,从而将 vue-router 和 vuex 集成。
你也能用 store.unregisterModule(moduleName) 移除动态注册过的模块。但是你不能用这个方法移除静态的模块(也就是在 store 创建的时候声明的模块)。
Plugins
Vuex 的 store 接收 plugins 选项,这个选项暴露出每个 mutation 的钩子。一个 Vuex 的插件就是一个简单的方法,接收 sotre 作为唯一参数:
const myPlugin = store => { // 当 store 在被初始化完成时被调用 store.subscribe((mutation, state) => { // mutation 之后被调用 // mutation 的格式为 {type, payload}。 }) }
然后像这样使用:
const store = new Vuex.Store({ // ... plugins: [myPlugin] })
在插件内提交 Mutations
插件不能直接修改状态 - 这就像你的组件,它们只能被 mutations 来触发改变。
通过提交 mutations,插件可以用来同步数据源到 store。例如, 为了同步 websocket 数据源到 store (这只是为说明用法的例子,在实际中,createPlugin 方法会附加更多的可选项,来完成复杂的任务)。
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] })
生成状态快照
有时候插件想获取状态 “快照” 和状态的改变前后的变化。为了实现这些功能,需要对状态对象进行深拷贝:
const myPluginWithSnapshot = store => { let prevState = _.cloneDeep(store.state) store.subscribe((mutation, state) => { let nextState = _.cloneDeep(state) // 对比 prevState 和 nextState... // 保存状态,用于下一次 mutation prevState = nextState }) }
** 生成状态快照的插件只能在开发阶段使用,使用 Webpack 或 Browserify,让构建工具帮我们处理:
const store = new Vuex.Store({ // ... plugins: process.env.NODE_ENV !== 'production' ? [myPluginWithSnapshot] : [] })
插件默认会被起用。为了发布产品,你需要用 Webpack 的 DefinePlugin 或者 Browserify 的 envify 来转换 process.env.NODE_ENV !== 'production' 的值为 false。
内置 Logger 插件
如果你正在使用 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 } })
日志插件还可以直接通过

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Comment recadrer des images dans le projet vue ? L'article suivant vous présentera comment utiliser vue-cropper pour recadrer des images. J'espère qu'il vous sera utile !

Avant-propos : Dans le développement de vue3, réactif fournit une méthode pour implémenter des données réactives. Il s'agit d'une API fréquemment utilisée dans le développement quotidien. Dans cet article, l’auteur explorera son mécanisme de fonctionnement interne.

vscode lui-même prend en charge les composants de fichiers Vue pour accéder aux définitions, mais la prise en charge est très faible. Sous la configuration de vue-cli, nous pouvons écrire de nombreuses utilisations flexibles, ce qui peut améliorer notre efficacité de production. Mais ce sont ces méthodes d'écriture flexibles qui empêchent les fonctions fournies par vscode lui-même de prendre en charge le passage aux définitions de fichiers. Afin d'être compatible avec ces méthodes d'écriture flexibles et d'améliorer l'efficacité du travail, j'ai écrit un plug-in vscode qui prend en charge les fichiers Vue pour accéder aux définitions.

Ace est un éditeur de code intégrable écrit en JavaScript. Il correspond aux fonctionnalités et aux performances des éditeurs natifs comme Sublime, Vim et TextMate. Il peut être facilement intégré à n’importe quelle page Web et application JavaScript. Ace est maintenu en tant qu'éditeur principal de l'IDE Cloud9 et est le successeur du projet Mozilla Skywriter (Bespin).

Vue.js est devenu aujourd'hui un framework très populaire dans le développement front-end. À mesure que Vue.js continue d'évoluer, les tests unitaires deviennent de plus en plus importants. Aujourd'hui, nous allons explorer comment écrire des tests unitaires dans Vue.js 3 et fournir quelques bonnes pratiques ainsi que des problèmes et solutions courants.

La différence entre la modularisation et la modularisation : la modularisation est divisée du point de vue de la logique du code ; elle facilite le développement en couches de code et garantit la cohérence des fonctions de chaque module fonctionnel. La composantisation est planifiée du point de vue de l'interface utilisateur ; la composantisation du frontal facilite la réutilisation des composants de l'interface utilisateur.

Comment gérer les exceptions dans les composants dynamiques Vue3 ? L'article suivant parlera des méthodes de gestion des exceptions des composants dynamiques Vue3. J'espère qu'il sera utile à tout le monde !

Lorsque nous utilisons le framework Vue pour développer des projets front-end, nous déploierons plusieurs environnements lors du déploiement. Souvent, les noms de domaine d'interface appelés par les environnements de développement, de test et en ligne sont différents. Comment peut-on faire la distinction ? Cela utilise des variables et des modèles d'environnement.
