Vuex
概念:
-
Vuex是一个专为Vue.js应用程序开发中管理的一个模式
-
通过创建一个数据存储
对比Vue.js:
- 传统的vue是 单向数据流 ,如果是兄弟组件之间的传值兄弟组件间的状态传递无能为力
- 我们经常会采用父子组件正向/反向传值来对数据进行传递,以上的这些模式非常脆弱,通常会导致我也发维护的代码
- Vue.js只能用于 单个页面中不同组件(例如兄弟组件)数据流通
安装
npm install vuex --save
- 配置vuex文件创建在src中创建store文件夹==>于store.js
单一状态树
- Vuex使用单一状态——用一个对象就包含全部的应用层级状态,至此他便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个store实例
- 创建store实例
import Vue from "vue"
import Vuex from "vuex"
//使用中间件使用Vue
Vue.use(Vuex);
//需要让外部使用实例化的sotre对象,export暴露出去
export let store = new Vue.Store({
})
Vuex–State数据源
- vuex的数据源state,我们需要保存的数据就存放在这里
import Vue from "vue"
import Vuex from "vuex"
Vue.user(Vuex)
export const store = new Vuex.Store({
state:{
arr:["数据1","数据2","数据3","数据4","数据5"]
}
})
vuex–使用数据源
- 要使用首先在main.js引入vuex
- 一对大括号的原因是,指定要从其他模块导入的便变量名
import {store} from "./store/store"
引入对外暴露的vuex对象
new Vue({
store:store,
el:"#app",
router,
compontents:{
App
},
template:"<App/>"
})
vuex —使用数据源
- 使用$store.state.xx调用
{{$state.state.text}}
mounted(){
console.log(this.$store.state.text)
}
- 使用数据的组件中使用计算属性调用
this.$store.state.xx
computed:{
obj(){
return this.$store.state.obj
}
}
vuex–state扩展知识点
- vuex就是一个仓库,仓库内部存放很多对象,其中 state就是数据源存放地,对应于一半Vue对象里面的data
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的state和getters映射到当前组件的computed计算属性之中
vuex–Getters
- getters相当于之前组件中学习的计算属性,getters属性主要是对于state中数据的一种过滤
- 使用场景:在项目开发中,有时候希望对state中的某个属性在多个组件中展示出不同的状态
getters:{
//接受state传递的参数
newarr(state){
var newarr = state.arr.filter((v,i)=>{
//过滤出id大于3的
if(v.id>3){
return v
}
})
//不要忘了
return newarr;
}
}
vuex–使用Getters数据
- 与使用state相同在组件中的 计算属性当中使用 this.$store.getters.xxx来调用
newtextobj(){
return this.$store.getters.newdataobj
}
vuex–Getters扩展知识点
vuex的特性是什么?
- getters可以对state进行计算操作,他就是store的计算属性
- 虽然在组件内部可以叫做计算属性,但是getters可以在多组件之间复用
- 如果一个状态只在一个组件内使用一次或者使用了多次但是展示的形态相同,是可以不用getters
vuex–Mutations
- mutations里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在mutations里面(当触发事件的时候,需要改变state数据的时候使用mutations)
mutations:{
up(state){
state.arr.forEach((v,i)=>{
v.id++
})
}
}
- 注意:不能直接调用一个mutations中的处理函数要使用 this.$store.commit()来进行调用
methods:{
fun(){
//this.$store.commit("调用mutation")
this.$store.commit("dataup")
}
}
vuex–Mutations提交载荷(payload)
- 之前只是一个简单的修改state中的数据
- 在实际项目中,往往会有值传递给Mutations 给store.commit传一个附加参数,也就是叫做mutation的载荷
<button @click="funa(i)">修改</button>
funa(num){
this.$store.commit("uptwo",num)
}
mutations:{
uptwo(state,payload){
//根据用户传递过来的下标修改对应内容
state.arr.forEach((item,index)=>{
if(index==payload){
state.arr[index].title="哈哈哈哈数据我改了奥"
}
})
}
}
多个参数也可以传递一个对象\
this.$store.commit("add",{"num":20})
vuex-Mutations问题
- vuex中页面刷新数据丢失问题
- 使用vue进行开发的过程中,状态管理工具一半选用vue下进行管理,但是修改后的数据vuex数据存储在内存中,所以当页面刷新页面会产生丢失现象
- 使用h5特性本地存储
解决问题的方法
created () {
//在页面加载时读取localStorage里的状态信息
if (localStorage.getItem("data") ) {
//replaceState替换数据 Object.assign合并对象
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(localStorage.getItem("data"))))
}
//在页面刷新时将vuex里的信息保存到localStorage里
window.addEventListener("beforeunload",()=>{
localStorage.setItem("data",JSON.stringify(this.$store.state))
})
},
vuex–Actions
- Actions进行操作,使用Actions进行异步操作(异步请求)
actions:{
actionfun(context){
//调用mutation中的方法
context.commit("dataup")
}
}
- 分发Action:Action通过 **this.$store.dispatch(‘xxxx’)**方法触发
this.$store.dispatch("actionfun")
vuex --Actions载荷(payload)
- Action同样支持载荷
<button @click="funb(i)">修改2</button>
funb(num){
this.$store.dispatch("act",num)
}
actions:{
act(context,payload){
context.commit("uptwo",payload)
}
}
vuex–Actions总结
- Actions可以理解为通过将mutations里处理数据的方法变成异步的处理数据的方法,简单地说就是异步操作数据(但是还是通过mutations来操作,因为只有他有资格操作)
vuex–modules
- 在Vue中State使用的是单一状态数结构,所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理
- modules:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理
创建文件容纳模块
export let a={
namespaced:true,//命名空间true
state:{
text:"德玛西亚"
},
mutations:{
},
actions:{
}
}
在vuex中引用模块
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
import {a} from "./model/a.js"
export default new Vue.Store({
state:{
},
mutations:{
},
modules:{
a
}
})
使用数据
$store.state.模块名.xxx
<template>
<div class="about">
<h1>This is an about page ----- {{$store.state.a.text}}</h1>
</div>
</template>
<script>
export default{
mounted(){
console.log(this.$store.state.a.text)
}
}
</script>
修改数据
和没有modules的时候一样
add(){
this.$store.commit("add")
}
mutations:{
add(state){
state.text+="aaaa"
}
}