#yyds干货盘点#Vuex实战讲解(全),玩转Vue必备知识

网站建设1年前发布 123456
38 00

Vuex概况

store核心概念

  1. State:  包含了store中存储的各个状态。
  2. Getters:  类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值。
  3. Mutation: 一组方法,是改变store中状态的执行者,只能是同步操作。
  4. Action:  一组方法,其中可以包含异步操作。
  5. Moudule:  Module是store分割的模块,每个模块拥有自己的state、getters、mutations、actions。   

vuex辅助函数

在Vuex中获取数据的辅助函数有两个mapState、mapGetters, 操作Mutation和acitonhas函数mapMutations、mapActions

前两个用在computed(计算属性中)

后两个用在methods(方法中)

如何使用

多个组件共享同一个状态(数据)

1.安装vuex

新建store文件夹===>index.js main.js中,导入store对象,并且放在new Vue中 就可以通过this.$store的方式获取到这个store对象

2.使用vuex中的count(state中定义的共享状态)

this.$store.state.count

3.不能直接修改store中的状态,直接修改devtools监听不到数据的修改

4.mutations 负责同步修改状态

Vuex的store修改状态唯一的方式:提交mutations–>(this.$store.commit(‘add’))

Getters Store中的计算属性


// 计算数字的平方
quadratic(state) {
// 第一个参数,状态state
return state.count * state.count

![](<> “点击并拖拽以移动”)

2.筛选数据


filterInfo(state) {
return state.info.filter(res =>{
return res.age>18
})
  • 获取数据

info:this.$store.getters.filterInf

3.如果想要获取符合条件的个数

  • {{$store.getters.filterInfo.length}}

4.如果不想年龄晒选写死,想自己输入年龄,只需要在getters里写一个方法


// 筛选数据
filterInfo(state, age) {
//要返回一个方法才可以传值
//age返回的不是一个确定的值,而是一个函数
// 1.
// return function(age){
// return state.info.filter(res =>{
// return res.age>age
// })
// }
// 2.
return (age) => {//return后才可以传递参数
return state.info.filter(res => res.age > age)

5.getters中的两个参数


// 第一个state,拿数据,第二个参数geters:也就是说可以从getters中调用上面平方根的方法
testGettes(state,getters){
return getters.quadratic

vuex辅助函数

辅助函数

mapState, 用于将state中的数据映射到组件的计算属性中


<!-- 第一种 -->

<!--
组件中的计算属性名称,和vuex状态名称不一致的时候,可以使用对象写法
-->
computed:mapState({
cnum:"count",
})
<!-- 第二种 -->
<!--
字符串数组写法,
组件中计算属性名,和vuex中状态名一致的时候
-->
computed:mapState([
"count",
])
<!-- 第三种 -->
<!--
当组件有自己的计算属性的时候,我们可以使用结构写法,将辅助函数合并到计算属性中
-->

computed:{
...mapState({
cnum:"count",
})

![](<> “点击并拖拽以移动”)

mapGetters 用于将getter中的计算属性映射到组件的计算属性中用法同mapState


computed:{
// 对象展开符,解构mapGetters
...mapGetters({
// 将store中的getters的filterInfo,映射到组件上的info计算属性上
info:"filterInfo"
}),

...mapGetters([ //字符串数组
"getInfoLength"
])
}

mapMutations : 用于将mutations映射到methods中
...mapMutations([
"add"
]),
// 对象写法
...mapMutations({
// 同步,通过commit触发mutations
myadd:"add",
// 方法名:mutation函数名
addtwo:"addParms"
}),
mapActions :于将actions映射到methods中
...mapActions({
// 方法名:mutation函数名
myasync:"asyncAdd"
}

Vuex中的核心 — modules

当项目比较大的时候,如果只有一个模块来维护数据,那么这个模块会非常的大,对于维护性来说,不是特别高,所以vuex中,提供模块功能,我们可以通过modules将vuex处理为多个模块


const myCount={
state:{
user:{
name:'admin',
pass:'12345'
},
count:10
},
getters:{

},
mutations:{
// 模块的同步中是没有第三参数,(根状态)
cAdd(state,paylaod){
console.log(this)
state.count++
}
},
actions:{

}
}
export default new Vuex.Store({
state:{
num:2
},
modules: { // 模块选项
// 引用myuser模块
u:myUser,
c:myCount,
cat

}
}

使用模块的属性


$store.state.模块名称.属性名
$store.getters.模块名称.属性名
$store.commit('方法名称')//同步提交
$store.dispatch('方法名称') //异步提

实战解析

上面概念说完了,该实战练习了,动起来!

State,Mutations

store下的index.js


import Vue from 'vue'
import Vuex from 'vuex'
// 安装插件
Vue.use(Vuex)
export default new Vuex.Store({
state: {//存储状态
// 自定义共享状态
count:0,
stu:[
{id:1001,name:123},
{id:1003,name:'符鼠'},
{id:1004,name:'追梦'},
],
user:{
name:'随便',
sex:'随机'
}
},
// vuex中的store状态更新的唯一方式是提交Mutation
mutations: {//写方法,通过mutations修改、页面的插件才能监听到
add(state){//方法的第一个参数就是state,也就是state的对象
// this是store对象
state.count++
},
//state(store中的state),(Payload:提交方法携带的参数)
addTen(state,ten){//点击加10
state.count += ten
},
addTwo(state,obj){//点击加2,加obj才能接收对象
state.count += obj.two
},
// 向stu数组中添加一条数据
addStu(state,payload){
state.stu.push(payload)//向数组中添加数据
},
updUser(state,age){//给stu对象添加新属性
// state.user.age='18'不能写等号
// state.user = {...state.user,'age':12}
Vue.set(state.user,'age',123)
}
},
actions: {},
modules: {}
}

Aone组件


<template>
<div class="hello">
<h1>aone组件</h1>
<h2>{{$store.state.count}}</h2>
<li>{{$store.state.stu}}</li>
<button @click="addTen">+10</button>
<button @click="addStu">添加成员</button>
</div>
</template>
<script>
export default {
name: 'aone',
props: {
msg: String,
count:Number
},
data() {
return {
stu:{id:1005,name:'测试'}
}
},
methods: {
addTen(){
// 触发mutations函数,指定额外参数,字符串方式提交
this.$store.commit('addTen',10)
},
addStu(){
this.$store.commit('addStu',this.stu)
}
},
}
</script

hello组件


<template>
<div class="hello">
<h1>helloworld组件</h1>
<h2>{{$store.state.count}}</h2>
<h2>{{$store.state.user}}</h2>
<button @click="addTwo">点击加2</button>
<button @click="updUser">修改</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
count:Number
},
methods: {
addTwo(){
// 触发mutations函数,指定额外参数,对象形式提交
this.$store.commit({
type:'addTwo',
two:2
})
},
updUser(){
// 触发mutations函数,指定额外参数
this.$store.commit({
type:'updUser' })
}
},
}
</script

Actions,Getters

store下的index.js


import Vue from 'vue'
import Vuex from 'vuex'
// 安装插件
Vue.use(Vuex)
// 实例化vuex并导出
export default new Vuex.Store({
state: {
count: 0,
info: [
{
di: 1, name: '开发者1', age: 21
},
{
di: 2, name: '开发者2', age: 22
},
{
di: 3, name: '开发者3', age: 23
},
]
},
// 只能通过mutations更改数据
mutations: {//如果mutation是一个异步函数,那么devtools不能跟踪数据变化
// mutations负责同步修改状态
increment(state, payload) {
// setTimeout(()=>{
state.count += payload
// },2000)
}
},
// 专写异步actions
actions: {//context上下文对象
asyncIcrement(context, payload) {
setTimeout(() => {
context.commit('increment', payload)
}, 2000)
}
},
getters: {//store的计算属性
// 计算数字的平方
quadratic(state) {
// 第一个参数,状态state
return state.count * state.count
},
// 筛选数据
filterInfo(state, age) {
//要返回一个方法才可以传值
//age返回的不是一个确定的值,而是一个函数
// return function(age){
// return state.info.filter(res =>{
// return res.age>age
// })
// }
return (age) => {//return后才可以传递参数
return state.info.filter(res => res.age > age)
}
},
testGettes(state,getters){
// 调用上面平方根的方法
return getters.quadratic
}
},
modules: {
}
}

myvux组件


<template>
<div id="main">
<h2>这是myvue组件</h2>
<h3>{{$store.state.count}}</h3>
<button @click="add">+1</button>
<button @click="asyAdd">异步+1</button>
<h2>获取年龄小于22的开发</h2>
</div>
</template>
<script>
export default {
methods: {
add(){
this.$store.commit('increment',5)
},
asyAdd(){
// 触发actions异步并传参
this.$store.dispatch('asyncIcrement',10)
}
},
}
</script

myhome组件


<template>
<div id="home">
<h2>这是home组件</h2>
<h3>{{$store.state.count}}</h3>
<h3>平方:{{$store.getters.quadratic}}</h3>
<!-- 通过getters来筛选数据 -->
<div>
<h3>获取大于22的</h3>
<li v-for="itme in info">
{{itme}}
</li>
<!-- {{$store.getters.filterInfo.length}} -->
//调用上面函数
<h5>{{$store.getters.testGettes}}</h5>
</div>
</div>
</template>
<script>
export default {
data() {
return {
info:this.$store.getters.filterInfo(22)
}
},
}
</script

辅助函数及Modules

store下的index.js


import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0,
user:{
name:'admin',
pass:'123'
},
info: [
{
di: 1, name: '开发者1', age: 21
},
{
di: 2, name: '开发者2', age: 22
},
]
},
getters:{
filterInfo(state){
// 过滤大于20的数据
return state.info.filter(info=>info.age>22)
},
getInfoLeng(state,getter){
return getter.filterInfo.length
}
},
mutations: {
add(state){
this.count ++
},
addParms(state,num){
this.count += num
}
},
actions: {
//异步
asyncAdd(context){
setTimeout(()=>{
context.commit('add')
},2000)
}
},
modules: {
}
}

Mystate组件(mapstate对应state)


<template>
<div id="mystate">
<!-- 使用vuex中的count -->
<p>数字:{{ $store.state.count }}</p>
<!-- <p>数字data:{{num}}</p> -->
<!-- <p>计算属性中的数字:{{cnum}}</p> -->
<!-- vuex中的数据 -->
<!-- <p>mapstate:{{count}}</p>
<p>mapstate:{{user}}</p> -->
<p>cuser:{{ cuser }}</p>
<p>cuser:{{ csuser }}</p>
<p>cnum:{{ cnum }}</p>
<p>组件自己的计算属性:{{ cPrice }}</p>
</div>
</template>
<script>
import {mapState} from 'vuex'
// console.log(mapState);
export default {
data() {
return {
// 在data中定义不是响应式
num:this.$store.state.count,
price:10
}
},
// 计算属性
// computed:{
// cnum(){
// return this.$store.state.count
// }
// }
// 通过mapState辅助函数,帮我们自动生成计算属性
// computed:mapState([//字符串数组写法
// // 属性名和vuex状态名相同可以使用数组的形式写
// 'count',//将vuex中状态count映射到计算属性中
// 'user'
// ])
// 以对象形式使用
// computed:mapState({
// cuser(state){
// // 通过计算属性的第一个函数,是vuex中的状态state,所以可以通过state直接获取数据
// return state.user//this.$store.user
// },
// // 简写方式
// csuser:state => state.user,
// // 等价于tate => state.count
// cnum:'count'
// })
computed:{
//组件自己的计算属性
cPrice(){
return '$'+this.price
},
//通过mapState映射过来的计算属性
...mapState({
cuser(state){
// 通过计算属性的第一个函数,是vuex中的状态state,所以可以通过state直接获取数据
return state.user//this.$store.user
},
// 简写方式
csuser:state => state.user,
// 等价于tate => state.count
cnum:'count'
})
}
}
</script

Mygetter组件(mapgetters对应getters)


<template>
<div id="mygetter">
<h3>mapgetter用法</h3>
<p>直接使用getters:{{$store.getters.filterInfo}}</p>
<p>mapgetters:{{info}}</p>
<p>获取长度(info):{{getInfoLeng}}</p>
</div>
</template>
<script>
// 获取辅助函数
import { mapGetters, mapState } from "vuex";
// console.log(mapState);
export default {
computed: {
// 对象展开符解构mapgetters
...mapGetters({//对象写法
// 将store中的getters的filterInfo映射到组件上的info计算属性上
info:'filterInfo'
}),
...mapGetters([//字符串数组写法
'getInfoLeng'
])
},
};
</script

mymutations组件(mapmutations对应mutations)


<template>
<div id="mymutations">
<h3>使用mapmutions和mapactions</h3>
<button @click="add">触发add</button>
<button @click="myadd">触发myadd</button>
<!-- 传参 -->
<button @click="addtwo(3)">+3</button>
<button @click="myasync">触发异步</button>
</div>
</template>
<script>
// 获取辅助函数
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex';
export default {
// 计算属性
computed:{
},
// 放方法
methods: {
// 为了触发mutation函数 定义的方法没必要这么写
// clickAdd(){
// this.$store.commit('add')
// }
//触发异步
myasync(){
this.$store.dispantch('asyncAdd')
},
// 字符串数组的用法
...mapMutations([
'add'
]),
// 对象写法
...mapMutations({
// 同步方法通过commit触发mutauions
myadd:'add',
// 方法名:mutation函数名
addtwo:'addParms'
}),
//异步
...mapActions({
myasync:'asyncAdd'
})
},
}
</script

Modules模块的使用


<script>
//vuex文件
import Vue from 'vue'
import Vuex from 'vuex'
import myUser from './myuser'
import cat from './cat'
Vue.use(Vuex)
// const myUser={

// }
export default new Vuex.Store({
modules: {//模块选项
// 引入
u:myUser,
cat
}
})
</script>
-----------------------------------------------------------下面是展示页面
<template>
<div class="modules">
<!-- 多了一层u -->
<h4>user信息:{{$store.state.u.user}}</h4>
<h4>cat信息:{{$store.state.cat.mycat}}</h4>
</div>
</template

结尾

如果对您有帮助,希望能给个评论收藏三连!

想跟博主交朋友的可以关注下,有问题评论留言。

​博主公众号:前端老实人,希望可以认识大家,一起学习哦​

© 版权声明

相关文章