vuex的使用

Vuex的快速入门

快速开始_

安装依赖

"vuex": "3.6.0"

在store下添加index.js,然后再main.js引入

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
    // 定义共享变量,所有页面都可以访问到,类似于data
    state: {
    },
    // 定义同步方法
    mutations: {
    },
    // 定义异步方法
    actions: {},
    // 计算属性,可以过滤;返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
    getters: {
    },
    // 模块化
    modules: {}
})

export default store

main.js

import Vue from 'vue'
import App from './App.vue'

import store from './store/index'

new Vue({
    store,
    render: h => h(App),
}).$mount('#app')

state

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        name: '张三',
        age: 18,
    }
})

export default store

取值方式一

子组件通过 this.$store.state 获取

<template>
  <div>
    <!--直接通过this.$store.state获取变量 -->
    {{ this.$store.state.name }}
  </div>
</template>

<script>
export default {
  mounted() {
    //在js中直接通过this.$store.state.name获取
    console.log(this.$store.state.name)
  },
}
</script>

取值方式二

当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

<template>
  <div>
    <!--通过mapState辅助函数获取-->
    {{ age }}
  </div>
</template>

<script>
import {mapState} from 'vuex'

export default {
  computed: {
    ...mapState(['age'])
  },
}
</script>

getter

有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表数据进行过滤,对名字进行二次加工等。

如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        name: '张三',
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    },
    getters: {
        addHello(state) {
            return state.name + " 你好";
        },
        filter8(state) {
            return state.list.filter(item => item !== 8)
        }
    },
})

export default store

展示

<!--方式一-->
<template>
  <div>
    {{ this.$store.getters.addHello }}
    {{ this.$store.getters.filter8 }}
  </div>
</template>

<script>
export default {}
</script>

<!--方式二mapGetters 辅助函数-->
<template>
  <div>
      <!-- 名字二次加工-->
      {{ addHello }}
      <!-- 对数据进行过滤-->
      {{filter8}}
  </div>
</template>

<script>
import {mapGetters, mapState} from 'vuex'
export default {
  computed: {
    ...mapGetters(['addHello','filter8'])
  },
}
</script>

mutations

  • mutation是更改store 中的状态的唯一方法

  • mutation 必须是同步函数

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        age: 18,
    },
    mutations: {
        //无参方法,调用
        addAge(state) {
            state.age += 5
        }
    },
})

export default store

展示

方式一
<template>
  <div>
    {{this.$store.state.age}} <br/>
    <el-button @click="addAge1">无参点击+5</el-button>
    <el-button @click="addAge2">有参点击+n</el-button>
  </div>
</template>

<script>
export default {
  methods: {
    addAge1() {
      this.$store.commit('addAge')
    },
    addAge2() {
      this.$store.commit('addAgeN',2)
    }
  }
}
</script>

方式二
<template>
  <div>
    {{ this.$store.state.age }} <br/>
    <el-button @click="addAge">无参点击+5</el-button>
    <el-button @click="addAgeN(2)">有参点击+n</el-button>
  </div>
</template>

<script>
import {mapMutations} from 'vuex'

export default {
  methods: {
    ...mapMutations(['addAge', 'addAgeN'])
  }
}
</script>

actions

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
   
    state: {
        age: 18,
    },

    mutations: {
        //无参方法
        addAge(state) {
            state.age += 5
        },
        //有参方法
        addAgeN(state, n) {
            state.age += n
        }
    },
    actions: {
       addAge(context) {
            context.commit('addAge')
        },
        addAgeN(context, n) {
            context.commit('addAgeN', n)
        },
        //定义一个异步方法,3s过后才调用addAge(mutations)方法
        addAgeAsync({commit}) {
            setTimeout(() => {
                commit('addAge')
            }, 3000)
        },
        addAgeNAsync({commit}, n) {
            setTimeout(() => {
                commit('addAgeN', n)
            }, 3000)
        },
        addAgeNAsync2(context, n) {
            setTimeout(() => {
                context.commit('addAgeN', n)
            }, 3000)
        }
    },
})

export default store

展示

<template>
  <div>
    {{ this.$store.state.age }} <br/>
    <span> 方法1</span>
    <el-button @click="addAge1">无参点击+5</el-button>
    <el-button @click="addAge2">有参点击+n</el-button>
    <span>方法2</span>
    <el-button @click="addAge">无参点击+5</el-button>
    <el-button @click="addAgeN(2)">有参点击+n</el-button>
    <el-button @click="addAgeAsync()">异步(3s后执行)无参方法+5</el-button>
    <el-button @click="addAgeNAsync(10)">异步(3s后执行)有参方法+10</el-button>
  </div>
</template>

<script>
import {mapActions} from 'vuex'

export default {
  methods: {
    //方法1
    addAge1() {
      this.$store.dispatch('addAge')
    },
    addAge2() {
      this.$store.dispatch('addAgeN', 2)
    },
    //方法2
    ...mapActions(['addAge', 'addAgeN', 'addAgeAsync', 'addAgeNAsync'])
  }
}
</script>

modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
    // 模块化
    modules: {
        app,
    },
    getters
})

export default store

store/modules/app.js

//定义变量
const state = {
    app: 'app'
}
//定义同步方法,唯一更改state的地方
const mutations = {}
//定义异步方法
const actions = {}
export default {
    state,
    mutations,
    actions
}

例子

<template>
  <div>
    <!--直接通过state获取变量 -->
    {{ this.$store.state.app.name }}
    {{ this.$store.state.app.age }}

    <el-button @click="addAge1">调用方式一+5</el-button>
    <el-button @click="addAge">调用方式二+5</el-button>
  </div>
</template>

<script>
import { mapMutations} from 'vuex'

export default {
  name: "vuex",
  methods: {
    addAge1() {
      this.$store.commit('addAge')
    },
    ...mapMutations(['addAge'])
  }
}
</script>

命名空间

例子

const state = {
    name: '张三',
    age: 18
}
const mutations = {
    addAge(state) {
        state.age += 5
    },
}
const actions = {}
export default {
    //名字空间,防止不同模块方法名和变量名重复,后面访问变量方法都是带上模块前缀;如:this.$store.state.app.name 会加上app
    namespaced: true,
    
    state,
    mutations,
    actions
}
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
    // 模块化
    modules: {
        app,  //如:this.$store.state.app.name 会加上app,是这个app
    },
    getters
})

export default store


------来自 NPException对我的爱,我是爱乱写的嵩鼠

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值