vue_使用vuex

vuex其实就是一个观察者模式

  1. 可以在Vue实例绑定一个全局的属性,this.$myStore 来创建一个仓库存储数据,只是不是响应式的
  2. this.$root 可以访问Vue根实例,和上一点差不多,绑定一个全局仓库
  3. 使用Vue的bus总线机制,原理就是在Vue原型上创建一个vue实例,Vue.prototype.$bus = new Vue(),练习小demo可以使用

vuex 使用

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果项目很小,可以不使用vuex
每一个Vuex应用的核心就是store(仓库), “store”基本上就是一个容器,它包含着你的应用中大部分的状态(state)。

这个状态自管理应用包含以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

Vuex和单纯的全局对象有以下两点不同:

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。

Vuex安装

$ npm install vuex --save

Vuex配置

在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex// 创建一个仓库 src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Stroe({
  state: {
    count:'',
    ....
  },
  actions: {
    ....
  },
  mutations: {
    ...
  }
})
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到
// main.js
import store from './store'
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

vuex state

通过在根实例中注册store选项后,子组件可以通过this.$store.state.count访问到该状态
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。

// 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,
import { mapState } from 'vuex'  
// 解构赋值,相当于mapState = vuex.mapState
// 注意: mapState名字不能随便取,因为随便取的话,vuex对象下没有这个方法
export default {
  computed: {
    otherComputed () {/* do something... */ },

    // 将this.count 映射为 this.$store.state.count
    // 将this.city 映射为 this.$store.state.city
    ...mapState(['count'], ['city']),    

    // 也可以接收一个对象, 
    // 将this.currentCount 映射为 this.$store.state.count
    // 将this.currentCity 映射为 this.$store.state.city
    ...mapState({currentCount: 'count', currentCity: 'city'}),
  }
}

vuex Mutations

// 更改 Vuex 的 store 中的状态(state)的唯一方法是提交 mutation。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
// store/index.js
export default new Vuex.Stroe({
  state: {
    count: 0,
  },
  actions: {
  },
  mutations: {
    increment (state, value) {
      state.count = value 
    },
    decrement (state, obj) {
      state.count = obj.count--
    }
  }
})
// 在组件中提交Mutations
  - 可以使用this.$store.commit('increment', 10)方法,第二个参数作为要改变的值,也可以是一个对象
  - 对象风格的提交方式, this.$store.commit({type: 'decrement', count: 10})
      type属性指定调用mutations对象的方法, 其他属性作为该方法的第二参数的属性

// 使用mapMutations辅助函数提交Mutations
import { mapMutations, mapState } from 'vuex' // 也可以同时引用
export default {,
  name: '',
  data () {/* do something.... */},
  computed: {...mapState(['count'])},
  methods: {
    otherMethods () {/* do something.... */},
    handleIncrementClick () {
      this.increment(this.count)
      this.incr(this.count)
    },
    handleDecrementClick () {
      this.decrement(this.count)
      this.decr(this.count)
    },

    // 将this.increment()映射为 this.$store.commit('increment')
    // 将this.decrement()映射为 this.$store.commit('decrement')
    ...mapMutations(['increment', 'decrement']),
    
    // 对象提交方式
    // 将this.incr()映射为 this.$store.commit('increment')
    // 将this.decr()映射为 this.$store.commit('decrement')
    ...mapMutations({incr: 'increment', decr: 'decrement'})
  }
}
// Vuex 的 store 中的状态是响应式的,当我们变更状态时,监视状态的 Vue 组件也会自动更新。
// Mutation 必须是同步函数,一条重要的原则就是要记住 mutation 必须是同步函数

vuex actions

在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你调用了两个包含异步回调的 mutation 来改变状态,你怎么知道什么时候回调和哪个先回调呢?这就是为什么我们要区分这两个概念。
Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,
因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

// store/index.js
export default new Vuex.Stroe({
  state: {
    count: 0,
  },
  actions: {
    increment (context) {
      context.commit('increment', context.count)
    },
    // 异步操作
    decrementAsync ({ commit }, obj) {
      setTimeout(() => {
        // 结构赋值, 这里的 commit === commit.commit 
        // 这里commit保存的是context上下文对象,而他有一个方法叫commit,es6语法键值对都名字一样可以简写
        commit('decrement', obj)
      }, 1000);
    }
  },
  mutations: {
    increment (state, value) {
      state.count = value 
    },
    decrement (state, obj) {
      state.count = obj.count--
    }
  }
})
// 在组件中分发action
  - 可以使用this.$store.dispatch('increment')
  - 或者this.$store.dispatch('decrementAsync', {count: 10}) // 传参对象提交

// 使用mapActions辅助函数
import { mapActions } from 'vuex'
export default {
  //....
  methods: {
    otherMethods () {/* do something... */},
    
    handleIncrementClick () {
      this.increment()
      this.incr()
    },
    handleDecrementAsyncClick () {
      this.decrementAsync({count: 10})
      this.decr({count: 10})
    },
    // 将 this.increment() 映射为 this.$store.dispatch('increment')
    // 将 this.decrementAsync() 映射为 this.$store.dispatch('decrementAsync')
    ...mapActions(['increment', 'decrementAsync']),
    
    // 对象提交方式
    // 将 this.incr() 映射为 this.$store.dispatch('increment')
    // 将 this.decr() 映射为 this.$store.dispatch('decrementAsync')
    ...mapActions({incr: 'increment', decr: 'decrementAsync'})
  }
}
posted @   前端之旅  阅读(204)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示