Vue笔记(十六) vuex

vuex 理解

vuex 是什么

1) github 站点: https://github.com/vuejs/vuex
2) 在线文档: https://vuex.vuejs.org/zh-cn/
3) 简单来说: 对 vue 应用中多个组件的共享状态进行集中式的管理(读/写)

状态自管理应用

1) state: 驱动应用的数据源
2) view: 以声明方式将 state 映射到视图
3) actions: 响应在 view 上的用户输入导致的状态变化(包含 n 个更新状态的方法)

 

多组件共享状态的问题

1) 多个视图依赖于同一状态
2) 来自不同视图的行为需要变更同一状态
3) 以前的解决办法
a. 将数据以及操作数据的行为都定义在父组件
b. 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
4) vuex 就是用来解决这个问题的

 

vuex 核心概念和 API

state

1) vuex 管理的状态对象
2) 它应该是唯一的
const state = {
 xxx: initValue
}

mutations

1) 包含多个直接更新 state 的方法(回调函数)的对象
2) 谁来触发: action 中的 commit('mutation 名称')
3) 只能包含同步的代码, 不能写异步代码
const mutations = {
 yyy (state, {data1})
 {
 // 更新 state 的某个属性
 }
}

actions

1) 包含多个事件回调函数的对象
2) 通过执行: commit()来触发 mutation 的调用, 间接更新 state
3) 谁来触发: 组件中: $store.dispatch('action 名称', data1) // 'zzz'
4) 可以包含异步代码(定时器, ajax)
const actions = {
    zzz ({commit, state}, data1){
    commit(
        'yyy', {data1}
    )
  }
}

getters

1) 包含多个计算属性(get)的对象
2) 谁来读取: 组件中: $store.getters.xxx
const getters = {
    mmm (state) {
        return ...
    }
}

modules

1) 包含多个 module
2) 一个 module 是一个 store 的配置对象
3) 与一个组件(包含有共享数据)对应

向外暴露 store 对象

export default new Vuex.Store({
state,
mutations,
actions,
getters
})

组件中

import {mapState, mapGetters, mapActions} from 'vuex'
export default {
computed: {
 ...mapState(['xxx']),
 ...mapGetters(['mmm']),
}
methods: mapActions(['zzz'])
}

{{xxx}} {{mmm}} @click="zzz(data)"

映射 store
import store from './store'
new Vue({
    store
})

store 对象

1) 所有用 vuex 管理的组件中都多了一个属性$store, 它就是一个 store 对象
2) 属性: state: 注册的 state 对象 getters: 注册的 getters 对象
3) 方法: dispatch(actionName, data): 分发调用 action

实际案例

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
/*state 对象 类似于 data */
const state = {
  count: 0
  // 初始化状态数据
}
/*
mutations 对象包含个方法: 
能直接更新 state 一个方法就是一个 mutation mutation 
只能包含更新 state 的同步代码, 也不会有逻辑 
mutation 由 action 触发调用: commit('mutationName') 
*/
const mutations = {
  INCREMENT(state) {
    state.count++
  },
  DECREMENT(state) {
    // ctrl + shift + x 
    state.count--
  }
}
/*
actions 对象 包含个方法: 触发 mutation 调用, 
间接更新 state 一个方法就是一个 action action 
中可以有逻辑代码和异步代码 action 由组件来触发调用: 
this.$store.dispatch('actionName') 
*/
const actions = {
  increment({
    commit
  }) {
    commit('INCREMENT')
  },
  decrement({
    commit
  }) {
    commit('DECREMENT')
  },
  incrementIfOdd({
    commit,
    state
  }) {
    if (state.count % 2 === 1) {
      commit('INCREMENT')
    }
  },
  incrementAsync({
    commit
  }) {
    setTimeout(() => {
      commit('INCREMENT')
    }, 1000)
  }
}
/*getters 对象 包含多个 get 计算计算属性方法 */
const getters = {
  oddOrEven(state) {
    return state.count % 2 === 0 ? '偶数' : '奇数'
  },
  count(state) {
    return state.count
  }
}
// 向外暴露 store 实例对象 
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

main.js

import Vue from 'vue'
import app from './app.vue'

import store from './store'
// 创建 vue 配置路由器 
new Vue({
  el: '#app',
  store,
  render: h => h(app)
})

app.vue(未优化前)

<template>
  <div>
    <p>clicked: {{$store.state.count}} times, count is {{oddOrEven}}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">increment if odd</button>
    <button @click="incrementAsync">increment async</button>
  </div>
</template> <script>
export default {
  computed: {
    oddOrEven() {
      return this.$store.getters.oddOrEven;
    }
  },
  methods: {
    increment() {
      this.$store.dispatch("increment");
    },
    decrement() {
      this.$store.dispatch("decrement");
    },
    incrementIfOdd() {
      this.$store.dispatch("incrementIfOdd");
    },
    incrementAsync() {
      this.$store.dispatch("incrementAsync");
    }
  }
};
</script> <style>
</style>

 app2.vue(优化后)

<template>
  <div>
    <p>clicked: {{count}} times, count is {{oddOrEven2}}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">increment if odd</button>
    <button @click="incrementAsync">increment async</button>
  </div>
</template> <script>
import { mapGetters, mapActions } from "vuex";
export default {
  computed: mapGetters({
    // 名称不一样
    oddOrEven2: "oddOrEven",
    count: "count"
  }),
  methods: mapActions([
    "increment",
    "decrement",
    "incrementIfOdd",
    "incrementAsync"
  ]) // 名称一样
};
</script> 
  <style>
</style>
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值