松鼠乐园 松鼠乐园
  • 注册
  • 登录
  • 首页
  • 快捷入口
    • Vue
    • Tensorflow
    • Springboot
    • 语言类
      • CSS
      • ES5
      • ES6
      • Go
      • Java
      • Javascript
    • 工具类
      • Git
      • 工具推荐
    • 服务器&运维
      • Centos
      • Docker
      • Linux
      • Mac
      • MySQL
      • Nginx
      • Redis
      • Windows
    • 资源类
      • 论文
      • 书籍推荐
      • 后端资源
      • 前端资源
      • html网页模板
      • 代码
    • 性能优化
    • 测试
  • 重大新闻
  • 人工智能
  • 开源项目
  • Vue2.0从零开始
  • 广场
首页 › Vue2.x从零开始 › vuex的简单使用

vuex的简单使用

迦娜王
3年前Vue2.x从零开始
1,890 0 5

当多个视图或者组件需要数据共享的时候,vuex就出现了。vuex是vue官方提供的响应式数据存储插件。一般用来存放全局变量,共享数据,配置项数据。下面我们从多个方面来使用。


[loginview]

引入vuex

在使用之前,我们当然需要先引入vuex啦,先要使用yarn add vuex安装vuex依赖,然后在main.js中引入import store from './store',为了方便使用,我们可以把store注入vue实例根节点

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

vuex的state基本使用

state顾名思义就是用来存储状态用的,在实际使用的时候不止可以用来存储状态,像数组,对象也是可以存储的。

  • 用法1,直接在store.js里面声明自己需要的变量。
  ```js
  	import Vue from 'vue'
	import Vuex from 'vuex'
	
	Vue.use(Vuex)
	
	export default new Vuex.Store({
	  state: {
	    menu:[],//这就是自己定义的变量
	    version:''
	  }
	})
  ```

我声明了一个菜单数组和一个版本号(字符串类型)。多个变量,可以用,隔开就行了。

调用变量:像this.$store.state.menu或者this.$store.state['menu']这样。我们在test1.vue中尝试一下,修改为:

      <template>
        <div>
            <div>Test1视图</div>
            <!--页面读取-->
            <p>version={{$store.state.version}}</p>
            <p>menu={{$store.state.menu}}</p>

            <p>mVersion={{mVersion}}</p>
            <p>mMenu={{mMenu}}</p>
        </div>
    </template>

    <script>
        export default {
            data(){
                return {
                  mVersion:'',
                  mMenu:[],
                }
            },
            mounted() {
                //赋值
                this.$store.state.menu = ['menu1', 'menu2']
                this.$store.state.version = '1.0'

                this.mVersion = this.$store.state.version
                this.mMenu = this.$store.state.menu
            }
        }
    </script>

我们对stote里面的变量进行赋值,然后再读取出来赋值给我们本地的变量,观察本地变量和store里面的变量是否一致,现在页面输出:

符合我们的预期。

  • 用法2,我们不直接声明变量,我们可以动态的创建出来。因为state本身也是一个对象,动态创建,相当于给这个对象加一个key。注意了,如果我们使用这种方式创建:
```js
 this.$store.state['menu'] = ['menu1', 'menu2']
 this.$store.state['version'] = '1.0'
```

是不支持响应式的,vue无法监听到数据的变化,就无法更新页面,这取决于vue框架。但是vue提供了set方法,我们要这样写:

```js
 this.$set( this.$store.state,'menu',['menu1', 'menu2'])
 this.$set( this.$store.state,'version','1.0')
```

调用方式和用法1一样。

vuex的getter基本使用

vuex考虑到开发者会根据一种状态派生出其他的状态,设计了getter,这玩意有点像computed属性,同样支持缓存。修改store.js :

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        persons: [{name: '小米', age: 10}, {name: '张珊', age: 20}]
    },
    getters:{
        personCount(state){
            return state.persons.length
        }
    }
})

我们在getters定义一个专门用来获取persons数组长度的属性personCount。

调用方式也很简单:

