Vuex 简介和使用
Vuex 是 Vue 的官方状态管理库。 一个方便的比喻是 Vuex 之于 Vue 就像 Redux 于 React 。 如果您已经了解 Redux,那么 Vuex 似乎很熟悉,只是术语略有不同。 在本文中,您将从独立的 Node.js 脚本中学习 Vuex 的基础知识,无需浏览器。
首先,要开始使用,您应该 vue 、 vuex 和 vue-server-renderer 从 npm 以下是导入这些库的方法:
const { renderToString } = require('vue-server-renderer').createRenderer();
const Vuex = require('vuex');
Vue.use(Vuex);
接下来,让我们定义一个显示单个数字的模板 count
存储在 Vuex 中。 该脚本有 4 个步骤:
- 创建一个 Vuex 商店。 要创建 Vuex 存储,您需要定义 state 、 mutation 和 actions 。
- 创建一个连接到使用 Vuex 商店的 Vue 应用程序。
- 使用 vue-server-renderer 渲染应用程序。
- 调度一个动作并使用 vue-server-renderer 重新渲染应用程序。
/**
* Step 1: Create a Vuex store.
* Vuex stores have 3 primary concepts:
* - `state` is a POJO that contains all the application's data
* - `mutations` are synchronous functions that change the `state`
* - `actions` are potentially async functions that may trigger 1 or
* more mutations.
*/
const state = { count: 0 };
const mutations = {
increment: (state) => { ++state.count; },
decrement: (state) => { --state.count; }
};
const actions = {
increment: ({ commit }) => commit('increment'),
decrement: ({ commit }) => commit('decrement')
};
const store = new Vuex.Store({ state, mutations, actions });
// Step 2: Create a Vue app that's wired up to use the Vuex store
const app = new Vue({
store,
// In Vue templates, you reference the Vuex state with `$store.state`
template: '<div>{{$store.state.count}}</div>'
});
// Step 3: Render the app using vue-server-renderer
await renderToString(app); // <div data-server-rendered="true">0</div>
// Step 4: Dispatch an action and re-render the app
store.dispatch('increment');
store.state.count; // 1
await renderToString(app); // <div data-server-rendered="true">1</div>
assert.equal(await renderToString(app),
'<div data-server-rendered="true">1</div>');
// acquit:ignore:end
如果你来自 Redux,Vuex 中的 state 和 action 等同于 Redux 中的 states 和 actions。 您可以将 突变 视为等同于减速器。
异步操作
动作和突变之间的一个关键区别是动作可以是异步的,而 突变必须是同步 的。 在单独的同步突变中进行状态更改可以实现更好的调试和更好的开发工具。 但是,动作可以是异步的。 例如,您的 increment
动作可以是异步的,如下所示。
// Create the store
const state = { count: 0 };
const mutations = {
increment: (state) => { ++state.count; },
decrement: (state) => { --state.count; }
};
const actions = {
increment: async ({ commit }) => {
await new Promise(resolve => setTimeout(resolve, 100));
commit('increment');
}
};
const store = new Vuex.Store({ state, mutations, actions });
// Create the app
const app = new Vue({
store,
template: '<div>{{$store.state.count}}</div>'
});
// Dispatch an action. Note that the `dispatch()` function returns a
// promise because the `increment` action is an async function.
await store.dispatch('increment');
await renderToString(app); // <div data-server-rendered="true">1</div>
assert.equal(await renderToString(app),
'<div data-server-rendered="true">1</div>');
// acquit:ignore:end
一个重要的警告是 Vuex 不会为您处理异步操作中的错误。 如果异步操作抛出错误, 未处理的 Promise 拒绝 除非您使用显式处理错误,否则您 .catch()
或 异步/等待 。
const actions = {
increment: async () => {
await new Promise(resolve => setTimeout(resolve, 100));
throw new Error('Oops');
}
};
const store = new Vuex.Store({ state, mutations, actions });
//
const err = await store.dispatch('increment').catch(err => err);
err.message; // "Oops"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论