vuex中的state属性解析

 更新时间:2022年04月12日 11:23:01   作者:正版蜀黍  
这篇文章主要介绍了vuex中的state属性,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

state属性介绍

state属性是Vuex中用于存放组件之间共享的数据;也就是说,我们把一些组件之间共享的状态主要存放在state属性中;它采用的是单一状态树——用一个对象就包含了全部的应用层级状态。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

state的使用

在HTML中我们可以直接省略 this 关键字 ,直接使用 $store.state.状态名(变量名) 来访问 vuex 中的存储的状态;

① 抽离出去的state.js文件

export default {
  loadingFlag: true,
  // 用于保存已选类别标签
  changedLableList: [
    { name: '头条', class: 'iconfont icon-jinrishouru', url: 'topnews/index' },
    { name: '苹果', class: 'iconfont icon-pingguoapple', url: "apple/index" },
    { name: 'NBA', class: 'iconfont icon-tiyu-lanqiu', url: "nba/index" },
    { name: '创业', class: 'iconfont  icon-chaxunchuangyebankaitongqingkuang', url: "startup/index" },
    { name: '足球', class: 'iconfont icon-swticonzuqiu', url: "football/index" },
    { name: '体育', class: 'iconfont icon-paobu', url: "tiyu/index" }
  ]
}

② 在index.js文件中导入state.js文件并注册

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import state from './state'
import actions from './actions'
import getters from './getters'
// 安装插件
Vue.use(Vuex)
// 创建对象
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

③ 在组件中使用

<div class="flex-content">
          <div class="lable-items" v-for="(item, index) in $store.state.changedLableList" :key="index" @click="decrementTypeLable(index)">
            <div class="item">
              <div><i :class="item.class"></i></div>
              <span>{{ item.name }}</span>
            </div>
          </div>
        </div>

在js代码中,必须使用 this.$store.state.状态名(变量名) 来访问vuex中存储的状态;

computed: {
    title() {
      return this.$route.meta.title
    },
    changedLableList() {
      return this.$store.state.changedLableList
    },
    alternativeLableList() {
      return this.$store.state.alternativeLableList
    }
  },

扩展

为什么要在组件的computed计算属性中使用不能放到data属性中?

data 中的内容只会在 created 钩子函数触发前初始化一次,类似于我们直接写 const data = { foo: 123 }这样,这时属性的值是纯粹的字面量,而不是所谓的【缓存】(没有 Cache Miss 哪来的缓存?)。JS字面量赋值后显然不会自动更新。

最简单的例子:

let b = ‘xxx' // 相当于state中的数据
let a = b // 相当于data初始化时,将b的值赋值给了a
b = ‘xyz' // 这时对于原始类型,a 肯定还是 ‘xxx'

换句话说,data 中内容依赖变更时,data 属性不会变更(它的设计目标就是保存组件的局部状态数据而已)。而 computed则是通过【依赖追踪】实现的,在 computed 求值时引用的 Vue 变量变化时,会触发对 computed 的重新计算。所以我们可以使用computed 去引用 Vuex 状态变量,从而使得依赖追踪生效。或者,将 Vuex 状态变量通过 mapState() 方法映射为 computed 也是一个很方便的选择。

vuex的State

state 是Vuex中的基本数据,state 上存放的就是所谓的状态。当没有使用 state 的时候,直接在 data 中进行初始化,有了 state 之后,我们就把 data 上的数据转移到 state 上去了。

单一状态树

Vuex 使用到的是单一状态树,即用一个对象就包含了全部的状态数据。也就是说如果我们定义了一个 store 的实例,那么这个 store 实例里面只有一个 state。state作为构造器选项,定义了所有我们需要的基本状态参数。

单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

在Vue组件中获得 Vuex 状态

从store实例中读取状态最简单的方法就是在计算属性中返回某个状态。

示例:

例如我们在state中定义一个count属性,给它赋一个值为10,store.js文件内容如下所示:

import Vue from 'vue' // 引入vue
import Vuex from 'vuex' // 引入vuex
Vue.use(Vuex)  
const state = {
    count: 10
}
export default new Vuex.Store({
    state
})

然后创建一个 Counter组件,在组件中返回count,内容如下所示:

const Counter = {
  template: `<div> count的值为:{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count  //返回store实例的count状态
    }
  }
}

每当 store.state.count 变化的时候,都会重新求取count属性,并刷新界面。

这种模式依赖于全局的管理员 store,如果模块多了,那么每个模块或者页面只要用到了这个 state 里面的数据,都得把 store 引入进来,这样的操作确实有点难受。所以出现了下面这种解决办法。

Vuex 通过store 选项,提供了一种机制将状态从根组件 “注入” 到每一个子组件中:

new Vue({
  el: '#app',
  store,  // 根组件通过store选项将store实例注入所有地子组件
  // 子组件
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

Vue项目的index.html文件内容如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>侠课岛</title>
  </head>
  <body>
    <h1>侠课岛欢迎你</h1>
    <div id="app"></div>
  </body>
</html>

最终我们使用 npm run dev 运行项目,浏览器中的输出结果如下图所示,如果我们在state中改变count的值,页面会自动刷新:

mapState辅助函数

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

示例:

在使用mapState函数之前,需要先引入它:

import { mapState } from 'vuex'

引入后才可以开始使用,它两种用法,可以接受一个对象或接受一个数组。

对象用法如下:

import { mapState } from 'vuex'
export default {
  // 下面这两种写法都可以
  computed: mapState({
    // 组件内的每一个属性函数都会获得一个默认参数state,然后通过state直接获取它的属性
    count: state => state.count,
    // 'count' 直接映射到state对象中的count,相当于this.$store.state.count
    count: 'count' 
  })
}

数组用法如下所示:

// 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给mapState传一个字符串数组。
export default {
    computed: mapState([ // 数组
      'count'
    ])
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • vue+canvas实现简易的九宮格手势解锁器

    vue+canvas实现简易的九宮格手势解锁器

    这篇文章主要为大家详细介绍了如何流vue+canvas实现一个简易的九宮格手势解锁器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-09-09
  • 一篇文章看懂Vue组合式API

    一篇文章看懂Vue组合式API

    众所周知组合式API是一系列API的集合,使我们可以使用函数而不是声明选项的方式书写Vue组件,这篇文章主要给大家介绍了关于Vue组合式API的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • Vue3中如何使用component :is 加载组件

    Vue3中如何使用component :is 加载组件

    Monaco-editor,一个vs code 编辑器,需要将其集成到项目,这篇文章主要介绍了Vue3中如何使用component :is 加载组件,需要的朋友可以参考下
    2023-11-11
  • 简单了解vue.js数组的常用操作

    简单了解vue.js数组的常用操作

    这篇文章主要介绍了简单了解vue.js数组的常用操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06
  • vuejs响应用户事件(如点击事件)

    vuejs响应用户事件(如点击事件)

    本篇文章主要介绍了vuejs响应用户事件(如点击),通过vuejs响应用户事件的技巧,具有一定的参考价值,有兴趣的小伙伴们可以参考一下。
    2017-03-03
  • Vue3样式渗透之deep()为什么无效详解

    Vue3样式渗透之deep()为什么无效详解

    项目开发中因为ui设计常常需要修改vue常用的组件库(element,antD等等),这就需要用到样式穿透,下面这篇文章主要给大家介绍了关于Vue3样式渗透之deep()为什么无效的相关资料,需要的朋友可以参考下
    2022-11-11
  • Vue.js弹出模态框组件开发的示例代码

    Vue.js弹出模态框组件开发的示例代码

    本篇文章主要介绍了Vue.js弹出模态框组件开发的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 解决v-if 与 v-for 同时使用报错的问题

    解决v-if 与 v-for 同时使用报错的问题

    在进行项目开发的时候因为在一个标签上同时使用了v-for和v-if两个指令导致的报错,遇到这个问题如何解决呢?下面小编给大家带来了关于v-if 与 v-for 使用报错问题分析及解决方法,一起看看吧
    2022-03-03
  • 动态Axios的配置步骤详解

    动态Axios的配置步骤详解

    这篇文章主要给大家分享介绍了关于动态Axios的配置步骤,文中通过示例代码介绍的非常详细,通过这个教程大家可以很方便的实现动态Axios的配置,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2018-01-01
  • Vue开发指南之重点知识梳理

    Vue开发指南之重点知识梳理

    这篇文章主要介绍了Vue开发指南之重点知识梳理,对Vue框架感兴趣的同学,可以参考下
    2021-05-05

最新评论