一、概述

官方文档:https://vuex.vuejs.org/zh/installation.html

1.1vuex有什么用

Vuex:实现data(){}内数据多个组件间共享一种解决方案(类似react的redux)

1.2什么情况下使用vuex

  1. 虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
  2. 如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

1.3Vuex状态管理

  1. view ->(dispatch) Action ->(Commit) Mutations ->(Mutate) State -> View
  2. 注意:Action不是必需品,如果有异步操作才可能用到Action,否则可以不使用

1.4Actions:

  1. Action 提交的是 mutation,而不是直接变更状态。
  2. Action 可以包含任意异步操作。

二、安装及使用

官方文档:https://vuex.vuejs.org/zh/installation.html

安装方法1,npm

  1. cnpm install vuex --save

  2. npm install vuex --save

安装方法2,cdn

  1. <script src="/path/to/vue.js"></script>
  2. <script src="/path/to/vuex.js"></script>

其它略过,见文档。

【使用】

在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)

当使用全局 script 标签引用 Vuex 时,不需要以上安装过程。

2.1 vuex定义共享数据和引用 state:{}

应用场景: 例如在购物车中,你在商品详情页进行加减库存操作,而到购物车详情中时,用之前学得的data(){}内数据用法,你是得不到商品详情里的商品数量这个数据的,此时就引入了state:{}做为所有页面的共享数据,加减商品都可使用此处的数据,从而实现数据的共享。

代码实例

(多余代码为父子组件互传值复习)

第1步,引入vuex并创建store实例 src/main.js

[1]引入vuex

[2]使用vuex

[3]创建一个store实例(主要)

[4]所有组件共用数据存放处

[5]注入store(重要)

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import Vuex from 'vuex' //[1]引入vuex
  4. Vue.use(Vuex)//[2]使用vuex
  5. //[3]创建一个store实例
  6. const store=new Vuex.Store({
  7. state:{//[4]所有组件共用数据存放处
  8. count:10
  9. }
  10. })
  11. new Vue({
  12. el: '#app',
  13. store,//[5]注入store
  14. render: h => h(App)
  15. })

第2步,引用1步所创建的共享数据count(src/components/home.vue)

【1】获取store里的共享数据方法1直接调用(this.$store.state.count)

  1. <template>
  2. <div>
  3. <Hello :title='msg' @msg='getmsg'/><br/>
  4. {{msg2}}<br/>
  5. <!-- 【1】获取store里的共享数据方法1 -->
  6. home:获取vuex的store共用数据:{{this.$store.state.count}}
  7. </div>
  8. </template>
  9. <script>
  10. import Hello from './hello.vue';
  11. export default{
  12. name:'home',
  13. data(){
  14. return{
  15. msg:'Home向Hello传的消息',
  16. msg2:''
  17. }
  18. },
  19. components:{Hello},
  20. methods:{
  21. getmsg(data){
  22. this.msg2=data;
  23. }
  24. }
  25. }
  26. </script>
  27. <style>
  28. </style>

第2.2步,其它组件都可以引用共享数据

src/components/hello.vue

【1】写一个函数获取vuex并返回store共享数据

【2】获取vuex的store共享数据方法2(在computed内写一个获取函数,再调用)

  1. <template>
  2. <div>
  3. <!--【2】获取vuex的store共享数据方法2 -->
  4. hello子组件:{{getCount}}----{{title}}<br/>
  5. <button @click="sendMsg">给父组件传消息</button>
  6. </div>
  7. </template>
  8. <script>
  9. export default{
  10. name:'hello',
  11. data(){
  12. return{
  13. msg:'Hello子组件向父组件传数据'
  14. }
  15. },
  16. props:{
  17. title:{
  18. type:String,
  19. default:''
  20. }
  21. },
  22. computed:{
  23. //【1】写一个函数获取vuex并返回store共享数据
  24. getCount(){
  25. return this.$store.state.count
  26. }
  27. },
  28. methods:{
  29. sendMsg(){
  30. this.$emit('msg',this.msg)
  31. }
  32. }
  33. }
  34. </script>
  35. <style>
  36. </style>

效果:成功获取到在mian.js内定义的count数据值

10

2.2 修改共享数据实例 mutaitions:{}

第1步,定义修改共享数据的函数 main.js

[6]更改state里的数据在mutations里写函数操作

