vuex状态机是什么,有哪些要点
Admin 2022-07-18 群英技术资讯 292 次浏览
通常有以下几种方式:
3.使用vuex优点:
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中。而对于组件中的私有数据,就没必要了,依旧存储在组件自身的data中即可。当然,如果你想要都存在vuex中也是可以的。
1.安装依赖包:
npm install vuex --save
2.导入依赖包:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
3.创建store对象:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ //state中存放的就是全局共享的数据 state: { count: 0 } })
4. 将store对象挂载到vue实例中:
new Vue({ el: '#app', store })
此时所有组件就可以从store中获取数据了。
下面为创建一个vue项目流程,后面会有案例:
(1)打开cmd窗口输入 vue ui 打开vue的可视化面板:
(2)选择新建项目路径:
(3)命名:
(4)手动选择配置,注意用的是vue2版本:
(5)创建:
(6)下一步:
(7)创建成功,到对应目录打开vscode开始编程:
(8)运行项目:
前提(注意):
写一个计数器小案例,从案例中配合概念能更快上手vuex。所以下面核心概念中的代码部分是基于这个小案例来演示的。目标:写两个子组件,有一个公共count值,在父组件中,其中一个组件实现点击后count值减1,一个组件实现点击后count值增1。
父组件 App.vue 初始代码:
<template> <div id="app"> <my-add></my-add> <p>--------------------</p> <my-reduce></my-reduce> </div> </template> <script> // 引入组件 import Add from './components/Add.vue' import Reduce from './components/Reduce.vue' export default { name: 'App', data() { return { } }, components: { 'my-add': Add, 'my-reduce': Reduce } } </script>
子组件Add.vue初始代码:
<template> <div> <p>count值为:</p> <button>+1</button> </div> </template> <script> export default{ data() { return { } }, } </script>
子组件Reduce.vue初始代码:
<template> <div> <p>count值为:</p> <button>-1</button> </div> </template> <script> export default{ data() { return { } }, } </script>
store对象初始代码为:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0 } })
初始效果:
按照官方的话来说,如下:Vuex 使用单一状态树――是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
简单来说,就是State提供唯一的公共数据源, 所有共享的数据都要统一放到Store的State中进行存储。
组件中直接输入以下命令:
this.$store.state.引用的数据名字
如在Add.vue子组件中引用:
<template> <div> <p>count值为:{{this.$store.state.count}}</p> <button>+1</button> </div> </template> //下面部分代码跟前面一样无改变,所以省略了
看效果,显示了count的值为0:
(1)从 vuex 中按需导入 mapState 函数
import { mapState } from 'vuex'
(2)通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
computed: { ...mapState([count]) }
小知识:computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
如在Reduce.vue子组件中引用:
<template> <div> <p>count值为:{{count}}</p> <button>-1</button> </div> </template> <script> import {mapState} from 'vuex' export default{ data() { return { } }, computed: { ...mapState(['count']) } } </script>
看效果,同样显示了count的值为0:
按照官方的话来说,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
简单来说就是Mutation用于变更Store中的数据。
①只能通过mutation变更Store数据,不可以直接操作Store中的数据。
②通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
比如,要实现count值自增加1的操作,那就在先motations里定义一个自增加1的函数。然后对应子组件想用,该组件就直接引入mutation并调用对应的函数就好。
如下,Add.vue子组件要实现自增加1功能:
先在状态机里的mutations里定义一个能实现自增的函数add:
export default new Vuex.Store({ state: { count: 0 }, mutations: { //自增加1函数 add(state){ state.count++ } } })
Add.vue子组件里给按钮绑定点击事件,并触发mutation:
<template> <div> <p>count值为:{{this.$store.state.count}}</p> <button @click="btnAdd">+1</button> </div> </template> <script> export default{ data() { return { } }, methods: { btnAdd() { // 第一种引入mutation的方式,触发add函数 this.$store.commit('add') } } } </script>
看效果实现了点击自增:
当然,当组件里调用mutation里函数时,也是可以传参数的。
比如,有一个自增函数,但增多少看调用时传入的参数:
export default new Vuex.Store({ state: { count: 0 }, mutations: { // 传入参数,第一个一定是state,第二个为传入的参数 //自增加 n 的函数 addN(state,n){ state.count+= n } } })
对应组件调用时要传入参数:
methods: { btnAdd2() { // 引入mutation的方式,触发addN函数 // 并传参,自增加6吧 this.$store.commit('addN',6) } }
(1)从 vuex 中按需导入 mapMutations 函数
import { mapMutations } from 'vuex'
(2)通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法:
methods: { ...mapMutations(['add','addN']) }
实战,实现Reduce.vue组件的点击自减1的功能要求:
状态机添加自减函数:
export default new Vuex.Store({ state: { count: 0 }, mutations: { //自增加1函数 add(state){ state.count++ }, // 自减1的函数 sub(state){ state.count-- } } })
Reduce.vue组件点击按钮实现自减1:
<template> <div> <p>count值为:{{count}}</p> <button @click="btnSub">-1</button> </div> </template> <script> //导入 import {mapState,mapMutations} from 'vuex' export default{ data() { return { } }, computed: { ...mapState(['count']) }, methods: { // 映射mutation里的sub函数 ...mapMutations(['sub']), // 要自减,调用sub函数 btnSub(){ this.sub() } } } </script>
看效果:
至此,第四大点里的案例已经完成,已经实现了自增和自减,现在对案例做改进,要我们点击按钮一秒后再自增和自减,该怎么实现?可以在状态机里的mutation里的函数是加一个1秒定时器吗,这肯定是不行的,因为mutation里不支持异步操作,那咋办,当当当,Action闪亮登场。
Action 可以包含任意异步操作,所以它用来处理异步任务。
Action 提交的是 mutation,而不是直接变更状态。记住它并不能直接修改state里的数据,只有mutation能修改。就是说,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
先在状态机里定义Action:
export default new Vuex.Store({ state: { count: 0 }, mutations: { //自增加1函数 add(state){ state.count++ }, // 自减1的函数 sub(state){ state.count-- } }, // 定义action,里面的addAsync函数实现1秒后执行mutation里的add函数 actions: { addAsync(context) { setTimeout(()=>{ // 必须通过context.commit()触发mutation才行 context.commit('add') },1000) } } })
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation。
更改组件Add.vue代码,引入Action,实现异步自增操作。
<template> <div> <p>count值为:{{this.$store.state.count}}</p> <button @click="btnAdd">+1</button> </div> </template> <script> export default{ data() { return { } }, methods: { btnAdd() { // 第一种引入Action的方式,触发addAsync函数 // 这里的dispatch专门用来调用action函数 this.$store.dispatch('addAsync') } } } </script>
看效果,实现1秒后自增:
当然,当组件里调用action里函数时,也是可以传参数的。
比如,有一个点击1秒后才执行的自增函数,但增多少看调用时传入的参数:
定义:
export default new Vuex.Store({ state: { count: 0 }, mutations: { // 传入参数,第一个一定是state,第二个为传入的参数 //自增加 n 的函数 addN(state,n){ state.count+= n } }, actions: { // 有参数 n,这个n又传给了mutation里的addN函数 addNAsync(context,n) { setTimeout(()=>{ context.commit('addN',n) },1000) } } })
对应组件调用时要传入参数:
methods: { btnAdd2() { // 调用dispatch函数 // 触发action时传参数,为 6 吧,表示自增6 this.$store.dispatch('addNAsync',6) } }
(1)从 vuex 中按需导入 mapActions 函数
import { mapActions } from 'vuex'
(2)通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法:
methods: { ...mapActions(['add','addN']) }
实战,实现Reduce.vue组件的点击一秒后自减1的功能要求:
定义actions里的subAsync为一秒后自减函数:
export default new Vuex.Store({ state: { count: 0 }, mutations: { //自增加1函数 add(state){ state.count++ }, // 自减1的函数 sub(state){ state.count-- } }, actions: { addAsync(context) { setTimeout(()=>{ context.commit('add') },1000) }, subAsync(context) { setTimeout(()=>{ context.commit('sub') },1000) } } })
更改Reduce.vue代码,实现功能:
<template> <div> <p>count值为:{{count}}</p> <button @click="btnSub">-1</button> </div> </template> <script> //导入 import {mapState,mapActions} from 'vuex' export default{ data() { return { } }, computed: { ...mapState(['count']) }, methods: { // 映射Action里的函数 ...mapActions(['subAsync']), // 要自减,调用subAsync函数 btnSub(){ this.subAsync() } } } </script>
看效果:
Getter用于对Store中的数据进行加工处理形成新的数据。且要注意的是它并不会修改state中的数据。
①Getter 可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性。
②Store 中数据发生变化,Getter 的数据也会跟着变化。
如,有一个返回当前count+1的getter函数:
export default new Vuex.Store({ state: { count: 0 }, getters: { showNum(state){ return`当前count值加1为:${state.count+1}` } } })
4.1 触发getters的第一种方式:
this.$store.getters.名称
在App.vue组件中显示:
<template> <div id="app"> <my-add></my-add> <p>--------------------</p> <my-reduce></my-reduce> <p>--------------------</p> <h3>{{this.$store.getters.showNum}}</h3> </div> </template>
效果:
(1)从 vuex 中按需导入 mapGetters 函数
import { mapGetters } from 'vuex'
(2)通过刚才导入的mapGetters函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
computed: { ...mapGetters(['showNum']) }
还是在App.vue中使用把:
<template> <div id="app"> <my-add></my-add> <p>--------------------</p> <my-reduce></my-reduce> <p>--------------------</p> <h3>{{showNum}}</h3> </div> </template> <script> // 引入组件 import Add from './components/Add.vue' import Reduce from './components/Reduce.vue' // 导入 mapGetters函数 import {mapGetters} from 'vuex' export default { name: 'App', data() { return { } }, components: { 'my-add': Add, 'my-reduce': Reduce }, // 引入 getter computed: { ...mapGetters(['showNum']) } } </script>
看,一样的效果:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了详解JavaScript中的this指向问题,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下
目录累加/累积求最大/最小值格式化搜索参数反序列化搜索参数拉平嵌套数组实现 flat数组去重数组计数获取对象多个属性反转字符串不知道大家平常用 Reduce 多不多,反正本瓜用
node.js显示乱码的解决办法:1、通过记事本查看nodeJs的编码格式,并设置编码格式为utf-8;2、在js文件中增加编码说明即可。
这篇文章主要为大家详细介绍了Vue实现简易购物车页面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
今天给大家分享的是用Vue怎样实现实时获取天气的功能,而在在 vue 中,我们可以利用webSocket来做一个简单的天气实时更新,下文是实现效果及示例,感兴趣的朋友就继续往下看吧。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008