vue、vuex状态管理、vuex的核心概念state状态

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

vuex初步使用

1、安装vuex

口诀:“233”、“344”

数字分别对应,“vue版本,vue 路由版本、vuex 版本”。

所以这里了使用vuex3版本:

yarn add vuex@3

 

 2、创建仓库文件

 编写如下:

// 这个文件用于存放vuex的核心代码
import Vue from 'vue'
import Vuex from 'vuex'

// 插件安装
Vue.use(Vuex)

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

// 导出仓库,把仓库丢到main.js
export default store

 3、在main.js中导入

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/store/index'

Vue.config.productionTip = false

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

 4、验证仓库是否被创建成功

    created () {
      console.log('222222')
      console.log(this.$store)
    },

控制台打印:

这个对象就是我们的仓库了



使用state仓库的数据

state是vuex的核心。

状态目标:明确如何给仓库提供数据。

如何使用仓库的数据?方式有两种:

1、通过store直接访问

步骤1:提供数据State

提供唯一的公共数据源,所有共享的数据都要统一放到 Store中的 State中存储。在 state对象中可以添加我们要共享的数据。

步骤2:获取数据:

示例:

1、在我们的vuex仓库中添加共享的数据

// 这个文件用于存放vuex的核心代码
import Vue from 'vue'
import Vuex from 'vuex'

// 插件安装
Vue.use(Vuex)

// 创建仓库
const store = new Vuex.Store({
  // 通过提供数据,这些数据被所有的组件共享
  state: {
    title: '公共的标题',
    count: 100
  }
})

// 导出仓库,把仓库丢到main.js
export default store

2、在我们的页面中获取数据

  <h1>{{ $store.state.title }}</h1>

2、通过辅助函数访问

简化mapstate是辅助函数,帮助我们把 store中的数据自动映射到组件的计算属性中。

 

步骤1:

  import { mapState } from 'vuex'
  // console.log(mapState(['count','title']))
  // 我们可以在计算属性中展开mapState

步骤2:

    computed: {
      ...mapState(['count', 'title'])
    },

步骤3:

我们可以像使用vue的data中的数据一样,去使用计算属性中的变量。

   <h1>{{ title }}</h1>

 

 3、严格模式

明确νuex同样遵循单向数据流,组件中不能直接修改仓库的数据通过 strict:true可以开启严格模式

// 创建仓库
const store = new Vuex.Store({
  // 严格模式: 如果每个组件都可以修改数据,一旦项目打了,开发人员多了,就很难维护了
  // 可以使用严格模式来让vuex修改数据,修改后,vuex在通知我们的组件,更新数据。
  // 有利于初学者,检测不规范的代码=>上线时需要关闭
  strict: true,
  // 通过提供数据,这些数据被所有的组件共享
  state: {
    title: '公共的标题',
    count: 100
  }
})

 4  mutations的操作流程

state数据的修改只能通过 mutations。

1、仓库index.js

const store = new Vuex.Store({
  strict: true,
  state: {
    title: '公共的标题',
    count: 100
  },
  mutations: {
    // 所有 mutation函数,第一个参数,都是 state
    addCount (state) {
      state.count += 1
    }
  }
})

 2、在页面中使用我们的mutations

      handleAddCount(){
        this.$store.commit('addCount')
      }
     <button @click="handleAddCount">值 + 1</button>

 

5  mutations传参语法

需要注意的是,如果要传递多个参数,我们需要把多个参数丢到对象当中,像传递一个参数一样,把对象传递给我们定义的mutations函数 。

6  辅助函数: mapmutations

目标:掌握辅助函数 mapmutations,映射方法mapmutations和 mapstate很像,它是把位于 mutations中的方法提取了出来,映射到组件 methods中

mapmutations相当于3.1的辅助写法,只是把方法捞到了methods当中了。

7 actions (异步操作)

目标:明确 actions的基本语法,处理异步操作,

需求:一秒钟之后,修改 state的 count成666。