[6.1.0]自加函数,用于其它组件操作数据通过 this.\(store.commit('increment')
[6.1.1]自减函数,用于其它组件操作数据通过 this.\)store.commit('decrement')

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import Vuex from 'vuex' //[1]引入vuex
  4. Vue.use(Vuex)//[2]使用vuex
  5. //[3]创建一个store实例
  6. const store=new Vuex.Store({
  7. state:{//[4]所有组件共用数据存放处
  8. count:10
  9. },//[6]更改state里的数据在mutations里写函数操作
  10. mutations: {
  11. increment (state) {//[6.1.0]自加函数,用于其它组件操作数据通过 this.$store.commit('increment')
  12. state.count++
  13. },
  14. decrement(state){//[6.1.1]自减函数,用于其它组件操作数据通过 this.$store.commit('decrement')
  15. state.count--
  16. }
  17. }
  18. })
  19. new Vue({
  20. el: '#app',
  21. store,//[5]注入store
  22. render: h => h(App)
  23. })

第2步,在组件中使用1步定义的修改共享数据函数 home.vue

【1】使用mutations里定义好的函数进行共享数据自加操作

【1.1】使用mutations里定义好的函数进行共享数据自减操作

【2】修改共享数据自加

【2.1】修改共享数据自减

  1. <template>
  2. <div>
  3. <Hello :title='msg' @msg='getmsg'/><br/>
  4. {{msg2}}<br/>
  5. <!-- 获取store里的共享数据方法1 -->
  6. home:获取vuex的store共用数据:{{this.$store.state.count}}<br/><br/>
  7. <button @click='add'>加store.state里数据</button> <!-- 【2】修改共享数据自加 -->
  8. <button @click="sub"></button> <!-- 【2.1】修改共享数据自减 -->
  9. </div>
  10. </template>
  11. <script>
  12. import Hello from './hello.vue';
  13. export default{
  14. name:'home',
  15. data(){
  16. return{
  17. msg:'Home向Hello传的消息',
  18. msg2:''
  19. }
  20. },
  21. components:{Hello},
  22. methods:{
  23. add(){//【1】使用mutations里定义好的函数进行共享数据自加操作
  24. this.$store.commit('increment')
  25. },
  26. sub(){//【1.1】使用mutations里定义好的函数进行共享数据自减操作
  27. this.$store.commit('decrement')
  28. },
  29. getmsg(data){
  30. this.msg2=data;
  31. }
  32. }
  33. }
  34. </script>
  35. <style>
  36. </style>

hello.vue 不重要

  1. <template>
  2. <div>
  3. <!--获取vuex的store共享数据方法2 -->
  4. hello子组件:{{getCount}}----{{title}}<br/>
  5. <button @click="sendMsg">给父组件传消息</button>
  6. </div>
  7. </template>
  8. <script>
  9. export default{
  10. name:'hello',
  11. data(){
  12. return{
  13. msg:'Hello子组件向父组件传数据'
  14. }
  15. },
  16. props:{
  17. title:{
  18. type:String,
  19. default:''
  20. }
  21. },
  22. computed:{
  23. //写一个函数获取vuex并返回store共享数据
  24. getCount(){
  25. return this.$store.state.count
  26. }
  27. },
  28. methods:{
  29. sendMsg(){
  30. this.$emit('msg',this.msg)
  31. }
  32. }
  33. }
  34. </script>
  35. <style>
  36. </style>

效果:点加按钮会进行共享数据自加操作,减则自减

注意:数据变更后,所有地方数据都会自动进行变更

2.3 actions的使用

Actions:

Action 提交的是 mutation,而不是直接变更状态。

Action 可以包含任意异步操作。

mutaitions内只能执行同步操作。

src/main.js 定义actions:{}内函数

【1】用动作操作mutations里函数

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import Vuex from 'vuex' //[1]引入vuex
  4. Vue.use(Vuex)//[2]使用vuex
  5. //[3]创建一个store实例
  6. const store=new Vuex.Store({
  7. state:{//[4]所有组件共用数据存放处
  8. count:10
  9. },//[6]更改state里的数据在mutations里写函数操作
  10. mutations: {
  11. increment (state) {//[6.1.0]自加函数,用于其它组件操作数据通过 this.$store.commit('increment')
  12. state.count++
  13. },
  14. decrement(state){//[6.1.1]自减函数,用于其它组件操作数据通过 this.$store.commit('decrement')
  15. state.count--
  16. }
  17. },
  18. actions:{//【1】用动作操作mutations里函数
  19. increment(context){//context承上启下
  20. context.commit('increment');
  21. },
  22. decrement(context){
  23. context.commit('decrement');
  24. }
  25. }
  26. })
  27. new Vue({
  28. el: '#app',
  29. store,//[5]注入store
  30. render: h => h(App)
  31. })

