初学Vuex我想吐血,但是坚持下来,我还是入门了。。。
先来说说我现在的感受吧:
一个字: “草”
两个字: “草蛋”
三个字: “草尼玛”
一句话: “心中一万只草泥马奔腾而过。。。”
言归正传,学了 vue 基本语法,又学了 vue-router 这些好像都不难,但是vuex官方文档读了好几遍,还是不懂啥意思~~,官方给的示例也是没头没脑的,看不太懂,造成很多童鞋跟我一样,一度想放弃学习vuex,因为没有vuex也能写出来简单的项目。但是,宝强哥说过:不抛弃,不放弃。不能因为难而抛弃vuex,不能因为学不会而放弃,这些都是暂时的…[此处省略2048字…],话说回来,看官方文档学不会,不看官方文档更不可能学的会,所以,向下看 —>
先照着中文官网撸一遍:
- 安装以前的这部分我就不说了。
“vuex是什么” —–> 状态管理模式(记着有这么个词就行了,我开始也不懂)
// 官方代码: new Vue({ // state data () { return { count: 0 } }, // view template: ` <div>{{ count }}</div> `, // actions methods: { increment () { this.count++ } } })
这些都是浮云,我表示乱糟糟的,刚接触我也看不懂,只知道下面这几个概念字面意思
- state,驱动应用的数据源;
- view,以声明方式将state映射到视图;
- actions,响应在view上的用户输入导致的状态变化。
- 配的图还是贴过来吧,虽然看不懂,但是要有印象
知道上面三个概念就可以继续往下撸了 —–> “开始”进入vuex到世界
- 先创建一个webpack项目:在命令行输入
vue init webpack vuexdemo
,安装依赖和vuex 在main.js中引入 vuex
import Vuex from 'vuex'; Vue.use(Vuex);
来写个最简单的vuex状态管理
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment: state => state.count++, decrement: state => state.count-- } }) // 在下面调用并改变状态试试 store.commit('increment') console.log(store.state.count) // 打印结果为 1 (注意放在vue实例对象前面)
- 这样虽然完成了最简单的状态管理,但是不实用哇~~,这个也算不得vuex的状态管理呢
- 先创建一个webpack项目:在命令行输入
一步步来,首先来看看 “单一状态树” — state
- 还是上面那个例子(我不会跟官网那样跳来跳去,我就用一个例子让你一点点证明白vuex是什么),现在这样写:
// main.js const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment: state => state.count++, decrement: state => state.count-- } }) new Vue({ el: '#app', router, store, // 将 store 在vue实例中申明并全局化,这样在其他组件中可以用 this.$store 调用 render: (h) => h(App) }) // 组件 vuex1.vue (新建组件是要配置对应的路由的,否则是看不到组件效果的,这个这里不再赘述) <template> <div id="apd"> <p>vuex1 -- {{ count }}</p> <p> <button @click="increment">+</button> <button @click="decrement">-</button> </p> </div> </template> <script> console.log(this.$state); export default({ computed: { count() { return this.$store.state.count } }, methods: { increment() { this.$store.commit('increment') console.log(this.$store.state.count); }, decrement() { this.$store.commit('decrement') } } }) </script>
- 这里我只说说我是怎么思考的
- 前面不是将store在vue实例中实例化了么,那么先在组件的script中打印下this.$store看看能不能调出来,并在控制台查看store的数据结构
- 在computed中获取state里保存的count,并返回给这个组件中的count(这里只是用同名的count来接收,你可以试试用不同的名字接收count)
- 至于这里的commit,仔细看store的数据结构的童鞋,可能会注意到里面有commit:function(){}的定义,这东西是胎带动方法,就这么用,记住就好。
- 一切准备好了就去页面试试吧。
- 到这里,我想你对state是否有点理解了,他就是保存可在其他组件中使用的变量的
- 上面提到了mutation(释义:变化),这玩意儿开始就有,在这里我想给你解释下,state只能保存变量,自己没能力对变量操作,执行操作的是mutation,上面的加和减都是定义在mutations中的。事实上,vuex就是用mutation来动态操作state的。
- mutation构成: 字符事件名称 + 回调函数
- matation使用: store.commit(‘事件名’)
- matation只能使用同步函数回调,异步回调需要有actions
到此我想你已经对这个vuex有点基础的了解了吧,我们在按照这个顺序展开联想,vuex是可以在兄弟组件中传递数据的,这个怎么做到的,把我们的示例改一下:
// vuex2.vue <template> <div> {{ num }} -- <router-link to="/vuex1">切换到视图1</router-link> </div> </template> <script> export default{ computed:{ num(){ return this.$store.state.count } } } </script>
运行一下,切换到vuex1的视图,随意加减,然后再切回来,可以看到我们vuex2视图中始终显示的是vuex1视图最终保存的结果
最后一部,我们来对vuex的写法美化一下,main.js中方太多东西乱七八糟的总不好(原谅我的强迫症)
- 新建vuex文件夹,内建 store.js 、state.js 和 mutations.js 文件
- 我们先把store放到store.js文件中去
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { count: 0 } const mutations = { increment: state => state.count++, decrement: state => state.count-- } export default new Vuex.Store({ state, mutations })
*注意此处*export default 是暴露模块的语法,大括号内是es6中json的简写,意为:state:state,mutations:mutations
这样在main.js中只需要引入store.js(模块用import … from … 引入) 并在vue实例中申明即可,此处不需要再重复引入vuex了。写程序要能举一反三,我们简化了main.js, store.js是否也可以简化呢?,是的:
// state.js const state = { count: 0 } export default{ state } // mutations.js const mutations = { increment: state => state.count++, decrement: state => state.count-- } export default{ mutations } // store.js import Vue from 'vue' import Vuex from 'vuex' import state from './state' import mutations from './mutation' Vue.use(Vuex) export default new Vuex.Store({ state:state.state, mutations:mutations.mutations })
注意此处我们引入的是state这个模块对象,而不是对象中的用来存储变量的state,所以需要使用state.state来正确引入状态。