1.基本概念
Vuex 是一个专为 Vue.js 应用程序开发的(数据的)状态管理模式。
Vuex采用“集中式存储管理”方式去管理数据,把 这些数据 应用到 所有组件上 !!!
vuex就是仓库---数据仓库--这个数据仓库里的所有的数据,是为组件来使用的!为组件来服务的!
vuex 只 做 “数据” 的维护!!
对vuex仓库中数据的处理,我们都放在“模型”里面。在vuex这个仓库 store 里面。
2.vuex核心概念
state 存储数据
getters 获取数据的方式
mutations 修改数据的方式
actions 通过后台更改操作异步数据的方式
以上,这几个 都是对象
3.下载和使用
下载
(1)使用script标签引入
直接引用
https://unpkg.com/vuex@3.6.2/dist/vuex.js
下载本地,引用
<script src="/js/vue.js"></script>
<script src="/js/vuex.js"></script>
(2)安装vuex
npm install vuex --save
(3)使用vuex
安装后,在工程化项目中,使用Vuex插件之前需要在main.js入口文件中
a.使用import方式引入Vuex
import Vuex from 'vuex'
b.使用Vuex的插件引入函数Vue.use()使用Vuex
Vue.use(Vuex);
(4)创建数据仓库
创建数据仓库
var store = new Vuex.Store({})
首先来看一下,state的使用
1.先引入插件,在创建好根实例,使用vuex,并创建数据仓库
<script src="./js/vue.js"></script>
<!-- 一定要在vue插件下面引入vuex插件 -->
<script src="./js/vuex.js"></script>
<script>
// 使用Vuex
Vue.use(Vuex)
// 创建数据仓库(存储数据)
let store = new Vuex.Store({})
let vm = new Vue({
el:'#app',
// 引入vuex插件
store,
})
</script>
2.在数据仓库中的state中定义好公共数据
let store = new Vuex.Store({
// state 用来存放数据(类似于组件中的data数据中心)
state:{
zongjia:0,
goods:[
{
id:1,
name:'笔记本',
price:1,
num:10
},
{
id:2,
name:'手机',
price:2,
num:100
},
{
id:3,
name:'平板',
price:10,
num:100
}
]
}
})
3.我们在 计算属性中 使用 this.$store.state.xxx 获取 数据仓库中state中的数据
但是要注意的是:组件 访问数据仓库store 中的公共数据,组件 必须 使用 计算属性 computed
computed:{
// 去仓库中拿总价这条数据
tozongjia(){
return this.$store.state.zongjia
},
// 拿goods数据
goods(){
return this.$store.state.goods
}
}
4.组件 通过 计算属性 computed 拿到 数据仓库 数据,将数据 显示在 该组件的 视图层
<template id="child">
<div>
<h1>我是child子组件</h1>
<hr>
<table border="1" width="600px">
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
</tr>
<tr v-for="(i,index) in goods">
<td>{{i.id}}</td>
<td>{{i.name}}</td>
<td>{{i.price}}</td>
<td>{{i.num}}</td>
</tr>
</table>
<hr>
<p>商品总价为{{tozongjia}}</p>
</div>
</template>
下面接着看 getters的使用
先说一下getters
getters 获取仓库里面的数据
getters 这个是获取仓库里的数据
获取数据的时候,如果 说 你 想在 获取的时候 对数据 进行 计算。
通过 计算 改 state中的数据的状态
(计算---你去做事情,你做的事情,写在哪里?写在方法里,或者 我们说 写在函数里)
(使用getters,它就有逻辑了,它就能思考了。)
getters:{
下面这3种写法 均可。
totalPrice:state=>{
},
totalPrice:function(state){
},
totalPrice(state){
}
}
继续接着上面这个例子,使用getters计算每一件商品的总价
1.先在视图层做些小改动,多出一列来显示单个商品总价:
<table border="1" width="600px">
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>单个商品总价</th>
</tr>
<tr v-for="(i,index) in goods">
<td>{{i.id}}</td>
<td>{{i.name}}</td>
<td>{{i.price}}</td>
<td>{{i.num}}</td>
<td>{{i.jiage}}</td>
</tr>
</table>
2.在数据仓库的goods每一个对象中新添一个 jiage,为每个商品总价:
goods:[
{
id:1,
name:'笔记本',
price:1,
num:10,
jiage:0
},
{
id:2,
name:'手机',
price:2,
num:100,
jiage:0
},
{
id:3,
name:'平板',
price:10,
num:100,
jiage:0
}
]
3.获取数据的时候,如果 说 你 想在 获取的时候 对数据 进行 计算。
getters:{
//如果想对state中的数据进行计算,就需要传参 state
getgoods(state){// 这里等于对state中的goods进行重构了
// 对goods进行遍历
state.goods.forEach((v) =>{
// 商品的单价乘以商品的数量,就等于单个商品总价
v.jiage = v.price*v.num
})
return state.goods
}
}
4.这时候结果是出不来的,因为getters中的方法已经把state中的goods进行了改变,所以:
goods(){
// 所以在这里要拿取的就是被getters重构后的goods了,所以这里的state要改成getters
// 而且后面拿的的也不是goods了,是getters中的方法名
return this.$store.getters.getgoods
}
查看结果:
5.同样的原理,使用getters计算出所有商品总价
getzongjia(state){
let sum = 0;
state.goods.forEach((v) =>{
sum+=v.jiage
})
return sum
}
tozongjia(){
return this.$store.getters.getzongjia
},
下面接着看 mutations的使用
首先看一下this.$store.commit():同步操作,写法:
this.$store.commit('mutations里的方法名',值)
或者
在仓库中的actions里这样写:
store.commit('mutations里的方法名',值)
------------------
mutations 修改仓库里面的数据
mutations 这个是修改仓库里的数据。(同步修改)
我们使用vuex数据仓库中的state和getters 获取数据,但是 现在唯独不能改这里的数据。我们是 用 mutations 改仓库中的数据!
在组件中,想要操作 仓库里面的数据,我们使用commit() “调用” mutations里面的方法
this.$store.commit('mutations里面的方法',值)
例如:
this.$store.commit('del',{id})
'del'---第一个参数 是 仓库里 mutations里面的 方法
{id} ---第二个参数 是 传递给 仓库里mutations方法里的 参数
----------
1.在这里继续接着上面这个例子,在每一项后面添加一个删除按钮,当点击时,删除对应的那一项
<!-- 添加删除按钮,并传入参数id -->
<td>
<button @click="del(i.id)">删除</button>
</td>
2.数据时组件child通过数据仓库获取的,所以在child组件的方法中心写上方法
methods:{
del(id){
// 当你点击按钮时,获取到的id值,通过commit()方法,把id的值,传递给mutations中的del方法去使用
this.$store.commit('del', id)
}
}
3.在数据仓库的mutations中,接收参数,并添加方法
mutations:{
// 删除购物车中的商品
//state---第一个参数,是仓库中的state
//param---第二个参数,是你(组件) 传递过来 的参数id
del(state,param){//注意,第一个参数必须要有
// 定义一个空变量
let k;
state.goods.forEach((v,index) =>{
// 在遍历的过程中,当前这项的id等于传入的id时
if(v.id == param){
// 把当前的索引值赋值给k
k = index
}
})
// k有了值以后,从第k个开始,删除1个
state.goods.splice(k,1)
}
}