Vue之store

  • Post author:
  • Post category:vue


1.Vuex初识

vuex是基于vue框架的一个状态管理库。可以管理复杂应用的数据状态,比如兄弟组件的通信、多层嵌套的组件的传值等等。vuex有这么几个核心概念——


State





Getter





Mutation





Action





Module

2.Store尝试

2.1  添加依赖

【 package.json 】:

"dependencies": {
    "vue": "^2.5.2",
    "vuex": "^3.4.0"
  }

2.2  store

新建store文件夹底下的index.js

【 index.js 】:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    nickname:'李雪琴',
    age:20,
    gender:'女'
  },
  mutations: {},
  actions: {},
  modules: {}
})
export default store

2.3  main.js


index.html :主页,项目入口                        App.vue:根组件         main.js:入口文件

在项目运行中,main.js作为项目的入口文件,运行中,找到其实例需要挂载的位置,即index.html中,刚开始,index.html的挂载点处的内容会被显示,但是随后就被实例中的组件中的模板中的内容所取代,所以我们会看到有那么一瞬间会显示出index.html中正文的内容。

main.js作用:实例化Vue;放置项目中经常会用到的插件和CSS样式。例如: 网络请求插件:

axios和vue-resource;

存储全局变量(基本信息)。

我看网上有人这样比喻main.js的作用:

main.js

是工会老大,你把奖励给了老大,老大有的道具会交给你使用,那么你就可以通过this来使用

【main.js】:

import store from './store'

import Utils from './util'

// main.js是工会老大,你把奖励给了老大,老大有的道具会交给你使用,那么你就可以通过this来使用

new Vue({
 // el: '#app',
  router,
  store,  //注册进全局
  components: { App },
  template: '<App/>'
}).$mount("#app")

2.4  mapState用法


第一种:

页面直接引用

<P>姓名:{{$store.state.nickname}} 性别:{{$store.state.gender}} 年龄:{{$store.state.age}}</


第二种:

computed

<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>

export default {
    name: "ComponentC",
    data() {
        return {
          msg: '这是组件'
        }
    },
    computed: {//computed是不能传参数的
        nickname(){return this.$store.state.nickname},
        age(){return this.$store.state.age},
        gender(){return this.$store.state.gender}
    }
}


第三种:

mapState

<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>


import {mapState} from "vuex"

export default {
    name: "ComponentC",
    data() {
      return {
        msg: '这是组件C'
      }
    },
     computed: {//computed是不能传参数的
        ...mapState([
        'nickname', 'age', 'gender'  // 映射哪些字段就填入哪些字段
      ])
}


第四种:

mapState

<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>


import {mapState} from "vuex"

export default {
    name: "ComponentC",
    data() {
      return {
        msg: '这是组件C'
      }
    },
     computed: {//computed是不能传参数的
        ...mapState({
        //使用箭头函数
        age: state=>state.age+100,
        //传入字符串 ‘nickname’ 等同于 `nickname => state.nickname`
        nickname:'nickname',
        // 为了能够使用 `this` 获取局部状态,必须使用常规函数
        gender(state) {
          return state.gender
        }
      ])
}

2.5  mapGetters用法

 getters:{
    objGet(state) {
      return {
        nickname: state.nickname,
        age: state.age+20,
        gender: state.gender
      }
    }
  }

组件引用:

<P>{{objGet}}</P>
import {mapGetters} from "vuex"

 computed: {
     ...mapGetters([
         'objGet'  // 把vuex 中的 getters 筛选返回数据的方法加进来,{{objGet}}使用
      ])
 }



注意:

如果你的值是需要加工的,那么用getter;反之直接通过 state 取值,只需要源值就用 mapState。

2.6  mutations用法

mutations: {
//类似于methods,调用的时候第二个参数最好写成对象形式,这样我们就可以传递更多信息
    nameTest(state, name) {
      state.nickname = name;
      state.age+=10
    },
    commitTest(state, payload) {
      alert(payload.number)
      state.age = payload.number;
    }
}

组件引用:

import {mapMutations} from "vuex"

methods: {

 ...mapMutations([
          "nameTest"  // 把 vuex 方法加进来,然后 this.nameTest(params) 就可以用
        ]),
   tt() {
        this.nameTest("女_update_update")
   },
   tt1(){
     //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
       this.$store.commit('commitTest',{
            number:5
      })
    }
}

2.7  mapAction用法

 actions: {
    increment1({commit,state},number){
      //提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
      //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
      alert(number)
    },
    increment({commit,state}){
      //提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
      //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
      commit('nameTest',"commit")
    },
    dispatchTest({commit,state},name){
      //提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
      //commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
      state.nickname = name
    },
    dispatchTest1(context){//官方给出的指定对象, 此处context可以理解为store对象
      debugger
    }
  }

组件引用:

      <P>mapAction↓</P>
      <button @click="increment">尝试mapMutations_1</button>
      <button @click="increment1(696)">尝试mapMutations_2</button>
      <button @click="tt5()">尝试mapAction_dispatch</button>
      <button @click="tt6()">尝试mapAction_context</button>


import {mapActions} from "vuex"

    methods: {
      tt5(){
        //打印res,结果打印出Promise,这表明,在actions中的方法,默认就是异步的,通过then获取数据
        var res = this.$store.dispatch('dispatchTest',"haha")
        console.log(res)
      },
      tt6(){
        //打印res,结果打印出Promise,这表明,在actions中的方法,默认就是异步的,通过then获取数据
        this.$store.dispatch('dispatchTest1')
      },
       ...mapActions([
          //该 increment 来自 store.js 中导出的 actions 和 mutations 中的 increment
          'increment','increment1'
        ])
    }

通过

2.6



2.7

可以得出:




*****




action

也有一个固有参数 context,但是 context 是 state 的父级,包含 state、getters


action

可以提交mutation(通过commit)


action

也不要直接去操作state,而是去操作mutation


action

包含异步操作,类似于axios请求,可以都放在action中写


action

中的方法默认的就是异步,并且返回promise




*****




mutations

有一个固有参数 state,接收的是 Vuex 中的 state 对象


mutations

只能写同步方法,不能写异步,比如axios、setTimeout等,这些都不能写,mutations的主要作用就是为了修改state的

3.数据丢失处理

因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化


解决思路:

将state的数据保存在localstorage、sessionstorage或cookie中(

三者的区别

),这样即可保证页面刷新数据不丢失且易于读取。

  1. localStorage: localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。
  2. sessionStorage:sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
  3. cookie:cookie生命期为只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 存放数据大小为4K左右,有个数限制(各浏览器不同),一般不能超过20个。缺点是不能储存大数据且不易读取。



版权声明:本文为tianruozhaomi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。