说明: mutations必须是同步的(便于监测数据变化,记录调试。

 步骤1:修改仓库index.js

  mutations: {
    changeTitle (state, newTitle) {
      state.title = newTitle
    }
  },
  // 3.actions 处理异步
  // context上下文(此处未分模块,可以当成 store仓库)
  //  context, commit(" mutation名字,额外参数)
  actions: {
    asynChangeTitle (context, newTitle) {
      // setTimeout方法是异步的,3秒钟之后换成我们的新标题
      setTimeout(()=>{
        context.commit('changeTitle',newTitle)
      },3000)
    }
  }

这里,actions是mutations的同级对象。

步骤2: 测试

    <button @click="handleChangeTitle">3秒之换标题</button>
    methods: {
      handleChangeTitle () {
        // 调用action
        //this.$store.dispatch('我们vuex仓库中的action的名字','额外参数')
        this.$store.dispatch('asynChangeTitle','这是3秒钟之后的新标题')
      }
    },

 

总结:和前面的“mutations传参语法”目录类似,只是多了actions这个中间人 ,this.$store.commi换成了this.$store.dispatch。

8 getters

getters类似于计算属性。说明:除了 state之外,有时我们还需要从 state中派生出一些状态,这些状态是依赖 state的,此时会用到 getters。

例如: statel中定义了list,为1-6的数组,组件中,需要显示所有大于3的数据

步骤1:

getters和state同级

  getters: {
    filterList (state) {
      return state.list.filter(item => item > 3)
    }
  },

步骤2:

在组件内使用:

  import { mapState,mapGetters } from 'vuex'
    computed: {
      //mapState和mapGetters都是映射属性
      ...mapState(['count', 'title']),
      ...mapGetters(['filterList'])
    },

9 模块 module(进阶语法)

9.1 获取module的数据

项目大,代码就多了,store的文件内存上千行代码,很难维护,不易管理。

module的存在就是为了解决这个问题的。

步骤1:

在store目录下建一个新目录modules,在modules下建两个js文件,user.js,setting.js,如下:

// setting.js
const state = {
  theme: 'blue',
  desc: 'deom'
}
const mutations = {}

const actions = {}

const getters = {}

export default {
  state,
  mutations,
  actions,
  getters
}
// user.js
const state = {
  name: 'Mike',
  hobby: '唱、跳、Rap'
}
const mutations = {}

const actions = {}

const getters = {}

export default {
  state,
  mutations,
  actions,
  getters
}

步骤2、把user.js,setting.js导入到store目录下的index.js文件中:

import settings from './modules/settings'
import user from './modules/user'

 mudules对象和state对象同级:

  modules:{
    settings,
    user
  }

步骤3 使用modules下的数据:

modules的子模块的状态,还是会挂到根级别的 state使用模块中的数据

①直接通过模块名访问$ store. state模块名.XXX

②通过 mapstate映射

默认根级别的映射 mapstate(['XXX'])子模块的映射 mapstate('模块名',['XXX']) -

需要开启命名空间

export default {
  state,
  mutations,
  actions,
  getters,
  namespaced:true
}
 ①直接通过模块名访问$store.state.模块名.XXX
     <span>爱好: {{ $store.state.user.hobby }}</span>

②通过mapstate映射
  <span>(mapState)爱好: {{ user.hobby }}</span>
    computed: {
      //mapState和mapGetters都是映射属性
      ...mapState(['count', 'title','settings','user']),
      ...mapGetters(['filterList'])
    },

 9.2 修改module模块下的数据

步骤1、定义mutaion

const mutations = {
  setUserInfo(state,newHobby){
    state.hobby = newHobby
  }
}
    methods: {
      updateUserInfo () {
        // this.$store.commit('模块名/mutation名',参数)
        this.$store.commit('user/setUserInfo','唱、跳、Rap、Smile')
      }
    },
        <button @click="updateUserInfo"> 修改爱好信息 </button>
        <span>爱好: {{ user.hobby }}</span>

 点击按钮前:

 点击按钮后的页面:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值