美文网首页
vuex 使用

vuex 使用

作者: jasmine_6aa1 | 来源:发表于2020-03-08 00:09 被阅读0次

1, vuex 的作用

vuex 是vue配套的 公共数据管理工具,可以把一些共享的数据,保存到 vuex中,方便整个程序中任意组件获取或修改公共数据

vuex 是为了保存组件之间共享数据而诞生的,如果组件之间有要共享数据,可以直接挂载到 vuex 中,而不必通过父子组件之间传值,如果组件的数据不需要共享,此时,这些不需要共享的私有数据,没有必要放到vuex中

只有共享的数据才有权利放到vuex中;组件内部私有数据,只要放到组件data中即可

2, vuex 的安装

运行步骤

1,运行  npm i vuex -s 安装vuex依赖
2,导入包:`import Vuex from 'Vuex'`
3,注册 vuex 到vue中: `Vue use(Vuex)`
4,new Vuex.Store()实例,得到一个数据仓储对象

3, vuex 的基本结构

var store = new Vuex.Store({
   state:{//相当于 data 存储数据            
         count:0;
   },
   mutations:{//相当于mothods方法 
      increate(){
      //如果子组件要调用 mutations 中的方法,只能使用this.$store.commit('方法名') — 这个方法最多传两个参数,如果多个参数,可以把它作为一个对象传过去**
         state.count++;
       }
   }, 
   getters:{//这个只负责对外提供数据,不负责修改数据,如果想修改 state 中数据,请找 mutations,这个方法和过滤器
   },
    action: {}// 异步操作,是为了让mutations中的方法能在异步操作中起作用。
})

4,将vuex创建的 store 挂载到vue实例上

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

5, vuex 使用

1,store 下的 index 配置文件

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)  //挂载Vuex

const store = new Vuex.Store({
    state: {
        count: 20,
        todos: [
            { id: 1, text: '...', done: true,age:19 },
            { id: 2, text: '...', done: false,age:14}
        ]
    },
    mutations: { // 对于 state 中数据进行修改
        increase(state,n) {
            state.count += n
        },
        reduce(state,n) {
            state.count -= n
        }
    }
})

export default store  // 暴露出`store`接口

2,vuex中 mutations 使用

vuex mutations 中,不支持异步操作,所有的异步操作都放在 action 中
方法一

// html 文件中调用:如果在组件中,想要访问store中的数据,只能通过 `this.$store.state`  来访问
<input type="text" v-model="$store.state.count">
// 父组件 (子组件改变父组件中的 count 值)
count: <span>{{$store.state.count}}</span>

方法二:

<div>{{count}}</div> // 20

import { mapState } from "vuex";
computed: { 
    // 在computed中,引入store中的count数据,直接在页面中使用count就好
    ...mapState(["count"]),
},
2.1,mutations 传参

方法一:

  • 不传参数
increaseChild(){
     // 这里要调用配置文件中的 mutations 下的 increase 函数,
    // 不推荐直接操作 state 中的数据,万一导致数据的紊乱,不能快速定位到错误的原因,因为每个组件都可能有操作数据的方法
      this.$store.commit('increase',2)
},

如果子组件要调用 mutations 中的方法,只能使用this.$store.commit('方法名') — 这个方法最多传两个参数,如果多个参数,可以把它作为一个对象传过去

  • 传参数
// 配置文件中
increase(state,payload) {
    state.count += payload
},
// 传递文件中
increaseChild(){
   this.$store.commit({
      type: 'increase',
      count: 2
  })
},

方法二:

import { mapMutations } from "vuex";
methods: { 
    // 在methods中,引入mutations中的increase方法
    ...mapMutations (["increase"]),
   // 调用时候,直接使用 this.increase()即可
},
2.2,mutations 同步函数,给 state 中对象添加新属性方法

Vuex 中store中status是响应式的,当status中的数据发生变化时,Vue组件会自动更新,但是这个必须要求我们遵循Vue对应的规则

方法一:提前在 store 中初始化所需的属性
方法二:Vue.set (obj, 'newProp', 123)

// 给todos中每个 item 增加一个编辑布尔属性值
addDoneTodos(state){
    state.todos.filter(item=>{
       Vue.set(item,'eidt',true)
    })
}

