VUEX 详解

为什么使用vuex

在中大型应用中,应用的各个组件间需要进行数据传递,使用传统方式繁琐且不可控

Vuex 为所有组件提供集中式的可追踪的状态(数据) 管理

vuex 的数据是响应式的

使用Vuex将摒弃传统的 event emmit 和props的方式进行数据的传递和更新

问题场景

问题一、通过路由传参数,我们会采用params 或者query形式 ,但是这两种方式都会在URL上做手脚 , 如果传递参数过多,会导致400 Bad Request (如,点击表格某行,携带行数据跳转到新页面进行查看)

问题二、兄弟传值

问题三、多个地方使用同一数据,为减少重复请求数量

由于要下钻的ID过长,受浏览器的URL长度限制问题 可以使用Vuex做中间过渡,跳转前存储ID信息,进入B页面后从Vuex获取ID信息。

注意: vuex 存储的数据是在内存中的 页面刷新 数据就会消失

每次调用mutation之后向 localstorage 存值,防止刷新丢失

VUEX 具体用法

创建 VUEX

在 uni-app 项目根目录下新建 store 目录,在 store 目录下创建 index.js 定义状态值。

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

 const  store  = new Vuex.Store({
    state:{
        firstData:''
    },
    getters:{
        get(state){
            return state.firstData
        }
    },
    mutations:{
        add(state,data){
            state.firstData =state.firstData + data
        }
    },
    actions:{
        jian({commit,state},name){
            commit('add',name)
        }
    }
})

export default  store

在 main.js 中挂载

Vue.prototype.$store = store 
const app = new Vue({
    ...App ,
    ...store 
    
})

VUEX属性解析

1、组件Vue Component通过dispatch来调用actions提供的方法
2、而actions除了可以和api打交道外,还可以通过commit来调mutations提供的方法
3、最后mutaions将数据保存到state中
4、当然,Vue Components还以通过getters提供的方法获取state中的数据

VUX数据的使用

mutations

组件页面中的 可以通过 this.$store.dispatch('jian',2) 调用

state:{
        firstData:1
    },
mutations:{
        add(state,data){
            state.firstData =state.firstData + data
        }
    },
    actions:{
        jian({commit,state},name){   // 把commit 解构出来
            commit('add',name)
        }
    }

commit

组件页面中的可以通过 this.$store.commit("add",3);

mutations:{
        add(state,data){
            state.firstData =state.firstData + data
        }
    },

getters

组件可以通过 this.$store.getters.get

getters:{
        get(state){
            return state.firstData
        }
    },

VUEX 的高级用法

一定要引入 vuex 并且要在开头调用 Vue.use(Vuex)

下面四个方法均是在App组件中想要获得数据或方法

mapState

将状态从根组件“注入”到每一个子组件中

在 store 中添加一个数据

state: {
    counter: 1,          
}
复制代码

在App组件中使用这个数据

  • 可以使用 this.$store.state.counter 获得这个数据,但是我们一般不用此方法
  • 我们可以使用mapState

在App中导入这个方法

import {mapState} from "vuex"

然后在计算属性中(computed)使用

computed:{
    ...mapState(["counter"]),    //  映射 this.count 为 store.state.count   使用对象展开运算符将此对象混入到外部对象中
}
复制代码

这样就获得了这个数据,可以在页面中使用 插值表达式:{{ counter }},直接使用这个数据

如果想要获得多个数据(数组也可以)

...mapState(["counter","arr","list"]),

只需中间加个逗号,这样写就ok了

mapGetters

有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数,这时就要用到 mapGetters 方法了

例如我在 store 中定义一个数组

state: {
    list: [
      { name: "ming", score: 40 },
      { name: "gang", score: 50 },
      { name: "lan", score: 60 },
      { name: "mei", score: 70 },
      { name: "tian", score: 80 },
      { name: "bai", score: 90 },
    ]
}
复制代码

想要过滤出分数小于60分的,这时就需要在 store 中的 getters 中定义一个方法:

getters: {
    faileNum(state){
      return state.list.filter(item=>item.score < 60).length;
    }
}
复制代码

然后在App组件的计算属性中接收此方法
一定不要忘了引入

import {mapGetters} from "vuex"
computed:{
    ...mapGetters(["faileNum"]),    // 使用对象展开运算符将 getter 混入 computed 对象中
  }
复制代码

然后直接在组件中使用插值表达式输出就好了

<p>不及格的学生人数是:{{faileNum}}</p>

mapMutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

例如:我们在 store 中定义一个数据

state: {
    stus: ["ming", "hong"],
  }
复制代码

我们想要在stus数组中加入一个数据

除了平常用的 this.$store.commit(xxx) ,我们最经常使用的还是 mapMutation 方法

此时我们就需要在store中的 mutations 下定义一个方法

 mutations: {
    add(state, n) {
      state.stus.push(n)
    },
  }
复制代码

然后直接在 App组件中导入这个方法

import {mapMutations} from "vuex"

然后在methods下使用这个方法,如下

methods:{
    ...mapMutations(["add"]),   // 将 `this.add()` 映射为 `this.$store.commit('add')`
  }
    //// `mapMutations` 也支持载荷:
      'add' // 将 `this.add(amount)` 映射为 `this.$store.commit('add', amount)`

最后直接在组件中 绑定click方法使用 就好了,还可以传参

<button @click="add('tian')">增加</button>
复制代码

注:Mutation 必须是同步函数

mapActions

Action 类似于 mutation,不同在于:

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

例如,我们写一个异步操作,首先在 store 中定义数据

 state: {
    counter: 1,
  }
复制代码

然后在 mutations 中定义一个方法

mutations: {
    //同步点击
    add(state) {
      state.counter++
    }
  },
复制代码

最后在 actions 中定义一个异步操作

actions: {
    // 如果把异步放在mutaions中,使用程序在调试面板中很难调试,可以把异步放到actions
    // actions和mutations中不同之处在于:
    // action提交也是mutations,不能直接修改状态
    // actions可以包含任意的异步操作
    // actions函数接收一个与store实例具有相同方法的属性的context属性,可以通过context.commit提交,也可以通过context.state获取state
   // addAsyncNum(context){
     // setTimeout(function(){
      //  context.commit("addNum")
      //},2000)
    //},
    jian({commit,state},name){
            commit('add',name)
        }
  }
复制代码

接着在 App组件中导入

import {mapActions} from "vuex"

然后在方法中使用

methods:{
    ...mapActions(["jian"])
  }
// 'jian', // 将 `this.increment()` 映射为 `this.$store.dispatch('jian')`

      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('jian', amount)`

最后在App组件中绑定方法使用就ok了

<button @click="addAsyncNum">异步点击</button>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342