src/components/home.vue 调用actions内的函数

【1】使用main.js里actions里定义好的函数进行共享数据自加操作

【1.1】使用main.js里action里定义好的函数进行共享数据自减操作

this.$store.dispatch('decrement')

  1. <template>
  2. <div>
  3. <Hello :title='msg' @msg='getmsg'/><br/>
  4. {{msg2}}<br/>
  5. <!-- 获取store里的共享数据方法1 -->
  6. home:获取vuex的store共用数据:{{this.$store.state.count}}<br/><br/>
  7. <button @click='add'>加store.state里数据</button> <!-- 【2】修改共享数据自加 -->
  8. <button @click="sub"></button> <!-- 【2.1】修改共享数据自减 -->
  9. </div>
  10. </template>
  11. <script>
  12. import Hello from './hello.vue';
  13. export default{
  14. name:'home',
  15. data(){
  16. return{
  17. msg:'Home向Hello传的消息',
  18. msg2:''
  19. }
  20. },
  21. components:{Hello},
  22. methods:{
  23. add(){//【1】使用main.js里actions里定义好的函数进行共享数据自加操作
  24. // this.$store.commit('increment')
  25. this.$store.dispatch('increment')
  26. },
  27. sub(){//【1.1】使用main.js里action里定义好的函数进行共享数据自减操作
  28. // this.$store.commit('decrement')
  29. this.$store.dispatch('decrement')
  30. },
  31. getmsg(data){
  32. this.msg2=data;
  33. }
  34. }
  35. }
  36. </script>
  37. <style>
  38. </style>

效果:同上,操作共享数据,1加,2减

2.3.1 actions内执行异步操作

src/main.js actions:{}内进行异步模拟

【异步】异步操作模拟,利用setTimeout函数延迟1秒执行自加操作

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import Vuex from 'vuex' //[1]引入vuex
  4. Vue.use(Vuex)//[2]使用vuex
  5. //[3]创建一个store实例
  6. const store=new Vuex.Store({
  7. state:{//[4]所有组件共用数据存放处
  8. count:10
  9. },//[6]更改state里的数据在mutations里写函数操作
  10. mutations: {
  11. increment (state) {//[6.1.0]自加函数,用于其它组件操作数据通过 this.$store.commit('increment')
  12. state.count++
  13. },
  14. decrement(state){//[6.1.1]自减函数,用于其它组件操作数据通过 this.$store.commit('decrement')
  15. state.count--
  16. }
  17. },
  18. actions:{
  19. increment(context){
  20. // context.commit('increment');
  21. setTimeout(function(){ //【异步】异步操作模拟,利用setTimeout函数延迟1秒执行自加操作
  22. context.commit('increment');
  23. },1000)
  24. },
  25. decrement(context){
  26. context.commit('decrement');
  27. }
  28. }
  29. })
  30. new Vue({
  31. el: '#app',
  32. store,//[5]注入store
  33. render: h => h(App)
  34. })

src/components/home.vue

代码同上例,略过

效果同上例略过

2.4 getter:{}的使用

应用场景:例如在购物车中,利用2.3例的自减减少库存,当减少到0时还可以继续减为负数,此时商家将要向用户倒找钱,这样显然不合理。因此引入getter函数;

src/main.js 写 getters用于控制共享数据

【getter】用于控制共享数据的使用

如果count数据大于0则返回count,否则只返回0(小于0时只返回0)

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import Vuex from 'vuex' //[1]引入vuex
  4. Vue.use(Vuex)//[2]使用vuex
  5. //[3]创建一个store实例
  6. const store=new Vuex.Store({
  7. state:{//[4]所有组件共用数据存放处
  8. count:10
  9. },
  10. getters:{//【getter】用于控制共享数据的使用
  11. controlState(state){ //如果count数据大于0则返回count,否则只返回0(小于0时只返回0)
  12. return state.count > 0 ? state.count : 0
  13. }
  14. },
  15. //[6]更改state里的数据在mutations里写函数操作
  16. mutations: {
  17. increment (state) {//[6.1.0]自加函数,用于其它组件操作数据通过 this.$store.commit('increment')
  18. state.count++
  19. },
  20. decrement(state){//[6.1.1]自减函数,用于其它组件操作数据通过 this.$store.commit('decrement')
  21. state.count--
  22. }
  23. },
  24. actions:{
  25. increment(context){
  26. // context.commit('increment');
  27. setTimeout(function(){ //异步操作模拟,利用setTimeout函数延迟1秒执行自加操作
  28. context.commit('increment');
  29. },1000)
  30. },
  31. decrement(context){
  32. context.commit('decrement');
  33. }
  34. }
  35. })
  36. new Vue({
  37. el: '#app',
  38. store,//[5]注入store
  39. render: h => h(App)
  40. })

