vuex

vuex 基本使用

1. 安装 vuex

npm i vuex 

2. 在vue项目下的src目录下创建一个 store 目录,并在里面创建一个 index.js 文件

image-20200530220930581.png

3. 在 index.js 中 书写关于仓库的代码

// index.js

// 引入 vue
import Vue from 'vue';
//引入 vuex
import Vuex from 'vuex'

// 1. 安装插件 在 vue 中使用Vue
Vue.use(Vuex);

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    myname: '',
    count: 100,
    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
      },
    ],      

  },
  mutations: {
    // 方法
    // 这里通过是通过 action 里面的 asyncSaveName 方法触发的次方法
    // 因为 action 里面的方法不能修改 state 里面的数据,只能通过 mutations 里面的方
    // 法来修改.
    saveName(state,n){
      // console.log('从action 传过来的数据', n, state);
      // 通过
      state.myname = n.username;
    },
    increment() {
      // console.log(arguments);
      this.state.count++;
    },
    decrement() {
      this.state.count--;
    },
    add(state,n){
      state.stus.push(n);
    },
  },
  //相当于vue的 computed 计算属性
  getters: {
    // 这里是吧上面的 list 数组当中成绩小于60分的数据过滤出来
    faileNum(state){
      return (function(){
        // console.log(arguments);
        return state.list.filter(item => item.score < 60)
      })();
    }
  },
  actions: {
    //在组件当中调用登录接口,如果登录成功那么触发这个方法,把用户名保存到state当中
    // 的 myname 
    asyncSaveName(context,n){
    // console.log('登录成功action被调用', context,n);
    //这里面不能直接修改 state 中的数据 需要提交 mutations 在 mutations 当中的方法
    // 修改 saveName 为 mutations 里面的方法
    context.commit('saveName',n)
      
    }
  },
  modules: {},
})

// 3. 导出store对象
export default store;

// index.js

// store 里面包含 5个模块 
const store = new Vuex.Store({
    // state 存放数据的地方
    state:{},
    //相当于vue的 computed 计算属性
    getters:{},
    // 如果要修改仓库里面的数据 也就是修改 state 里面的数据需要提交 mutations 来修改
    // 并且 mutations 里面不能有异步操作
    mutations:{],
    //actions 是做异步操作的地方 发送请求之类的异步操作都要在 actions 里面做
    // 并且在 actions 里面 也必须提交 mutations  
    actions:{},
    // 如果项目非常大,所有组件数据放到一起管理,非常不方便,并且容易混淆
    // 通过 modules 把仓库分成 多个模块 不同组件的值,保证到不同模块当中
    // 在把模块注入到根仓库中 方便管理
    modules:{}
})

