Vuex是什么?
介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
理解:核心就是 store(仓库),仓库是用来干什么的?你就当它用来储存东西的。
看个官网图片:
state:存储数据和状态。
mutatins:通俗的理解mutations,里面装着一些改变数据方法的集合,这是Veux设计很重要的一点,就是把处理数据逻辑方法全部放在mutations里面,使得数据和视图分离。切记:Vuex中store数据改变的唯一方法就是mutation!
action:在mutation中我们讲到,mutation中是存放处理数据的方法的集合,我们使用的时候需要commit。但是commit是同步函数,而且只能是同步执行。那我们想异步操作怎么办?
作用:在actions中提交mutation,并且可以包含任何的异步操作。actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据(但是还是通过mutation来操作,因为只有它能操作)
下面说一下具体安装方法
但首先你得有一个脚手架,具体安装方法请参考Vue——安装@vue/cli(Vue脚手架)的三种方式
一、可以直接使用vue-ui 进行下载插件vuex
安装完毕后会发现文件中多了一个store文件夹,里面有个index.js文件
store/index.js中应该有以下代码:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations:{ }, getter:{ }, actions: { }, modules: { } })
接下来在main.js中引入配置
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'; Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')
引入后就可以使用vuex了
二、使用npm安装vuex
npm install vuex --save
三、yarn安装
yarn add vuex
安装完毕后不会自动生成store文件夹以及里面的文件,这时要自己去新建并且书写里面的配置项
可以package.json中查看是否安装成功vuex
下面来看一下vuex的五个核心:
vuex的五大核心
也就是store文件夹下的index.js中的五个状态
state、mutaions、getter、actions、modules
1.、state:vuex的基本数据,用来存储变量
在vue中使用
$store.state.(state中数据的名称)
state方法是写在计算属性(computed)里的
2、mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
在vue中使用
$store.commit('')
mutation方法是写在methods里的
3、 geeter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法
我们可以认为,【getters】是store的计算属性。getters方法是写在计算属性(computed)里的
4. action:和mutation的功能大致相同,不同之处在于 Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。
5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面。
使用state显示数据的四种方法
index.部分
state: { count:5 },
app.vue部分 如下:
第一种:
<h1>{{ $store.state.count }}</h1>
第二种:
<h2>{{ vcount }}</h2> computed: { vcount() { return this.$store.state.count } }
第三种:
<h3>{{ count }}</h3>
mapState辅助函数
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键。
接下来引入辅助函数:
import { mapState} from "vuex"; computed:{ ...mapState(["count"]), }
第四种:
<h4>{{ count }}</h4> computed:{ ...mapState({ count: (state) => state.count, }), }
效果如下:
使用mutation状态写出加减计数器
index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count:5 }, mutations: { add(state){ state.count++ }, sub(state){ state.count-- } }, })
app.vue部分 如下:
第一种:
<h1>{{ $store.state.count }}</h1> <button @click="vadd">+</button> <button @click="vsub">-</button> methods:{ vadd() { this.$store.commit("add"); }, vsub() { this.$store.commit("sub"); }, }
第二种:
<h2>{{ vcount }}</h2> <button @click="$store.commit('add')">+</button> <button @click="$store.commit('sub')">-</button> computed: { vcount() { return this.$store.state.count; }, }
第三种:
<h3>{{ count }}</h3> <button @click="add">+</button> <button @click="sub">-</button>
mapMutations 辅助函数
与其他辅助函数类似,你可以在组件中使用 this.$store.commit(‘xxx’) 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)
引入辅助函数: mapMutations
import { mapState ,mapMutations } from "vuex"; methods:{ ...mapMutations(['add', 'sub']) }
第四种:
<h4>{{ count }}</h4> <button @click="sadd">+</button> <button @click="ssub">-</button> methods:{ ...mapMutations({ sadd: "add", ssub: "sub", }), }
第五种01 点击增加5或者10甚至其他值 通过传参
//index.js部分 inc(state,n){ console.log(n); state.count += n },
app.vue部分
<button @click="inc(5)">+5</button> <button @click="inc(10)">+10</button> methods:{ ...mapMutations(['inc']) }
也可以这样写:
<button @click="Inc2(5)">+5</button> <button @click="Inc2(10)">+10</button> methods:{ ...mapMutations({ Inc2: "inc", }), }
第六种 通过preload载荷形式
mutations的载荷
把值传递给Mutations 给store.commit传一个附加参数,就叫做mutation的载荷
index.js部分:
// index.js 部分 // 第二个参数是载荷的方式,比如一个对象,一个数组,字符串等都可 incrementcount(state,preload){ console.log(preload); state.count += preload.count }
app.vue部分
<h2>{{count}}</h2> <button @click="counter(5)">+5</button> <button @click="counter(10)">+10</button> counter(count) { this.$store.commit({ type: 'incrementcount', count }) }
显示效果如下:
对数组中的对象进行添加的两种写法:
// index.js部分 export default new Vuex.Store({ state: { record:[ {id:100,name:'Nanchen',age:23}, {id:101,name:'JiuAn',age:30}, {id:102,name:'NanXi',age:50}, {id:103,name:'QiuYun',age:28}, ] }, mutations:{ add(state,preload){ state.record.push(preload) } }
app.vue部分
<p>{{ record }}</p> <button @click="add(home)">添加一组</button> data() { return { home:{ id:250, name:'Nanchen66', age:80 }, }; } methods: { ...mapMutations(['add']) , }, computed: { ...mapState(['record']), },
第二种写法:
app.vue部分
//index.js mutations: { addrecord(state,preload){ state.record.push(preload) } }, <h3>{{record}}</h3> <button @click="sadd()">添加+</button> methods: { sadd() { const home = { id: 114, name: 'xuqi', age: 35 } this.$store.commit('addrecord',home) } }, computed: { ...mapState(['record']), },
效果如下:
getters
index.js
重新弄一份对象中的数组
list: [{ id: 1, name: "商品一", status: false }, { id: 2, name: "商品二", status: true }, { id: 3, name: "商品三", status: false }, { id: 4, name: "商品四", status: true }, { id: 5, name: "商品五", status: false } ] getters:{ activeList(state){ return state.record.filter(v=>{ return v.status }) }, },
这里要筛选出带有status值为true的对象
app.vue部分
第一种写法:
<h1>{{$store.getters.activeList}}</h1>
第二种写法:
<h2>{{list}}</h2> computed:{ list(){ return this.$store.getters.activeList }, }
第三种写法:
使用辅助函数mapGetters
mapGetters辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
app.vue部分
import {mapGetters } from "vuex"; <!-- 第三种方法使用辅助函数 --> <h3>{{activeList}}</h3> computed:{ ...mapGetters(['activeList']), }
第四种写法:
<!-- 第四种方法 --> <h4>{{list}}</h4> computed:{ ...mapGetters({ list:'activeList' }) }
效果如下所示:(记得把之前的给注释掉以免被干扰)
下面是筛选ID大于3的数据(因为上面的代码影响所以也只会执行status为true并且ID大于3的数据)
index.js部分
getters:{ getList:(state,getters)=>{ return getters.activeList.filter(v=>{ return v.id >3 }) } }
app.vue部分
<h4>{{getList}}</h4>
直接在第四种方法后写入:
getList:'getList'
运行结果如下:
筛选只需要ID为3的数据
index.js部分
getters:{ getById:function(state){ return function(id){ return state.list.filter(function(v){ return v.id === id }) } } }
app.vue部分
<h4>{{getById(3)}}</h4>
再在第四种方法后写入:
getById:'getById'
效果如下: