vueX
vuex介绍
为什么有vuex?
在现代 Web 开发复杂多变的需求驱动之下,组件化开发已然成为了事实上的标准。
然而大多数场景下的组件都并不是独立存在的,而是相互协作共同构成了一个复杂的业务功能。
vuex是什么?
vue是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式储存管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
vuex的使用
下载vuex插件(可看官网选择用3还是4)
npm insrtall vuex@3
在src/story目录下的文件index.js引用vuex组件
//引入vue组件,来进行使用
import Vue from "vue";
// 引入vuex
import Vuex from "vuex";
//实例化Vuex对象里面的Store,要记得大写
const store = new Vuex.Store({
//键值对的形式:state(存放变量),mutations(同步的方法),actions(异步的方法),getters(跟计算器一样的性质),modules(模块)
})
//state,mutations,actions多数写在不同的modules内,getters一般是全局(组件)
// 通过Vue去使用Vuex
Vue.use(Vuex)
// 把实例化的store导出去
export default store
在main.js文件下引用vuex组件
import Vue from 'vue'
import App from './App.vue'
//引用声明为store,暴露出来的实例vuex.store组件
import store from '@/story/index'
Vue.config.productionTip = false
new Vue({
//在Vue实例里面去注册该store组件
store,
render: h => h(App),
}).$mount('#app')
概念一 state
介绍
官方:
- state是放置所有公共状态的属性,每一个公共状态数据 , 都可以定义在 state对象中来全局调用
- 一般都是写在各自模块里面的
**白话:**state是vuex提供给我们声明全局变量的对象,如果我们想要声明一个全局变量,那么只需要把这个变量声明在state对象中即可
定义
const store = new Vuex.Store({
state:{
//管理数据
//例如存进健名count的变量健值为1
count:1
}
})
使用
如下面三种方法都可获得定义的count健值1通过插值表达式显示在div内
原始形式---插值表达式
//在组件中可以使用this.$store获取到vuex中的store对象实例,通过state.语法可以获得属性
<div>
state的数据:{{$store.state.count}}
</div>
计算属性 - 将state属性定义在计算属性中
//把state中数据,定义在组件内的计算属性中
computed:{
count(){
return this.$store.state.count
}
}
在template的文件里调用该属性
<div>
state:{{count}}
</div>
辅助函数 - mapState
- 引入mapState
import {mapState} form 'vuex'
- 采用数组形式引入state属性,利用延展运算符将导出的状态映射给计算属性
computed:{
...mapState(['count'])
}
概念二 mutations
介绍
官方:state数据的修改只能通过mutations,并且mutaions必须是同步更新**,目的是形成**‘数据快照’**
白话:mutations是vuex专门提供给开发来修改state数据的对象,mutations中只能写同步代码。
定义
mutations是一个对象,在里面存储修改state的方法
const store = new Vuex.Store({
state:{
//管理数据
//例如存进健名count的变量健值为1
count:1
}
mutations:{
//方法里参数 第一个参数是当前store的state属性
//payload 载荷 运输参数 调用mutaions的时候 可以传递参数 传递载荷(根据情况看是否需要进行传参)
addCount(state,payload){
//方法的意思是state的count属性加上payload传递过来的实参
state.count +=payload
}
}
})
使用
如下面两种方法都可实现通过mutations里的方法去修改state的值
**调用方法 -$store.commit.方法名 **
- 将mutations属性定义在方法的函数内
- 直接在文档内容调用该方法
<template>
<button @click='$store.commit.addCount(1)'>+1</button>
</template>
<script>
export default {
methods: {
// 调用store中的mutations提交给mutaions
// commit('muations名称',需要传进去的参数)
this.$store.commit('addCount', 1)// 直接调用mutations
}
}
</script>
辅助函数 - mapMutations-,
- 采用数组形式引入mutations
- 利用延展运算符将导出的状态映射给methods
<template>
<button @click='addCount(1)'>+1</button>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['addCount'])
}
}
</script>
概念三 actions
介绍
官方:state是存放数据的,mutations是同步更新数据,actions则负责进行异步操作
白话:actions负责异步操作(通常都是ajax请求),然后通过mutations来间接修改state中的数据。
定义
actions: {
// 获得异步的数据store表示当前store的实例
//相当于const store=new Vuex.store()
//可以通过store.state获得状态,也可以通过store.commit来提交mutations,也可以store.deapatch调用其他的action
getAsyncCount(store){
setTimeout(function () {
// 一秒钟之后 要给一个数 去修改state
store.commit('addCount',1)
},1000)
}
}
使用
原始形式-$store.dispatch.方法名
<script>
export default {
methods: {
//通过方法封装异步函数
addAsyncCount(){
this.$store.dispatch('getAsyncCount')
}
}
}
</script>
辅助函数-mapActions
- 导入mapActions
- 采用数组形式导入actions
- 利用延展运算符将导出的状态映射给methods
<template>
//4.直接调用该异步方法
<button @click='getAsyncCount'>+1</button>
</template>
<script>
//1.引入mapActions
import { mapActions } from 'vuex'
export default {
methods: {
//2.采用数组形式导入actions
//3.利用延展运算符将导出的状态映射给methods
...mapActions(['getAsyncCount'])
}
}
</script>
概念四 getters
介绍
官方:除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters(等于计算器compted)
白话:除了state之外,我们还有能够通过getters来声明全局变量,而这些声明在getters中的变量的值是依赖于state中的数据得来。
定义
主要作用(使用场景):就是简化state中变化访问
//getters对象里面,可以声明任意的属性
//只要属性的值是一个函数,并且这个函数能够默认接收到state参数
//这个state参数就是指和getter统计的state
const store = new Vuex.Store({
state:{
//管理数据
//例如存进健名count的变量健值为1
count:[1,2,3,4,5,6]
}
getters:{
getCountGiger3(state){
//必须要有返回值
return state.count.filter(res=>res>3)
}
}
})
使用
原始形式-$store.getters.属性名
<template>
//展现大于3的数字
<h1>
{{$store.getters.getCountGiger3}}
</h1>
</template>
辅助函数-mapGetters
<template>
//4.直接调用该异步方法
<h1 >{{getCountGiger3}}</h1>
</template>
<script>
//1.引入mapGetters
import { mapGetters } from 'vuex'
export default {
compted: {
//2.采用数组形式导入getters
//3.利用延展运算符将导出的状态映射给compteds
...mapGetters(['getCountGiger3'])
}
}
</script>
概念五 module
介绍
官方:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象state中,当应用(项目)变得非常复杂的时候,就有可能变得相当臃肿。vuex会变得越来越难以维护,由此,有了vuex的模块化。(将一个大板块分成每个不同的区域)
白话:因为所有的数据都是声明在state对象中的,当我们的项目变得非常复杂的时候,我们的state对象就会变得相当臃肿,vuex就变得难以维护,由此,有了vuex的模块化,也就是分模块来保存数据。
定义
官方:
1、vuex专门提供了一个modules属性给我们声明模块,这个属性只要写在和state、mutations、actions、getters同级的位置上即可。
2、直接在modules中声明模块即可,每个模块都有state、mutations、actions、getters、modules
白话:
- 除了分区和可以用密码锁变成局部,和全局一样有state,mutations,actions,getters,modules5大模块,
- 但默认模式下(不启用密码锁)除state和mutations要通过模块名访问,其他mutations,actions,getters默认是注册在全局的
const store = new Vuex.Store({
state:{},
mutations: {},
actions: {},
getters: {},
modules: {}
})
使用
const store = new Vuex.Store({
modules: {
//在模块内声明user和setting两个模块放置state的属性
user: {
state: {
count:1
}
},
setting: {
state: {
name: '李好'
}
}
}
//getters依赖sate的方式可以方便优化调用方式
getters:{
//声明一个属性去承载获取方式
count:state=>state.user.count
name:state=>state.setting.name
})
原始形式-$store.state.模块名.属性名(5大概念都可以使用,不止state)
<h1>
//获取user模块中的count
{{$store.state.user.count}}
</h1>
优化使用-利用getters依赖state的属性和mapGetters辅助函数
<template>
//4.直接调用mapGetters数组里面的属性名显示
<h1 >{{count}}</h1>
<h1 >{{name}}</h1>
</template>
<script>
//1.引入mapGetters
import { mapGetters } from 'vuex'
export default {
compted: {
//2.采用数组形式导入getters
//3.利用延展运算符将导出的状态映射给compteds
...mapGetters(['count','name'])
}
</script>
修改模块的数据
默认情况下,模块内部的action、mutations、getters都注册在全局的。(如下图)
- 定义在模块内的方法
const store = new Vuex.Store({
modules: {
//在模块内声明user和setting两个模块放置state的属性
user: {
state:{
count:1
},
mutations:{
addCount(state){}
state.count++
}
},
})
- 调用该模块内方法(默认情况下和全局一致)
<template>
//调用这个模块的方法
<button @click='$store.commit('addCount')'>点击自增1</button>
</template>
让模块中的mutations具有独立命名空间(局部域)
介绍
通过namespaced属性设置为true, 从而给user模块加一道锁,此刻user模块中的所有内容都是局部的,都必须通过模块名才能访问到,该模块叫独立的命名空间
定义
const store = new Vuex.Store({
//模块
modules: {
//通过给namespaced的健值为true给下面的每个模块(例如user模块)添加一把锁,必须要通过模块名才可以访问的到
namespaced:true;
//在模块内声明user模块和user模块下的mutations的方法
user: {
state:{
count:1
},
mutations:{
addCount(state){}
state.count++
}
},
})
如何访问添加密码锁的模块方法('模块名/函数名')
<template>
//调用这个模块的方法
<button @click='$store.commit('user/addCount')'>点击自增1</button>
</template>