Vuex
1. 什么是vuex
- Vuex 是一个专为 Vue.js 应用程序开发中管理的一个模式。
- 通过创建一个集中的数据存储,方便程序中的所有组件进行访问
传统Vue使用场景
思考
- 传统vue是单向数据流。如果是兄弟组件之间传值兄弟组件间的状态传递无能为力
- 我们经常会采用父子组件通过正向/逆向传值来对数据进行传递。以上的这些模式非常脆弱,通常会导致无法维护的代码。
- vuex只能用于单个页面中不同组件(例如兄弟组件)的数据流通。
2. 安装vuex
- npm install vuex --save
- 配置vuex文件创建在src中创建store文件夹–>与store.js
3. 单一状态树
- Vuex 使用单一状态——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 ”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
- 创建store实例:
import Vue from 'vue'
import Vuex from 'vuex'
//在vue中使用vuex
Vue.use(Vuex);
// 需要让外部使用的实例化的store对象export,就是到处的意思
export let store=new Vuex.store({
})
4. vuex–State数据源
vuex中的数据源state,我们需要保存的数据就保存在这里
import Vue from 'vue'
import Vuex from 'vuex'
// 在vue中使用vuex
Vue.use(Vuex);
// 需要让外部使用的实例化的store对象export,就是到处的意思
export let store=new Vuex.Store({
//数据源
state:{
arr:["1","2","3","4","5"],
obj:[
{id:1,name:"mgd1",age:11},
{id:2,name:"mgd2",age:12},
{id:3,name:"mgd2",age:13},
{id:4,name:"mgd4",age:14},
{id:5,name:"mgd5",age:15},
{id:6,name:"mgd6",age:16},
{id:7,name:"mgd7",age:17}
],
text:"我是默认值"
},
})
5. vuex–使用数据源
- 要使用首先在main.js引入vuex。
- 一对大括号的原因是,指定要从其他模块导入的变量名。
main.js:
//引用vuex的store内容
import {store} from './store/store'
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
store
})
- 在需要使用数据的组件中使用计算属性调用
this.$store.state.xxx
//获取vuex中state数据源中的数据,使用计算属性来获取
computed: {
stateobj(){
return this.$store.state.obj;//从vuex中state拿去值的名字
}
}
6. vuex–state扩展知识点
- Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
7. Geeters
- vuex–Getters属性
- getters相当于之前组件中学习的计算属性,getters属性主要是对于state中数据的一种过滤
- ==使用场景:==在项目开发中,有时候希望对state中的某个属性在多个组件中展示出不同状态
//由于getter是store对象当中的一个属性,所以写的位置与state同级
//可以理解为vuex中的计算属性====》不同组件对同一个数据去不同值的时候进行数据的处理
getters:{
// 生成的新变量名(state就是state这个属性){
// return 数据
// }
// 取出大于三的数据
obja(state){
var newobja=state.obj.filter((v,i)=>{
if(v.id>3){
return v
}
})
return newobja
},
//取出小于等于三的数据
objb(state){
var newobjb=state.obj.filter((v,i)=>{
if(v.id<=3){
return v
}
})
return newobjb
}
}
- 与使用state相同在组件中的计算属性当中使用this.$store.getters.xxx来进行调用
<template>
<div>
<h1>取出id大于3的数据</h1>
<p>{{obja}}</p>
<h1>取出id小于等于3的数据</h1>
<p>{{objb}}</p>
</div>
</template>
<script>
export default {
//获取getter中的数据的时候也是通过计算属性得到的
computed:{
obja(){
return this.$store.getters.obja;
},
objb(){
return this.$store.getters.objb;
}
}
}
</script>
7.1vuex–Getters扩展知识点
vuex的Getter特性是?
- getters 可以对State进行计算操作,它就是Store的计算属性
- 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
- 如果一个状态只在一个组件内使用,是可以不用getters
8. Mutations
- mutations,里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在mutations里面(当触发事件的时候想改变state数据的时候使用mutations)
// mutations 修改state的数据的时候使用
mutations:{
add(state,payload){
state.obj[1].name=payload;
},
addb(state){
state.obj.forEach((v,i)=>{
v.age++;
})
},
addc(state,payload){
state.obj[2].name=payload;
},
// 6.创建mutitons来进行修改
inputmutitions(state,payload){
state.text=payload;
},
// axios请求数据过程第2步
axiosmutitions(state,payload){
state.text=payload;
}
},
- 注意:不能直接调用一个 mutations 中的处理函数 要使用this.$store.commit() 来进行调用。
methods:{
fun(){
this.$store.commit("add");
},
funb(){
this.$store.commit("addb")
},
func(text){
// 把这个形参的数据传递给mutations
this.$store.commit("addc",text);
}
}
8.1 提交载荷(Payload)
- 之前的只是一个简单的修改state中的属性
- 在实际项目中往往会有值传递给Mutations 给store.commit传一个附加参数,他就叫做mutation的载荷
代码见上 - 多个参数也可以传递一个对象
- this.$store.commit(‘add’, { ‘num’: 20 } )
9. Actions
- Actions 类似于 mutation,但是Actions 提交的是 mutation,而不是直接变更状态。Actions 可以异步操作。
// 创建actions来进行异步的修改state数据
actions:{
actionsfun(storeobj,payload){
storeobj.commit("add",payload)
}
}
- 分发 Action:Action 通过 this.$store.dispatch(“xxxx”);方法触发
this.$store.dispatch("actionsfun",text)
9.1 Actions 载荷(Payload)
Action同样支持载荷
<button @click="fun('你好呵呵哒')">点我异步的进行数据的修改</button>
fun(text){
// 需要异步的修改state中的数据 那么就不能直接调用mutitions他是同步的
// 需要先调用actions 在其中 调用mutitons
// 调用actions
this.$store.dispatch("actionsfun",text)
}
actionsfun(storeobj,payload){
storeobj.commit("add",payload)
},
// 创建actions来进行异步的修改state数据
actions:{
actionsfun(storeobj,payload){
storeobj.commit("add",payload)
},
// 5.创建actions进行异步的修改操作
inputactions(storeobj,payload){
storeobj.commit("inputmutitions",payload)
},
// axios请求数据过程第一步
axiosactions(storeobj){
axios({
url:"/chuichui",
method:"get"
}).then((ok)=>{
// 把请求过来的数据传递给mutitons
storeobj.commit("axiosmutitions",ok)
})
}
}
<template>
<div>
<h1>原始数据</h1>
<p>{{obj}}</p>
<h1>使用actions异步的来进行修改数据</h1>
<button @click="fun('你好呵呵哒')">点我异步的进行数据的修改</button>
</div>
</template>
<script>
export default {
methods:{
fun(text){
// 需要异步的修改state中的数据 那么就不能直接调用mutitions他是同步的
// 需要先调用actions 在其中 调用mutitons
// 调用actions
this.$store.dispatch("actionsfun",text)
}
},
computed:{
obj(){
return this.$store.state.obj
}
}
}
</script>
9.2 Actions总结
Actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据(但是还是通过mutation来操作,因为只有它能操作)
10. 严格模式
- 严格模式下,无论何时发生了==状态变更且不是由 mutation 函数引起的,将会抛出错误。==这能保证所有的状态变更都能被调试工具跟踪到。
- 开启严格模式,仅需在创建 store 的时候传入 strict: true
const store=new Store({
strict:true
})
不要在发布环境下启用严格模式!!!
11. 表单处理
当在严格模式中使用 Vuex 时,在属于 Vuex 的 state 上使用 v-model 会比较棘手。在用户输入时,v-model 会试图直接修改 state数据。在严格模式中,由于这个修改不是在 mutation 函数中执行的, 这里会抛出一个错误。
11.1 表单处理解决方式
- Vuex 的思维解决,给 < input> 中绑定 value,然后侦听 input 或者 change 事件,在事件回调中调用 action。
<input type="text" :value="objtext" @input="fun">
- 调用函数。
methods:{
// 4.创建函数调用异步的actions并且把输入框的内容传递给actions
fun(e){
this.$store.dispatch("inputactions",e.target.value);
}
}
案例:
<template>
<div>
<h1>在vuex中必须通过mutitions来操作数据的修改所以在表单修改state数据就比较麻烦</h1>
<p>{{objtext}}</p>
<!-- 2.把拿过来的数据使用v-bind:value属性 -->
<!-- 3.要修改state的数据必须通过mutition来修该所以当用户输入内容的时候触发一个函数 -->
<input type="text" :value="objtext" @input="fun">
</div>
</template>
<script>
export default {
computed:{
// 1.把state中的数据拿过来
objtext(){
return this.$store.state.text;
}
},
methods:{
// 4.创建函数调用异步的actions并且把输入框的内容传递给actions
fun(e){
this.$store.dispatch("inputactions",e.target.value);
}
}
}
</script>
- 创建actions调用mutations并接收数据
- 使用mutations来进行修改
12. 使用 axios 请求数据
12.1 axios 请求环境配置
- npm install --save axios 下载axios
- 在src文件加下的main.js中添加
import axios from 'axios'
Vue.prototype.axios = axios
- 实现网络请求
4. 综合交互post get请求
- this.axios(utl:‘请求地址’,method:‘请求方式’,data/params:{k:v}).then((ok)=>{})
- 使用get发送数据的时候 使用params:{key:val}发送数据
- 使用post发送数据需要使用 var param=new URLSearchParams();修改传参方法
- 使用param.append(“uname”,“xixi”)添加数据并且使用data发送数据
- vuex—axios 请求环境配置
- 在store文件中引用axios import axios from ‘axios’
- 通过事件触发active
<template>
<div>
<p> {{text}}</p>
<button @click="fun()">点我发送axios</button>
</div>
</template>
<script>
export default {
computed:{
text(){
return this.$store.state.text;
}
},
methods:{
fun(){
this.$store.dispatch("axiosactions")
}
}
}
</script>
- 创建actions 并进行异步请求,并且调用Mutations修改state数据
// axios请求数据过程第一步
axiosactions(storeobj){
axios({
url:"/chuichui",
method:"get"
}).then((ok)=>{
// 把请求过来的数据传递给mutitons
storeobj.commit("axiosmutitions",ok)
})
}
state:{
link:[],
}
linkupdate(state,payload){
state.link=payloads
}