<template>
    <div>
        <div>Test1视图</div>
        <!--页面模板中调用不需要this-->
        <p>personCount={{$store.getters.personCount}}</p>

    </div>
</template>

<script>
    export default {
        mounted(){
             //代码里面调用要加上this
            console.log(this.$store.getters.personCount)
        }
    }
</script>

它还可以实现参数传递,上面我们是通过属性调用,如果使用方法调用,那么他就可以传参了。代码变成:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        persons: [{name: '小米', age: 10}, {name: '张珊', age: 20}]
    },
    getters: {
        personCount: (state) => (age) => {
            return state.persons.filter(p => p.age===age).length
        }// 定义多个属性,用逗号隔开
    }
})

现在我们的personCount支持查询某个年龄的人数了。于此同时,调用的地方需要修改:

<template>
    <div>
        <div>Test1视图</div>
        <p>personCount={{$store.getters.personCount(10)}}</p>

    </div>
</template>

<script>
    export default {
        mounted(){
            console.log(this.$store.getters.personCount(10))
        }
    }
</script>

vuex的mutation基本使用

之前我们修改store.state中的数据,都是直接对变量赋值,这种方法其实不太友好,虽然很暴力很直接。通过mutation提交更加符合vue框架。我们先修改store.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        persons: [{name: '小米', age: 10}, {name: '张珊', age: 20}]
    },
    getters: {
        personCount: (state) => (age) => {
            return state.persons.filter(p => p.age===age).length
        }
    },
    mutations:{
        addPerson(state,person){
            state.persons.push(person)//push是数组操作方法,在数组尾部插入一个元素
        }
    }
})

我们加了一个addPerson在mutations,这玩意不是一个方法,因为不能直接调用,你必须要这样调用this.$store.commit('addPerson',{name: '小刚', age: 10})。注意: mutation中不要使用异步代码。

vuex的Action基本使用

Action 类似于 mutation,不同在于:

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

我们修改store.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        persons: [{name: '小米', age: 10}, {name: '张珊', age: 20}]
    },
    getters: {
        personCount: (state) => (age) => {
            return state.persons.filter(p => p.age===age).length
        }
    },
    mutations:{
        addPerson(state,person){
            state.persons.push(person)//push是数组操作方法,在数组尾部插入一个元素
        }
    },
    actions:{
        addPerson(context,person){
            setTimeout(()=>{
                context.commit('addPerson',person)
            },1000)
        }
    }
})

我们在actions节点中定义一个名为addPerson的action,然后故意延迟1s执行。同时我们把test1.vue修改为:

<template>
    <div>
        <div>Test1视图</div>
        <!--页面读取-->
        <p>personCount={{$store.getters.personCount(10)}}</p>

    </div>
</template>

<script>
    export default {
        mounted(){
            this.$store.dispatch('addPerson',{name: '小刚', age: 10})
        }
    }
</script>

刷新页面,我们发现页面上personCount一开始是1,过1s后就变成2了。

vuex的module基本使用

随着我们的项目越来越大,用到的共享变量越来越多,store变得越来越复杂和臃肿,那么我们有必要分割成不同模块。我们先修改store.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//模块1
const person = {

    state: {
        persons: [{name: '小米', age: 10}, {name: '张珊', age: 20}]
    },
    getters: {
        personCount: (state) => (age) => {
            return state.persons.filter(p => p.age === age).length
        }
    },
    mutations: {
        addPerson(state, person) {
            state.persons.push(person)//push是数组操作方法,在数组尾部插入一个元素
        }
    },
    actions: {
        addPerson(context, person) {
            setTimeout(() => {
                context.commit('addPerson', person)
            }, 1000)
        }
    }
}

//模块2
const phone = {

    state: {
        phone: [{name: '小米'}, {name: '苹果'}]
    },
    actions: {
        addPerson(context, person) {
            setTimeout(() => {
                context.commit('addPerson', person)
            }, 1000)
        }
    }
}

export default new Vuex.Store({
    modules: {
        person: person,
        phone: phone
    }
})