src/components/home.vue

【getters-1】通过computed写函数来获取store里的共享数据方法

【getters-2】通过computed写函数来显示store里的共享数据

  1. <template>
  2. <div>
  3. <Hello :title='msg' @msg='getmsg'/><br/>
  4. {{msg2}}<br/>
  5. <!-- 【getters-2】通过computed写函数来显示store里的共享数据 -->
  6. home:获取vuex的store共用数据:{{getState}}<br/><br/>
  7. <button @click='add'>加store.state里数据</button> <!--修改共享数据自加 -->
  8. <button @click="sub"></button> <!--修改共享数据自减 -->
  9. </div>
  10. </template>
  11. <script>
  12. import Hello from './hello.vue';
  13. export default{
  14. name:'home',
  15. data(){
  16. return{
  17. msg:'Home向Hello传的消息',
  18. msg2:''
  19. }
  20. },
  21. components:{Hello},
  22. computed:{//【getters-1】通过computed写函数来获取store里的共享数据方法
  23. getState(){
  24. return this.$store.getters.controlState;
  25. }
  26. },
  27. methods:{
  28. add(){//使用mutations里定义好的函数进行共享数据自加操作
  29. // this.$store.commit('increment')
  30. this.$store.dispatch('increment')
  31. },
  32. sub(){//使用mutations里定义好的函数进行共享数据自减操作
  33. // this.$store.commit('decrement')
  34. this.$store.dispatch('decrement')
  35. },
  36. getmsg(data){
  37. this.msg2=data;
  38. }
  39. }
  40. }
  41. </script>
  42. <style>
  43. </style>

效果:加了用getter获取数据2处最多只能减到0,没加的,3还是会返回负数

2.5 moudel模块操作

官方文档:https://vuex.vuejs.org/zh/guide/modules.html

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

  1. const moduleA = {
  2. state: { ... },
  3. mutations: { ... },
  4. actions: { ... },
  5. getters: { ... }
  6. }
  7. const moduleB = {
  8. state: { ... },
  9. mutations: { ... },
  10. actions: { ... }
  11. }
  12. const store = new Vuex.Store({
  13. modules: {
  14. a: moduleA,
  15. b: moduleB
  16. }
  17. })
  18. store.state.a // -> moduleA 的状态
  19. store.state.b // -> moduleB 的状态

2.6 store提取为单独文件

也可参考 router

具体步骤:

  1. 新建一个src/store文件夹
  2. 在建立一个文件/src/store/index.js
  3. 把store提取到2步建好的文件
  4. 在main.js里引入store文件

/src/store/index.js

【1】注意导出:创建一个store仓库

  1. import Vue from "vue"
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. // 【1】注意导出:创建一个store仓库
  5. export default new Vuex.Store({
  6. state: {
  7. count: 10
  8. },
  9. mutations: {
  10. increment(state) {
  11. state.count++;
  12. },
  13. decrement(state) {
  14. state.count--;
  15. }
  16. },
  17. actions: {
  18. // context:承上启下
  19. increment(context) {
  20. setTimeout(function() {
  21. context.commit("increment");
  22. })
  23. },
  24. decrement(context) {
  25. setTimeout(function() {
  26. context.commit("decrement");
  27. })
  28. }
  29. },
  30. getters: {
  31. controlState(state) {
  32. return state.count > 0 ? state.count : 0
  33. }
  34. }
  35. });

main.js

【1】全局引入store文件

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import store from './store/index.js' //【1】全局引入store文件
  4. new Vue({
  5. el: '#app',
  6. store,//[5]注入store
  7. render: h => h(App)
  8. })

效果:同上例

