zoukankan      html  css  js  c++  java
  • Vue —— 精讲 VueX (1)

    大纲

    这一讲我们最主要的就是学习vue中的数据管理VueX,这个是一个大杀器

    demo源代码地址 https://github.com/BM-laoli/BMlaoli-learn-VueX

    一、回顾一些Promise相关的东西

    Promise 有几个比较重要的方法,最重要的还是有一个叫做all的方法,这个也是非常的强大的

    假设我们目前要求,希望能按顺序的拿到先后的两个ajax那么我应该怎么处理呢

    Promse.all( [
    new Promose( ( resolve,rejcet ) => {
            $.ajax({
                url:'xxxx',
                data:'xxxx',
                sucess:(res) => {
                    resolve(res)
                }
            })
            $.ajax({
                url:'xxxx',
                data:'xxxx',
                sucess:(res) => {
                    resolve(res)
                }
            })
        })
    
    ]).then( results => {
        consel.log(results)
        // 这样拿到的就是一个数组了, 先后的顺序就是里面的值
    } )
    

    注意啊这里对promise的深入的解释说明

    1. 首先我们的两个回调resolve 还有reject注意啊,
    这两个回调回调函数是 在传入的时候定义的,但是调用是在promse里调的!这两个参数是函数!!函数!!回调函数!
    
    

    一、概念

    Vue官方介绍
    绝大多数的管方都非常喜欢用概念来解释概念,这就有点难搞了,我这个概念的都不懂,你又给我搞另一个概念
    实际上那个Vuex就是一个大管家,统一进行管理,全局的单例模式

    1.最通俗的解释

    Vuex实际上就是一个 用来放 一些组件共享的数据的,实际上这可能是是下面这些情况

    1. 登录
      假设我们目前有50+页面。我们都每一个页面都要发送接口请求而且这些请求需要token,那么如果我是登录的,我就需要在每一个页面拿到我的登录token这样就造成了数据的传来传去非常麻烦,如果我们有一个公共的地方来放这些东西就好了

    2. 购物车。收藏
      也会有这种组件之间打出传值的情况发生,那么我如何管理这些东西呢,这个就是一个问题

    综上所述,我们需要使用Vuex*

    二、如何入门的使用

    2.简单的使用

    这里假设有这样的一个需求:我们目前有两个组件App.vue 还有BMlaoli.vue 我呢,他们之间有层级的关系,app里面有一个变量叫做contuend 我希望我在app里面对countend的操作能够动态的传递到我们的BMlaoli里,而且不使用父子组件传值,那么我们如何做呢?亲看下面讲演

    1. 首先我们需要有两个组件
      他们都是最基础的样子

    App

    <template>
      <div id="app">
        <h1> 我是vueapp </h1>
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
      }
    }
    </script>
    
    <style>
    </style>
    
    

    BMlaoli

    
    <template>
        <div>
            <h1>我是bm界面</h1>
        </div>
    </template>
    
    <script>
        export default {
            
        }
    </script>
    
    <style lang="sass" scoped>
    
    </style>
    
    1. app的业务逻辑
    <template>
      <div id="app">
        <p>{{contuned}}</p>
        
          <button @click="contuned ++" >+</button>
          <button @click="contuned --" >-</button>
    
      </div>
    </template>
    
    <script>
    
    import bmlao from '@/components/Bmlaoli';
    
    export default {
      name: 'App',
      components: {
        bmlao,
      },
      data() {
        return {
          contuned: 100
        }
      },
    }
    </script>
    
    <style>
    </style>
    
    

    但是问题来了,我目前希望你们在app里面做的更改可以反映到我的Bm组件里,而且不通过父子组件的方式,那么我该怎么做呢?实际上非常的简单

    这个时候我们就需要一个 ‘第三者来处理这个东西’,这个第三者就是这个Vuex。

    1. vueX的引入

    实际上,如果你有手动的安装使用配VueRouter的经验的话。这Vuex也是差不多的都是一样的使用方法

    第一步:npm install vuex
    第二步:创建一个文件夹sote里写一个index.js
    第三部:在index里面安装
    第四部:在main里挂载就好了

    index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    // 安装
    Vue.use(Vuex)
    
    // 使用
    const store = new Vuex.Store({
        state:{},
        mutations: {
        },
        actions:{},
        getters:{},
        modules:{}
    
    })
    
    // 倒出
    export default store
    
    
    

    main.js

    import Vue from 'vue'
    import App from './App.vue'
    
    // 导入
    import Store from './store'
    
    Vue.config.productionTip = false
    
    // 挂载
    new Vue({
      Store,
      render: h => h(App),
    }).$mount('#app')
    
    

    非常的简单

    1. app里的业务逻辑
    <template>
      <div id="app">
        <p>{{ $store.state.contuned }}</p>
        
          <button @click="$store.state.contuned ++" >+</button>
          <button @click="$store.state.contuned --" >-</button>
        
        <h1>------bmlaoli的界面--------</h1>
    
        <bmlao></bmlao>
    
      </div>
    </template>
    
    <script>
    
    import bmlao from '@/components/Bmlaoli';
    
    export default {
      name: 'App',
      components: {
        bmlao,
      },
      data() {
        return {
          // contuned: 100
        }
      },
    }
    </script>
    
    <style>
    </style>
    
    

    三、正确的操作state的方式

    1.需要注意的地方

    $store.state.contuned

    需要非常说的就是 请你不要这样去修改vuex里的值,而是通过如下的方式去修改,详细见官方api说明

    1. 概述我们的更改逻辑
      view视图提交(Dispatch) ----> actions处理异步操作(commit) -----> Muations 记录你的修改 ,方便以后追踪(Mutate) -----> state修改(render)

    2. 代码逻辑
      /state/index.js

        state:{
            contuned:1000
        },
        mutations: {
            increment(state){
                state.contuned++
            },
            decrement(state){
                state.contuned--
            },
        },
        actions:{},
        getters:{},
        modules:{}
    

    /app.vue

    <template>
      <div id="app">
        <p>{{ $store.state.contuned }}</p>
        
          <button @click="additon" >+</button>
          <button @click="subraction" >-</button>
        
        <h1>------bmlaoli的界面--------</h1>
    
        <bmlao></bmlao>
    
      </div>
    </template>
    
    <script>
    
    import bmlao from '@/components/Bmlaoli';
    
    export default {
      name: 'App',
      components: {
        bmlao,
      },
      data() {
        return {
          // contuned: 100
        }
      },
      methods: {
        additon() {
          this.$store.commit('increment')
        },
        subraction() {
          this.$store.commit('decrement')
          
        },
      },
    }
    </script>
    
    <style>
    </style>
    
    
    
    1. 除了使用this.$store.state.XXX或缺vuex的数据之外,我们还有一种方法,也是开发和工作中,比较常见的东西,那就是使用map进行各种数据的映射,它可以映射全部的vuex里面的东西
    // 假设我们现在就使用map把东西数据,state里面的东西,映射到我们的computed里面
    improt { mapState } form 'vuex
    computed {
          ...mapState( ['XXX'] )
             // 但是我们不推荐使用上面得方式,我们更加推荐使用对象器别名的方式
          ...mapState( { xCount:'Count' } )      
    }
    
    ===> 这样你就得到这些State ,除了state之外,其它的mutation 还有getter也是一样的原理
    
    1. 深入立即map的映射原理,

    一个优秀的程序员,不应该只是停留在会用的层面,还应该灵活的掌握其中的原理,只有掌握了原理,才能做到行云流水的开发.工具永远只是工具,只有自己变强才是王道

    ====> 我们一点点的分析,
    // 1. 首先我们得computed需要接受函数
    computed:{
          XXXX:() => {  return this.$stroe.state.XXX }
     }
    // 2. 我们要写一个方法mapState
    function mapState( array ){
         let obj = {}
         array.forEach( stateKey => { obj[stateKey] = () => this.$store.state[stateKey] }  )
         return obj
    }
    // 以上就是内部的实现原理
    

    这样我们就能开发者工具追综这些东西的变化了

    四、核心概念解读

    vueX中有五个核心

    1.单一状态树

    1. 管理系统 现实生活中的例子
      我们先来举一个例子,在我们国家一个人有很多的信息会被记录到档案管理的各个部门,车贷房贷,身份证 ,户口 ,结婚登记,这些信息都分布式的存放在各个局,地产局,户口部门......,这样对于我们的人 来说, 我们的数据来来源就是多样的,多数据源,但是这样有问题,就是一起管理的时候是不好管理的,你可能需要去这个地方盖章,去哪个地方改造,如果不通过又要重新回来盖章,XXXX太麻烦了。
    2. vuex的管理逻辑
      在我们的vue中确确实实 ,你可以new 多个Vuex但是,我们是不推荐的,因为这样管理起来就会非常的麻烦,我们的vuex推荐是 只使用一个vuex来管理共享的数据源,这个设计理念就是;单一数据源(也叫单一状态树)

    2.getter

    这个东西类似于计算属性
    有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:
    高阶函数 ,返回函数的调用

    1. 需求,还是原来的案例,我希望我获取的contuned的平方

    当然了,你这样也是可以的

      <h2>{{ $store.state.contuned * $store.state.contuned }}</h2>
    

    但是很low 是不啦,如果你要写很多很多的复杂逻辑操作,那不就凉凉了吗,所以这里引申出我们的getter,字面理解就是获取的时候,对数据做一些手脚,那么我们看看如何使用

    1. 明确一下,我们的操作基本上都是在我们的vuex文件里面进行的

    在getter里面搞事情
    store/index.js

    
    import Vue from 'vue'
    import Vuex from 'vuex'
    // 安装
    Vue.use(Vuex)
    
    // 使用
    const store = new Vuex.Store({
        state:{
            contuned:1000
        },
        mutations: {
            increment(state){
                state.contuned++
            },
            decrement(state){
                state.contuned--
            },
        },
        actions:{},
        getters:{
            powerCounter(state){
                return state.contuned * state.contuned 
            }
        },
        modules:{}
    
    })
    
    // 倒出
    export default store
    
    

    使用的时候就非常简单了
    /bmlaoli.vue

      <h2>{{ $store.getters.powerCounter }}</h2>
    

    现在我们又有了另一个需求,如果我想传递参数,怎么办,我希望我过滤出一些数据,而且我们希望我们是指定条件的过滤
    这里就涉及到我们的传递参数的问题了
    store/index.js

    
      fliter(state,getters){
        console.log(getters)//这里的getters实际上就是你的整个外面的getters对象 
    
      // 如果你要传递参数,你只能返回函数的调用
          return age => {
            state.students.filter( s => s.age >= age )
          }
        }
    
    

    /bmlaoli.vue

    原数据
     <h2>{{ $store.getters.students }}</h2>
    过滤之后
     <h2>{{ $store.getters.fliter(40) }}</h2>
    

    3.mutation

    vuex唯一更新状态的方式,就是在这里,如果你要更改数据,vuex唯一的更改方式就是 mutation

    3.1 概念

    事件类型(函数名)
    回调函数(回调函数,具体的业务代码)

    mutations: {
    //      increment 事件类型
    // (state){ 回调函数
                // state.contuned++
            // },
            increment(state){
                state.contuned++
            },
    
            decrement(state){
                state.contuned--
            },
        },
    

    3.2 传递参数payload负载

    1. 单个参数
    2. 多参数(传递对象)

    需求:我们希望点击更改状态的时候的时候可传入参数
    /sotre/index.js

    
       mutations: {
            increment(state){
                state.contuned++
            },
            decrement(state){
                state.contuned--
            },
            incrementCour(state,palyload){
                consle.log(palyload)//拿到了一个传递过来的对象
            }
        },
    
    

    bmlaoliu.vue3

    addcCount(parmas){
    this.$sore.commit( 'incrementCour' ,palyload)
    }
    
  • 相关阅读:
    五步搞定Android开发环境部署
    centos7安装MongoDB3.4
    java数据结构之三叉链表示的二叉树
    java数据结构之二叉树遍历的非递归实现
    java数据结构之二叉树的定义和递归实现
    java数据结构之树
    java数据结构之递归算法
    java数据结构之(堆)栈
    redis主从复制配置
    Redis 发布订阅
  • 原文地址:https://www.cnblogs.com/BM-laoli/p/13095214.html
Copyright © 2011-2022 走看看