7.从零开始学会Vue--{{Vuex}}

1.基本概念

vuex是什么?

vuex 是vue的状态管理工具,状态即数据

大白话:vuex 是一个插件,可以帮我们管理 vue中通用的数据 (多组件共享的数据)

优势:

① 共同维护一份数据,数据归一化管理

② 响应式变化

③ 操作简洁 (vuex提供了一些辅助函数)

vuex 的使用 - 创建仓库

与vue-router类似,vuex是一个独立存在的插件,如果脚手架初始化没有选 vuex,就需要额外安装。

npm i vuex@3

2 新建 store/index.js 专门存放 vuex

为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。 (和 router/index.js 类似)

// 导入 vue
import Vue from 'vue'
// 导入 vuex
import Vuex from 'vuex'
// vuex也是vue的插件, 需要use一下, 进行插件的安装初始化
Vue.use(Vuex)

// 创建仓库 store
const store = new Vuex.Store()

// 导出仓库
export default store
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  store
}).$mount('#app')
此刻起, 就成功创建了一个 空仓库!!

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式(opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是:

2.state(状态)


通过上面已经准备好了一个空仓库,那么如何给仓库提供数据呢?
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。
在 state 对象中可以添加我们要共享的数据。

共享数据已经准备好了,如何访问它呢
1通过 store 直接访问
2通过辅助函数mapState来访问 (简化)

1. 通过 store 直接访问

2.mapState

mapState是辅助函数,帮助我们把store中的数据映射到 组件的计算属性中, 它属于一种方便的用法
用法 :

import { mapState } from 'vuex'
 computed: {
    ...mapState(['count'])
  }

/*
上面代码等价于
computed: {
    count () {
      return this.$store.state.count
    }
} 
*/
 <div> state的数据:{{ count }}</div>

2.Mutations(同步方法)

核心概念

vuex 建议我们组件中不直接修改仓库的数据,想要修改数据我们统一通过vuex提供的mutations来进行

state数据的修改只能通过 mutations ,并且mutations中必须写同步代码,ajax请求,setTimout等不应该放到mutations中

好处:数据的修改被vuex集中管理,提高对数据管理的有效性

1.通过 commit 提交

const store  = new Vuex.Store({
  state: {
    count: 0
  },
  // 定义mutations
   mutations: {
    // 方法里参数 第一个参数是当前store的state属性(固定写死)
    // 第二个参数count(可以自定义) 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
    addCount (state,count) {
      state.count += count
    }
  },
})
this.$store.commit('addCount',1)

2.mapMutation

mapMutations和mapState很像,它把位于mutations中的方法提取了出来,我们可以将它导入

import  { mapMutations } from 'vuex'
methods: {
    ...mapMutations(['addCount'])
}

/*
  上面代码的含义是将mutations的方法导入了methods中,等价于:
  methods: {
      // commit(方法名, 载荷参数)
      addCount (count) {
          this.$store.commit('addCount',count)
      }
 }
*/ 
<button @click="addCoun(1)">值+1</button>

注意: Vuex中mutations中要求不能写异步代码,如果有异步的ajax请求,setTimout等应该放置在actions中

3.Actions(异步方法)

1.通过dispatch派发

state是存放数据的

mutations是同步更新数据

actions则负责进行异步操,如果有异步的ajax请求,setTimout等应该放置在actions中

需求: 1秒钟之后, 修改 state 的 count 成 520

步骤:

  1. 提供mutations方法

  1. 提供action 方法

  1. 页面中 dispatch 调用

2. 辅助函数 -mapActions

actions也有辅助函数,可以将action导入到组件中

import { mapActions } from 'vuex'
methods: {
    ...mapActions(['setAsyncCount'])
}


/*
 等价于:
 methods: {
  setAsyncCount (n) {
    this.$store.dispatch('setAsyncCount', n)
  },
}

*/ 
<button @click="setAsyncCount(200)">+异步</button>

4.getters(状态处理)

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters

例如,state中定义了list,为1-10的数组

在组件中我们需要显示所有大于5的数据,getters可以帮助我们实现它

步骤:

  1. 定义 getters

  1. 访问getters

① 通过 store 访问 getters

② 通过辅助函数 mapGetters 映射

5.Modules(模块化)

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

1. 模块定义 - 准备 state

定义两个模块 usersetting

user中管理用户的信息状态 userInfo

const state = {
  userInfo: {
    name: 'zs',
    age: 18
  }
}

const mutations = {}

const actions = {}

const getters = {}

export default {
  state,
  mutations,
  actions,
  getters
}

setting中管理项目应用的 主题色 theme,描述 desc

const state = {
  theme: 'dark'
  desc: '描述真呀真不错'
}

const mutations = {}

const actions = {}

const getters = {}

export default {
  state,
  mutations,
  actions,
  getters
}
// 实例化一个仓库
const store = new Vuex.Store({
    modules:{
        setting,
        user
    }
})

使用模块中的数据, 可以直接通过模块名访问 $store.state.模块名.xxx => $store.state.setting.desc,也可以通过 mapState 映射

2. 命名空间 namespaced

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间

这句话的意思是 刚才的 user模块 还是 setting模块,它的 action、mutation 和 getter 其实并没有区分,都可以直接通过全局的方式调用, 如下图所示:

但是,如果我们想保证内部模块的高封闭性,我们可以采用namespaced来进行设置

const state = {
  userInfo: {
    name: 'zs',
    age: 18
  }
}

const mutations = {}

const actions = {}

const getters = {}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
const state = {
  theme: 'dark'
    desc: '描述真呀真不错'
}

const mutations = {}

const actions = {}

const getters = {}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
// 实例化一个仓库
const store = new Vuex.Store({
    modules:{
        setting,
        user
    }
})
全局的:   this.$store.commit('mutation函数名', 参数)

模块中的: this.$store.commit('模块名/mutation函数名', 参数)

使用 namespaced: true 后, 要添加映射, 可以加上模块名, 找对应模块的 state/mutations/actions/getters

computed: {
  // 全局的
  ...mapState(['count']),
  // 模块中的
  ...mapState('user', ['myMsg']),
},
methods: {
  // 全局的
  ...mapMutations(['addCount'])
  // 模块中的
  ...mapMutations('user', ['updateMsg'])
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值