import{createStore}from"vuex";//InstantiateourVuexstoreconststore=createStore({//"State"组件的应用程序数据state(){return{myValue:0};}});//组件从其计算的属性访问stateconstMyComponent={template:"<div>{{myValue}}</div>",computed:{myValue(){returnstore.state.myValue;}}};
原则2:数据是只读的组件可以从store中自由读取数据但是不能更改 store 中的数据,至少不能直接更改取而代之的是,它们必须告知 store 要更改数据的意图,store由负责通过一组定义的功能(称为mutation)进行更改为什么采用这种方法?如果我们集中数据更改逻辑,那么在状态不一致的情况下,我们只需要在同一地方排查就行了,不用到具体的每个文件中我们将某些随机组件(可能在第三方模块中)以意外方式更改数据的可能性降至最低conststore=createStore({state(){return{myValue:0};},mutations:{increment(state,value){state.myValue+=value;}}});//需要更新值吗?//错误的,不要直接更改store值store.myValue+=10;//正确的,调用正确的 mutationsstore.commit('increment',10);
原则3:mutation 是同步的如果应用程序在其体系结构中实现了上述两个原则,那么调试数据不一致就容易得多可以记录提交并观察状态如何变化(在使用Vue Devtools 时确实可以这样做)但如果我们的mutation被异步调用,这种能力就会被削弱我们知道提交的顺序,但我们不知道组件提交它们的顺序同步mutation可确保状态不取决于不可预测事件的顺序和时间太酷了,那么 Vuex 到底是什么?有了所有这些背景知识,我们终于可以解决这个问题-Vuex 是一个库,可帮助我们在Vue应用程序中实现Flux架构通过执行上述原则,即使在多个组件之间共享数据时,Vuex 仍可将我们的应用程序数据保持在透明且可预测的状态现在,我们已经对Vuex有了一个高级的了解,我们看看如何在实际项目创建基于Vuex的应用程序做一个使用 Vuex to-do-list为了演示Vuex的用法,我们设置一个简单的待办应用程序大家可以在此处访问代码的有效示例示例地址:https://codesandbox.io/s/happy-williams-rdni7如果大家自己的电脑尝试一波,那么可以使用下面的命令:vuecreatevuex-example
安装 Vuexcdvuex-examplenpmi-Svuex@4npmrunserve
创建一个 Vuex store现在,创建 Vuex store,在项目中创建 src/store/index.js:mkdirsrc/storetouchsrc/store/index.js
打开文件并导入createStore方法此方法用于定义store及其特性现在,我们导出该store ,以便在Vue应用中能访问它//src/store/index.jsimport{createStore}from"vuex";exportdefaultcreateStore({});
将 store 添加到 Vue 实例为了可以从任何组件中访问 Vuex store,我们需要在主文件中导入 store 模块,并将store作为插件安装在主Vue实例上//src/main.jsimport{createApp}from"vue";importAppfrom"@/App";importstorefrom"@/store";constapp=createApp(App);app.use(store);app.mount("#app");
创建一个简单的应用程序如上所述,Vuex 的重点是通常在大型应用程序中创建可扩展的全局状态但是,我们可以在一个简单的待办应用程序中演示其功能完成后效果如下所示:现在,删除 HelloWorld 文件:rmsrc/components/HelloWorld.vue
TodoNew.vue现在,添加一个新组件 TodoNew,它负责创建新的待办事项touchsrc/components/TodoNew.vue
打开 TodoNew.vue 并输入以下内容://src/components/TodoNew.vue<template><form@submit.prevent="addTodo"><inputtype="text"placeholder="Enteranewtask"v-model="task"/></form></template>
现在转到组件定义,有两个局部状态属性-task和给新待办事项提供唯一标识符的id//src/components/TodoNew.vue<template>...</template><script>exportdefault{data(){return{task:"",id:0};},methods:{addTodo:function(){//}}};</script>
定义 store 状态过会,我们会创建一个显示待办事项的组件由于它和TodoNew组件都需要访问相同的数据,因此这是我们在 Vuex 存储中保存的全局state 的理想选择现在,回到state并定义属性状态这里使用 Vux4 提供的 createStore 函数,该函数返回一个对象该对象具有一个属性 todos,它是一个空数组//src/store/index.jsimport{createStore}from"vuex";exportdefaultcreateStore({state(){return{todos:[]}}});
定义 mutation从原则2可以知道,Vuex state 不能直接更改,需要定义mutator函数现在,我们向store添加一个mutation属性,并添加一个函数属性addTodo所有mutator方法第一个参数第二个可选参数是 store,第二个是传递的数据//src/store/index.jsimport{createStore}from"vuex";exportdefaultcreateStore({state(){return{todos:[]}},mutations:{addTodo(state,item){state.todos.unshift(item);}}});
使用 commit 调用 mutation现在,可以在TodoNew组件中使用它,在 TodoNew组件定义一个addTodo方法要访问store ,我们可以使用全局属性this.$store使用commit方法创建一个新的mutation需要传递了两个参数-首先是mutation的名称,其次是我们要传递的对象,是一个新的待办事项(由id和task值组成)//src/components/TodoNew.vuemethods:{addTodo:function(){const{id,task}=this;this.$store.commit("addTodo",{id,task});this.id++;this.task="";}}
回顾到目前为止:用户将待办事项通过输入框输入,并绑定到 task 变量提交表单后,将调用addTodo方法创建一个待办事项对象并将其“提交”到store中//src/components/TodoNew.vue<template><form@submit.prevent="addTodo"><inputtype="text"placeholder="Enteranewtask"v-model="task"/></form></template><script>exportdefault{data(){return{task:"",id:0};},methods:{addTodo:function(){const{id,task}=this;this.$store.commit("addTodo",{id,task});this.id++;this.task="";}}};</script>
读取 store 数据现在,我们已经创建了用于添加待办事项的功能接下来,就是把它们显示出来创建一个新组件TodoList.vue 文件touchsrc/components/TodoList.vue
内容如下://src/components/TodoList.vue<template><ul><liv-for="todointodos":key="todo.id">{{todo.description}}</li></ul></template>
todos是一个计算属性,我们在其中返回Vuex store 的内容//src/components/TodoList.vue<script>exportdefault{computed:{todos(){//}}};</script>
定义 getters与直接访问store 内容不同,getter是类似于存储的计算属性的函数在将数据返回到应用程序之前,这些工具非常适合过滤或转换数据例如,下面有getTodos,它返回未过滤的状态在许多情况下,可以使用filter或map来转换此内容todoCount返回todo数组的长度通过确保组件愿意保留数据的本地副本,getter有助于实现原则1,即单一数据来源//src/store/index.jsexportdefaultcreateStore({...getters:{getTodos(state){returnstate.todos;},todoCount(state){returnstate.todos.length;}}})
返回TodoList组件,我们通过返回this.$store.getters.getTodos来完成功能//src/components/TodoList.vue<script>exportdefault{computed:{todos(){returnthis.$store.getters.getTodos;}}};</script>
App.vue要完成此应用程序,现在要做的就是导入并在App.vue中声明我们的组件//src/App.vue<template><div><h1>To-DoList</h1><div><TodoNew/><TodoList/></div></div></template><script>importTodoNewfrom"@/components/TodoNew.vue";importTodoListfrom"@/components/TodoList.vue";exportdefault{components:{TodoNew,TodoList}};</script>
你真的需要Vuex吗?显然,在大型应用程序中,拥有全局状态管理解决方案将有助于让我们的应用程序可预测和可维护但对于比较小的项目,有时候觉得使用 Vuex 太大材小用了,还这个还是大家跟着实际需求走比较合理Vuex的优点:易于管理全局状态强大的调试全局状态Vuex的缺点:额外的项目依赖繁琐的模板~ 完, 我是刷碗智,刷碗去咯,下期见作者:Anthony Gore 译者:前端小智 来源:vuejsdevelopers原文:https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
(图片来源网络,侵删)
0 评论