3,vuex中 getters 使用

如果 store中state上数据,在对外提供的时候,需要做一层包装,那么,推荐使用getters,相当于computed 属性,如果需要使用 getters 则用 this.$store.getters.xxx

var store = new Vuex.Store({
   state:{
         todos: [
            { id: 1, text: '...', done: true,age:19 },
            { id: 2, text: '...', done: false,age:14},
            { id: 3, text: '...', done: true,age:26 },
            { id: 4, text: '...', done: false,age:13 },
        ]
   },
   getters: {
        doneTodos(state){// 给数据进行一层过滤或者包装
            return state.todos.filter(todo => todo.age>18)
        }
    }
})

方法一:html 文件中调用

// 这里调用的,不需要 ()
<div>{{$store.getters.doneTodos }}</div> 

方法二:

import { mapGetters } from "vuex";
computed: {
    ...mapGetters(["doneTodos"]),
},

4,vuex中 action 使用

vuex mutations 中,不支持异步操作,所有的异步操作都放在 action 中
改变Vuex state中值,必须要通过mutations来处理,但是mutations中不支持异步操作,但是action中支持异步操作,所以必须要在action中结束异步操作,再调用mutations中事件来改变值

方法一:页面中调用Vuex action中事件

changeAdd(){
   this.$store.dispatch('increase', 8)
}

方法二:

import { mapActions} from "vuex";
methods: {
    ......mapActions(["increase"]),
    changeAdd(){
       this.increase(8)
    }
},

配置文件中

const store = new Vuex.Store({
    state: {
        count: 20
    },
    mutations: {
        increase(state,payload) {
            state.count += payload
        }
    },
    actions:{
        increase(ctx,payload){
            setTimeout(()=>{// 异步操作在此结束后 再调用mutations中的increase,进行修改值
                ctx.commit('increase',payload)
            })
        }
    }
})

export default store

5,vuex中 module 局部状态使用

5.1,结构目录
image.png

我们会把store下面的index拆成好几块,分为 actions.js,mutations.js,modules.js几个文件,之后再把这个引入到主文件 index.js 中,这样就会很清晰明了

5.2,module 使用

status 是单一的状态树,但是status下module可以分为几个模块组成,每个组成部分都有独立的结构

const moduleA = { 
    state: { ... },
    getters: { ... },
    mutations: { ... },
    actions:{ ... }
}

const moduleB = { 
    namespaced: true, // 开启命名空间,不会影响其他模块,表示是一个单独的模块
    state: { ... },
    getters: { ... },
    mutations: { ... },
    actions:{ ... }
}

再把上面 modules 文件引入主文件中
我们打印出来的 state 数据结构是

state: {
  moduleA: {...},
  moduleB: {...}
}

当我们在页面引用时:

import { mapActions } from "vuex";

// 前面要加一个模块,否则不知道调用的是哪一个模块里面的方法
...mapActions('moduleA', ["increase"]),

6,vuex 中监听数据改变

1,在组件中映射 state 数据到计算属性上
2,在组件中,使用watch进行监听

7,vuex持久化组件

当我们使用vuex中数据,页面刷新之后,数据会消失,所以 vuex-persistedstate 诞生了

1,安装:

npm install vuex-persistedstate -s

2,在 store下 index.js直接引入

import Vue from 'vue';
import Vuex from 'vuex';
// logger 插件会生成状态快照,所以仅在开发环境使用
import createLogger from 'vuex/dist/logger'; 
import createPersistedState from 'vuex-persistedstate';

const persistPlugin = createPersistedState({
    storage: window.sessionStorage,
    paths: moduleA.currentChangeInfo, // moduleA模块下的currentChangeInfo数据
  });

const debug = process.env.NODE_ENV !== 'production';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    order,
    tech,
    controlBoard,
  },
  plugins: debug ? [createLogger(), persistPlugin] : [persistPlugin],
});

注:当我们刷新后,数据是存储在本地的,而不是存储在vuex中的

export default {

state,
mutations,
actions
}

以上的内容,如果出错,请大家指教,谢谢!

相关文章

网友评论

      本文标题:vuex 使用

      本文链接:https://www.haomeiwen.com/subject/blfldhtx.html