十、Vue:Vuex实现data(){}内数据多个组件间共享的更多相关文章

  1. 还原Vue.js的data内的数组和对象

    最近学习Vue.js发现其为了实现对data内的数组和对象进行双向绑定,将数组和对象进行了封装. 如下的对象 todos: [     {         id: 1,         title: ...

  2. 【C++】DLL内共享数据区在进程间共享数据(重要)

    因项目需要,需要在DLL中共享数据,即DLL中某一变量只执行一次,在运行DLL中其他函数时该变量值不改变:刚开始想法理解错误,搜到了DLL进程间共享数据段,后面发现直接在DLL中定义全局变量就行,当时 ...

  3. android组件间共享数据的常用方法

    使用Intent在激活组件的时候携带数据,以进行数据的传递 使用广播进行组件间数据的伟递 使用外部存储(sharedPreference,文件,数据库,网络)进行组件间数据共享 使用Static静态成 ...

  4. 深入浅出的webpack4构建工具--webpack4+vue+vuex+mock模拟后台数据(十九)

    mock的官网文档 mock官网 关于mockjs的优点,官网这样描述它:1)可以前后端分离.2)增加单元测试的真实性(通过随机数据,模拟各种场景).3)开发无侵入(不需要修改既有代码,就可以拦截 A ...

  5. 解决vue中模态框内数据和外面的数据绑定的问题

    1.做表格的修改,把整条数据传到模态框做修改,但是出现模态框改变数据没有保存时,表格的数据也会跟着改变,我想实现保存以后表格数据才会改变的功能. html:使用item整条数据都上传过去了,在upda ...

  6. 对vue中的data进行数据初始化

    this.$data:是表示当前的改变后的this中的数据 this.$options.data():是表示没有赋值前的this中的数据,表示 初始化的data 一般可以使用Object.assign ...

  7. Vue+element UI实现表格数据导出Excel组件

    介绍 这是一个可以将页面中的表格数据导出为Excel文件的功能组件,该组件一般与表格一起使用,将表格数据传给组件,然后通过点击组件按钮可将表格中的数据导出成Excel文件. 使用方法 由于封装该组件内 ...

  8. vue使用技巧:Promise + async + await 解决组件间串行编程问题

    业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...

  9. 浅谈Vue不同场景下组件间的数据交流

    浅谈Vue不同场景下组件间的数据“交流”   Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...

随机推荐

  1. HashMap与HashTable源码学习及效率比较分析

    一.个人学习后的见解: 首先表明学习源码后的个人见解,后续一次依次进行分析: 1.线程安全:HashMap是非线程安全的,HashTable是线程安全的(HashTable中使用了synchroniz ...

  2. Java基础 -1.3

    CLASSPATH 为了 可以在不同的目录中都可以执行d:\java\Hello.class文件 只能够依靠CLASSPATH环境变量 在cmd中 SET CLASSPATH = d:\java 当设 ...

  3. 使用TortoiseGit处理代码冲突

    使用TortoiseGit处理代码冲突  https://www.cnblogs.com/jason-beijing/p/5718190.html 场景一  user0 有新提交 user1 没有pu ...

  4. Jquery 获取控件的值

    1:通过控件的ID 获取值 $("input[name='weiKuanDate']").val(); 2:通过控件的name 获取值 $("input[name='we ...

  5. idea右键新建选项没有类和包的创建方式

    Intelidea创建好项目之后,右键新建Java class的时候发现没有改选项,只有以下几个选项 把sec目录设为源码目录,首先打开Project Structure

  6. 运行cmd直接进入指定目录下的命令

    新建一个.bat批处理文件,文件命令为@ECHO OFF cmd /k cd /d c:data 运行该批处理文件cmd就可进入指定的文件夹,感兴趣的朋友可以参考下啊 新建一个.bat批处理文件,文件 ...

  7. Numpy 为运算

    Numpy “bitwise_” 开头的函数是位运算函数: Numpy 位运算包括以下几个函数: 函数 描述  bitwise_and  对数组元素执行位与操作  bitwise_or 对数组元素执行 ...

  8. leetcode424 Longest Repeating Character Replacement

    """ Given a string s that consists of only uppercase English letters, you can perform ...

  9. 【剑指Offer面试编程题】题目1385:重建二叉树--九度OJ

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...

  10. 【转载】将Centos的yum源更换为国内的阿里云源

    自己的yum源不知道什么时候给改毁了--搜到了个超简单的方法将yum源更换为阿里的源 完全参考 http://mirrors.aliyun.com/help/centos?spm=5176.bbsr1 ...