我们声明了2个模块person和phone。
这个时候我们该如何调用呢?

console.log(this.$store.state.person)
console.log(this.$store.state.phone)
this.$store.dispatch('addPerson',{name: '小刚', age: 10})
this.$store.commit('addPerson',{name: '小刚', age: 10})
console.log(this.$store.getters.personCount(10))

state的调用需要加上模块的名称,action,mutation,getter的调用还是保持一样,只是需要注意,如果不同的模块中有相同名称的action,mutation,getter都会被触发。默认情况下,模块内部的 action,mutation,getter 是注册在全局命名空间的。这种特性有时候也是有用的。如果你需要区分不同模块,那么需要把namespaced: true,当模块被注册后,它的所有action,mutation,getter都会自动根据模块注册的路径调整命名。调用方式也会发生变化:

console.log(this.$store.state.person)//不变
console.log(this.$store.state.phone)//不变
this.$store.dispatch('person/addPerson',{name: '小刚', age: 10})
this.$store.commit('person/addPerson',{name: '小刚', age: 10})
console.log(this.$store.getters['person/personCount'](10))

想要深入了解,请查阅官方手册。

vuex和computed的联合使用

利用computed可以简化vuex的调用,使得代码不用每次都this.$store.state.xxx。
比如:

<template>
    <div>
        <div>Test1视图</div>
        <!--页面读取-->
        <p>personCount={{personCount}}</p>

    </div>
</template>

<script>
    export default {
        mounted(){
            this.$store.dispatch('addPerson',{name: '小刚', age: 10})
        },
        computed:{
            personCount(){
                return this.$store.getters.personCount(10)
            }
        }
    }
</script>

注意计算属性没法直接传值。如果你非要传值也是有办法的,改成这样:

···
personCount(){
   return function(age){
        return this.$store.getters.personCount(age)
   }
}
···

本质上返回了一个方法,感觉有点投机取巧,在调用的时候只能这样调了:

···
this.personCount(10)
···

这和直接在metheds里面定义一个方法personCount:

···
methods:{
    personCount(age){
        return this.$store.getters.personCount(age)
    }
}
···

其实效果是一样的。不是很推荐这种投机的方法。尽量在设计角度去规避这种写法。

[/loginview]

5
本文系作者 @迦娜王 原创发布在 松鼠乐园。未经许可,禁止转载。
Linux&Mac下fork和exec的简单使用
上一篇
computed属性的使用
下一篇
评论 (0)

请登录以参与评论。

现在登录
  • 引入vuex
  • vuex的state基本使用
  • vuex的getter基本使用
  • vuex的mutation基本使用
  • vuex的Action基本使用
  • vuex的module基本使用
  • vuex和computed的联合使用
5
相关文章
router的使用
watch属性的使用
computed属性的使用
filters的使用
松鼠乐园

资源整合,创造价值

小伙伴
墨魇博客 无同创意
目录
重大新闻 Centos CSS Docker ES5 ES6 Go Java Javascript Linux Mac MySQL Nginx Redis Springboot Tensorflow Vue Vue2.x从零开始 Windows 书籍推荐 人工智能 前端资源 后端资源 壁纸 开源项目 测试 论文
Copyright © 2018-2022 松鼠乐园. Designed by nicetheme. 浙ICP备15039601号-4
  • 重大新闻
  • Centos
  • CSS
  • Docker
  • ES5
  • ES6
  • Go
  • Java
  • Javascript
  • Linux
  • Mac
  • MySQL
  • Nginx
  • Redis
  • Springboot
  • Tensorflow
  • Vue
  • Vue2.x从零开始
  • Windows
  • 书籍推荐
  • 人工智能
  • 前端资源
  • 后端资源
  • 壁纸
  • 开源项目
  • 测试
  • 论文
热门搜索
  • jetson nano
  • vue
  • java
  • mysql
  • 人工智能
  • 人脸识别
迦娜王
坚持才有希望
1224 文章
35 评论
242 喜欢
  • 5
  • 0
  • Top