zoukankan      html  css  js  c++  java
  • vuex实现数据持久化

    vuex-状态管理工具

    对于vuex来说,它只是一个状态管理工具,当有些变量不止在组件间用时,可能很多页面都会复用。我们使用vuex进行管理。

    state:设置初始值状态。

    getters:store仓库的计算属性,主要作用是派生出一些新的状态。比如将state状态的数据进行一次映射或者筛选。

    mutations:对state数据进行赋值操作,并进行相应操作;利用store.commit()触发该操作,

    actions处理异步操作,可以使用commit方法,使用store.dispatch()触发。

    实现数据的持久化--跟localStorage结合使用

    设置state的状态:

    const state = {
        status: '0'
    };

    设置getters:

        getStatus(state) {
            let t = localStorage.getItem('isLogined')
            if (t == null || t== undefined) {
                t = state.isLogined;
            }
            state.isLogined=t;
            return state.isLogined;
        }    

    设置mutations:

    SET_STATE(state, val) {
            state.status = val;
            try {
                localStorage.setItem('isLogined',val);
            } catch (e) {
                console.log(e);
            }
        }

    使用-----在页面的计算属性 根据getter获取状态

    computed:{
          isLogined(){
            return this.$store.getters['getStatus'];
        }   
    }        
    

     操作----修改状态即在方法中调用commit:

    methods:{
      handleStatus(){
         this.$store.commit('SET_STATUS','1');        
      }
    }

    (小知识点:如果是在公共函数内调用,请引入store的index的js文件,调用store.getters和store.commit)

    storage的存储方式:

    localStorage的存储是按照字符串存储的(以上例子为存储字符串格式)。如果存储为对象格式,会出现返回值是{Object object}的情况,那么,存储时要将数据转成string格式,请使用如下方式:

       localStorage.setItem('obj',JSON.stringfy(object));
    

    storage的读取和使用:

       JSON.parse(localStorage.getItem('obj'));

    注意点:

    getter的值是要根据依赖值进行变化的, 即如果return的返回值不是state的数据,则监听不到数据变化。

    假如只是return localStorage.getItem('status')的话, 则数据不会更新。必须进行state的赋值和return操作。

    如果不需要对数据二次改造的话,也可以写到state的初始值: status: localStorage.getItem('isLogined') || '0'。这样的话取数据只能用this.$store.state.status来获取了。

    ---同理,computed的计算属性也应该和data的数据依赖。

    插播一点: 可使用node require引入文件的方式  遍历模板,避免模板过多,每次引入文件。

    const modulesFiles = require.context('./modules', false, /\.js$/);
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
      // set './app.js' => 'app'  $1是正则里边的捕获,(.*)内的内容;
      const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
      const value = modulesFiles(modulePath);
      modules[moduleName] = value.default;
      return modules;
    }, {});
    
    const store = new Vuex.Store({
      modules,
    });
    

      

    ---------------------------------------------------------------想看原理的请继续往下划,如何使用------------------------------------------------------------------------------------------------------------

    实现原理

    1、vuex本质是一个对象,有两个属性:install方法和Store类。

    2、install方法的作用是将store这个实例挂载到所有组件。

    3、Store这个类有commit,dispatch方法,store类将用户传入的数据包装成data,作为new Vue的参数,从而实现state的响应式。

    • 剖析vuex本质

    Vue项目中是怎么引入Vuex?

    1. 安装Vuex,再通过import Vuex from 'vuex'引入
    2. 先 var store = new Vuex.Store({...}),再把store作为参数的一个属性值,new Vue({store})
    3. 通过Vue.use(Vuex) 使得每个组件都可以拥有store实例

    使用Vue.use(), 而 Vue.use的使用原则是执行对象的install方法。 如果参数是对象,则执行对象的install方法,如果是函数,则将函数当成install执行。

    class store{
    
    }
    
    function install (){
    
    }
    
    export default {store, install}

    1、插件的类型,可以是install方法,也可以是一个包含install方法的对象。

    2、插件只能被安装一次,保证插件列表中不能有重复的插件。

    实现:

    Vue.use = function(plugin){
     const installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
     if(installedPlugins.indexOf(plugin)>-1){
      return this;
     }
     <!-- 其他参数 -->
     const args = toArray(arguments,1);
     args.unshift(this);
     if(typeof plugin.install === 'function'){
      plugin.install.apply(plugin,args);
     }else if(typeof plugin === 'function'){
      plugin.apply(null,plugin,args);
     }
     installedPlugins.push(plugin);
     return this;
    }

    注意点: 首先要判断插件是不是已经注册过,如果注册过,则直接终止方法。保证相同插件不会被重复加载。

    通过Vue.use(Vuex) 使得每个组件都可以拥有store实例:

    function install() {
      Vue.mixin({
        beforeCreate() {
          if (this.$options && this.$options.store) { //根组件,传入vue的参数,可通过$options.store访问。
            this.$store = this.$options.store;
          } else { //不是根组件 
            this.$store = this.$parent && this.$parent.store;
          }
        },
      });
    }

    mixin的作用是将mixin的内容混合到Vue的初始化options中。为什么是beforeCreate 中执行? 因为created中,$options已经初始化好了。

    现在实现类store

    let Vue
    //myVuex.js
    class Store {
        constructor(options) {
            this.vm = new Vue({
                data: {
                    state: options.state
                }
            })
    
            let getters = options.getter || {}
            this.getters = {}
            Object.keys(getters).forEach(getterName => {
                Object.defineProperty(this.getters, getterName, {
                    get: () => {
                        return getters[getterName](this.state)
                    }
                })
            })
    
            let mutations = options.mutations || {}
            this.mutations = {}
            Object.keys(mutations).forEach(mutationName => {
                this.mutations[mutationName] = (arg) => {
                    mutations[mutationName](this.state, arg)
                }
            })
    
            let actions = options.actions
            this.actions = {}
            Object.keys(actions).forEach(actionName => {
                this.actions[actionName] = (arg) => {
                    actions[actionName](this, arg)
                }
            })
    
        }
        //dispatch,commit是方法;其余getter,state是属性!!!
        dispatch(method, arg) {
            this.actions[method](arg)
        }
        commit = (method, arg) => {
            console.log(method);
            console.log(this.mutations);
            this.mutations[method](arg)
        }
        get state() {
            return this.vm.state
        }
    }
    let install = function (vue) {
        ×××省略
    }
    
    let Vuex = {
        Store,
        install
    }
    
    export default Vuex

    生命周期执行顺序:

    data和el什么时候有数据:

    参考文章:

    https://zhuanlan.zhihu.com/p/166087818

  • 相关阅读:
    Windows API的CreateFile()中的OPEN_ALWAYS和CREATE_ALWAYS之间的差异
    Linux下的虚拟串口对(可用于在本机上模拟串口进行调试)
    [转&精]IO_STACK_LOCATION与IRP的一点笔记
    【转】在WIN7、WIN10操作系统用WebDAV映射网络驱动器需要的操作
    Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information
    分布式处理大数据的目录及学习树
    利用docker将传统企业集中式架构转换为微服务架构的实践经验
    docker学习笔记5 端口映射与容器互联
    docker学习笔记4 数据管理、持久化
    docker学习笔记3 容器 container
  • 原文地址:https://www.cnblogs.com/alaner/p/15767054.html
Copyright © 2011-2022 走看看