开一个Vuex的坑.
先来谈谈个人看法,之前很早的时候就用过Vuex做组件间通信,对于单页面应用来说,也就是不同的router子组件的一些数据通信,当然我也尝试过event bus的解决方案,这里不进行横向对比了,如果想做组件间的复杂通信,直接选择Vuex即可(个人建议).如果有人想学习Vuex,个人推荐是直接去官网的API,当然官网的API会让你先了解一下ES6的语法,当时也是看到那句话就比较反感那个文档,不过还是屁颠屁颠的把ES6的语法过了一遍,有兴趣的可以去我的分类里简单学习一下.关于这个系列肯定会有后续的展开,主要包括一些Vuex的核心概念(State,Getter,Mutation,Action,Module),但个人推荐不用深入了解Vuex,如果需求不是那么复杂的话,基本上你稍微了解一下今天的例子,知道如何用state存储状态,如何用mutation触发状态变更就可以完成大部分项目需求.
Vuex的设计初衷就是为了解决Vue中单项数据流的问题,什么是单项数据流,简单来说就是
父组件可以传值给子组件,你可以用props,还相对简单.
子组件可以传值给父组件,你可以用$emit,这个算相对难一丢丢.
这并不是单项数据流的官方解释,是我自己随便总结的,来看这种数据交互方式会产生什么问题
1.祖祖祖父组件要传值给曾曾曾孙,这就有点尴尬了,一个简单的数据要从祖宗十八代传到你这一代,得经历子组件的一个个祖辈,而且中间还不能断,这又不是传家宝,传那么多次又不会升值,所以这个问题是Vue的设计中未考虑完善的.
2.兄弟节点间的通信问题,可能需要父组件的支持,然而凭什么你和你兄弟的事情非得让你爸知道呢?这个问题在Vue的设计中也不好解决.
为了解决上述问题,Vuex提出了一个'公共仓库'(store)的概念,“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state).你的所有组件都可以访问这个容器中的公共状态,这有点像你定义了一个全局变量,因此你可以在当前代码块的所有位置访问到这个变量.当然store容器和全局变量还是有很大的区别的.
1.Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2.你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
前面两点是官网的说明,谈谈个人理解,首先第一点,由于使用Vuex需要将store实例挂载到Vue实例中,因此Vue实例可以对Vuex的state数据加监听,这跟Vue实例data的数据双向绑定是类似的.而全局变量由于没有被"数据劫持",因此即使全局变量的值发生改变,也无法在Vue实例中监听到他的变化.第二点更好理解一些,就是Vuex中的状态值,不能通过赋值的方式(state.xxx = yyy)改变,需要通过mutation触发变更,这样做方便状态管理,而一般的全局变量是支持直接赋值的.
下面来实现一个简单的例子,用vuex做一些事情
首先,项目是基于vue-cli脚手架搭的,你可以用npm的方式导入vuex,并通过Vue.use(Vuex)的显示声明方式来使用Vuex
在项目中,我通过store文件夹来管理vuex的一些模块,今天要用到的模块只有state模块和mutation模块,这也是Vuex状态管理的最基本的两个模块.
要使用Vuex,你还需要在main.js的Vue根实例中挂载一下store实例,如下所示
//main.js import Vue from 'vue' import App from './App' import router from './router' import store from './store/index' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, // 挂在store到所有子组件中 components: { App }, template: '<App/>' })
准备工作都完成了.我们在store里面存一个count用于后续操作.
//state.js let state = { count: 1 } export default state
存入后,我们就可以在任意子组件中访问这个值了,在vue的子组件中我们可以通过this.$store访问store对象,注意这里我用了computed接收了store的值,这有利于在值发生改变的时候及时的响应到当前子组件.
<template> <div id="example"> {{count}} </div> </template> <script> export default { computed: { count () { return this.$store.state.count } }, methods: { } } </script> <style lang="less" scoped> </style>
完成了值的接收,下面来对这个值进行一些操作,注意,如果要操作state中的值,不能直接通过this.$store.state.xxx = yyy的方式进行暴力修改,必须要提交给mutation处理,这在之前也有提过,所以我们要在mutation.js里写入对state的操作
//mutation.js // 第一个参数默认接收state对象 let increment = (state) => { state.count++ } let decrement = (state) => { state.count-- } export {increment, decrement}
然后我们就可以通过this.$store.commit('function')修改这个值了.
<template> <div id="example"> <button @click="decrement">-</button> {{count}} <button @click="increment">+</button> </div> </template> <script> export default { computed: { count () { return this.$store.state.count } }, methods: { increment () { this.$store.commit('increment') }, decrement () { this.$store.commit('decrement') } } } </script> <style lang="less" scoped> </style>
这里没有涉及到通信的问题,但事实上Vuex已经帮你做了状态管理了,如果别的子组件用到了上述的count,在count改变的时候,其他的子组件也会相应到count的改变,有兴趣的自己动手试一试,这里不婆婆妈妈啰啰嗦嗦了.
- 2025年3月 (1)
- 2024年6月 (2)
- 2024年5月 (2)
- 2024年4月 (4)
- 2024年3月 (30)
- 2024年1月 (4)
- 2023年12月 (2)
- 2023年11月 (4)
- 2023年10月 (4)
- 2023年9月 (6)
- 2023年3月 (2)
- 2023年2月 (1)
- 2023年1月 (1)
- 2022年12月 (1)
- 2022年9月 (21)
- 2022年8月 (10)
- 2022年7月 (3)
- 2022年4月 (1)
- 2022年3月 (13)
- 2021年8月 (1)
- 2021年3月 (1)
- 2020年12月 (42)
- 2020年11月 (7)
- 2020年10月 (5)
- 2020年8月 (1)
- 2020年6月 (1)
- 2020年3月 (2)
- 2019年12月 (8)
- 2019年11月 (3)
- 2019年9月 (1)
- 2019年4月 (1)
- 2019年3月 (6)
- 2019年2月 (1)
- 2018年7月 (7)
- 1.asp.net mvc内微信pc端、H5、JsApi支付方式总结(5751)
- 2.Windows 10休眠文件更改存储位置(3401)
- 3.各大搜索网站网站收录提交入口地址(3319)
- 4.ECharts仪表盘实例及参数使用详解(3218)
- 5.windows 10安装myeclipse 10破解补丁cracker.jar、run.bat闪退解决办法(3155)
- 6.HTML5 WebSocket与C#建立Socket连接实现代码(3015)
- 7.华为鸿蒙系统清除微信浏览器缓存方法(2926)
- 8.CERT_HAS_EXPIRED错误如何解决(2494)
- 9.Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2343)
- 10.HBuilder编辑器格式化代码(2241)