4. 在页面中展示 vuex 里面的数据

  • 目前仓库有以下数据
 state: {
    myname: '',
    count: 100,
    list: [{
        name: "ming",
  • 现在把 state 里面的 count 展示到页面上
  • vue 官网提供两种方式展示
    1. 直接在模板写 $store.state.***
    2. 先引入 mapState 并在计算属性当中写上 ...mapState([ 'count', 'myname’ ])
    3. 单引号里面写的是 你要展示的数据 可以通过 逗号隔开 写上多个
    4. 之后可以在模板当中直接 写 count 就能展示数据了
// store.vue 


 


5. 下面介绍 state, getters, mutations, actions 在页面中的一些用法

5.1 state 上面已经说过就不记录了

5.2 getters

  • getters相当于vue 里面的计算属性 computed.

  • 比如我们往仓库中存放了一个 学生成绩对象数据如:

  • const store = new Vuex.Store({
      ......
      state:{
      ......
      list: [{name:'小米',score:50 },
               {name:'小明 ',score:70 },
               {name:'小王 ',score:60 },
               {name:'小李 ',score:90 } 
              ]
      ......
    })
    
  • 现在 页面上要展示 仓库数据中 学生成绩小于60分的数据 我们可以这样写

  • const store = new Vuex.Store({
      ......
      getters: {//返回成绩低于60的数据
          filterScore(state){
              return state.list.filter( item => item.score < 60 )
          }
      },
      ......
    })
    
  • 在页面当中展示

  • 引入 mapGetters 可以使我们少写代码 import {mapState ,mapGetters} from 'vuex';

  • 在计算属性中写 ...mapGetters(['filterScore']) 中括号写 要展示到 模板上的 数据

  • // store.vue
    
    
     
    
    

5.3 mutations 不能做异步操作

  • mutations 是修改仓库数据的地方 在里面定义方法 通过触发里面的方法来修改仓库数据

  • 仓库里面有 count:100 的数据,现在我们做一个简单的计数器

  • 首先在 mutations 里面写好要操作的方法

  • const store = new Vuex.Store({
      ......
      state:{
      ......
      count:100,
      ......
      },
      mutations:{
          // 定义加法方法 方法里面可以接受2个参数(state,options)
        // options 通常作为一个对象传入进此方法 
        // state 为当前仓库数据 
        // { num } 是es6结构写法 传过来的对象中包含 num ,那么可以用此方法结构出来
        increment(state,{num}) {
          state.count += num;
        },
        decrement(state, {num}) {
          state.count += num;
        },
      }
      ......
    })
    
  • 在模板中使用出来

  • 定义两个 方法 sub(), add(),

  • 改变仓库中的数据就是提交 mutations

  • 触发 mutations 里面的方法 有两种方式

    1. this.$store.commit('increment',{num:1});// 提交到仓库中的 increment 里面进行数据修改, {num:1} 作为参数传入进去

    2. 第二种通过 mapMutations 不同与 mapState 和 mapGetters 这两种是在计算属性中书写出来, mapMutations 必须写在方法当中 也就是 methods 里面比如

    3. ...... 
      methods: {
          // 这样写好之后可以直接在 模板中使用
          //比如 @cliick='increment({num:1})'
          /*
           
              {{count}}
            
          */
          // 也可以在方法当中使用 
          /*
          add(){
            // this.increment({num:123})
          },
          */
          ...mapMutations(['increment']),
          add(){
            // this.increment({num:123})
          },
      ......
      
  • //store.vue
    
    
     
    
    
    

5.4 action 可以做异步

  • 在仓库中书写 action 代码

  • 我们通过 发送一个登录请求来改变 testname 的名字

  • // index.js   
    ......
    //  因为要发送请求,所以仓库中引入 axios
    import axios from '../utils/axios'
    
    const store = new Vuex.Store({
      ......
      state:{
      ......
      testname:'测试名字',
      ......
      },
      mutations:{
        // actions 里面提交并触发此方法 修改仓库数据
        changeName(state, {user}) {
          state.testname = user;
        }
      },
      actions:{
          async handleLogin({commit},{user,pwd}){
          let url = '/login';
          let a1 = await axios.post(url,{username:user,password:pwd});
          // a1.status === 'ok' 表示登录成功 可以修改用户名
          if (a1.status === 'ok'){
            // 我们把仓库中的 testname 改成用户登录的用户名
            // actin 里面可以做异步操作,但是不能直接修改仓库数据
            // 必须提交到 mutations 里面去修改
            commit('changeName',{user});
          }
        }
      }
      ......
    })
      
    
    
  • 触发 action 里面的方法 有两种方式

    1. this.$store.dispatch('handleLogin')
      
    2. 也可以通过 引入 mapActions

    3. import {mapActions} from 'vuex';
      ...... 
      methods: {
          ...mapActions(['handleLogin']),
          // 这样写好之后可以直接在 模板中使用
          //比如  @click="handleLogin({user,pwd})"
          /*
        
          */
          // 也可以在方法当中使用 
          /*
          
          login(){
            this.$store.dispatch('handleLogin',
            {user:this.user,pwd:this.pwd});
            console.log('登录');
          }
          */
      
      ......
      
  1. // store.vue 
    
    
     
    
    
  • 官网说明

  • import { mapActions } from 'vuex'
    
    export default {
      // ...
      methods: {
        ...mapActions([
          'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
    
          // `mapActions` 也支持载荷:
          'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
        ]),
        ...mapActions({
          add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
        })
      }
    }
    

gitee 项目地址 : git clone https://gitee.com/lil-kz/vuecli4.git

你可能感兴趣的:(vuex)