精华内容
下载资源
问答
  • Vuex状态管理模式的面试题及答案

    千次阅读 多人点赞 2018-05-16 11:14:17
    1、vuex有哪几种属性? 答:有五种,分别是 State、 Getter、Mutation 、Action、 Module 2、vuex的State特性是? 答: 一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,1、vuex有哪几种...
    1、vuex有哪几种属性? 答:有五种,分别是 State、 Getter、Mutation 、Action、 Module 2、vuex的State特性是? 答: 一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,
    1、vuex有哪几种属性?
    答:有五种,分别是 State、 Getter、Mutation 、Action、 Module


    2、vuex的State特性是?
    答:
    一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
    二、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
    三、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中


    3、vuex的Getter特性是?
    答:
    一、getters 可以对State进行计算操作,它就是Store的计算属性
    二、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
    三、 如果一个状态只在一个组件内使用,是可以不用getters


    4、vuex的Mutation特性是?
    答:
    一、Action 类似于 mutation,不同在于:
    二、Action 提交的是 mutation,而不是直接变更状态。
    三、Action 可以包含任意异步操作



    5、Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
    答:
    一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
    二、如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。


    6、不用Vuex会带来什么问题?
    答:

    一、可维护性会下降,你要想修改数据,你得维护三个地方

    二、可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的

    三、增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

    但兄弟组件有大量通信的,建议一定要用,不管大项目和小项目,因为这样会省很多事

    展开全文
  • Vuex状态管理总结

    2020-04-19 13:48:48
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 Vuex是什么? Vuex官方解释: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种...

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

    Vuex是什么?

    Vuex官方解释:

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    有点抽象?可以这么理解

    可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。再将这个对象放在顶层的Vue实例中,让其他组件可以使用。那么多个组件就可以共享这个对象中的所有变量属性了。

    可不可以自己封装一个对象实现相同的功能?

    当然可以,但是Vue的一大核心是响应式,即Vuex是经过响应式处理的,自己封装的话要处理响应式,显得非常复杂,所以直接使用Vuex插件比较方便。

    项目中哪些场景会用到Vuex?

    用户登陆信息、商品收藏和购物车商品信息等,这些信息都是要在多个页面即多个组件之间进行共享的,如果用一般的组件通信方式传递信息就会显得非常繁杂,这时就可以用Vuex将这些多组件共享的信息抽取出来统一管理。

    核心思想:把组件的共享状态抽取出来,以一个全局单例模式管理

    Vuex的五大核心属性

    • state 单一状态树,存放状态信息的地方
    • getters 加工state成员,类似于计算属性
    • mutations 状态更新的唯一方式
    • actions 代替 mutations 进行异步操作
    • modules 模块化状态管理

    下面详细介绍各个属性的作用:

    一、state

    const store = new Vuex.Store({
      state:{
      name:'CC' //需要统一管理的状态信息
      } 
    })
    

    可以在将共享信息存放在 state 里面进行统一管理,然后在组件中通过this.$store.state.name 就能取到里面的信息。

    二、getters

    const store = new Vuex.Store({
      state:{
        name:'CC' //需要统一管理的状态信息
      } 
    
      getters:{
        nameInfo(state){
          return "姓名:"+state.name //返回格式 姓名:CC
        }
    })
    

    类似于计算属性,对 state 里的信息进行加工再提供给组件,组件中使用this.$store.getters.nameInfo
    Getters中的方法有两个默认参数:
    state 当前VueX对象中的状态对象
    getters 当前getters对象,用于将getters下的其他getter拿来用
    例如:

    getters:{
        nameInfo(state){
            return "姓名:"+state.name
        },
        fullInfo(state,getters){
            return getters.nameInfo+'年龄:'+state.age
        }  //返回格式 姓名:CC 年龄:state.age
    }
    

    三、mutations

    const store = new Vuex.Store({
      state:{
        name:'CC' //需要统一管理的状态信息
      } 
    
      getters:{
        nameInfo(state){
          return "姓名:"+state.name //返回格式 姓名:CC
        }
        
      mutations:{
        edit(state){
          state.name = 'jack' //更新状态信息
            }
        }
    })
    
    

    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,组件中使用方式:

    this.$store.commit('edit') //不用传参时
    //需要传参时用下面方式,这里的 payload 称为载荷
    this.$store.commit('edit',{age:15,sex:'男'})
    //或
    this.$store.commit({
        type:'edit',
        payload:{
            age:15,
            sex:'男'
        }
    })
    

    Mutations 需遵守 Vue 的响应规则

    既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:

    (1)最好提前在你的 store 中初始化好所有所需属性。

    (2)当需要在对象上添加新属性时,应该:

    添加:例如对state对象中添加一个age成员 Vue.set(state,"age",15)
    或者以新对象替换老对象的方式。state = { ...state, age: 15 }

    删除:将刚刚添加的age成员删除:Vue.delete(state,'age')

    Mutations 必须是同步函数

    在 Mutations 进行异步操作的话,Vue开发工具VueDevtools追踪不到状态的改变,就无法进行准确的debug。

    四、actions

    const store = new Vuex.Store({
      state,
      getters,
      mutations,
      
      actions:{
        aEdit(context,payload){
            setTimeout(()=>{
                context.commit('edit',payload) //执行Mutations的commit,不能直接修改状态
            },2000)
          }
        }
    })
    
    
    

    代替 mutations 进行异步操作(Action 提交的是 mutation,而不是直接变更状态),也可以将一些复杂的更新方法放在里面,组件中使用方式:this.$store.dispatch('aEdit',{age:15})
    :Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。context 对象不是 store 实例本身,之后介绍到 Modules会说明。

    五、modules

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    

    使用 modules 需要注意的几个细节

    (1)对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。

    const moduleA = {
      state: { count: 0 },
      mutations: {
        increment (state) {
          // 这里的 `state` 对象是模块的局部状态,即moduleA的状态
          state.count++
        }
      }
    }
    

    (2)同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:(可以看出context 对象不是 store 实例本身)

    const moduleA = {
    
      actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
          if ((state.count + rootState.count) % 2 === 1) {
            commit('increment')
          }
        }
      }
    }
    

    (3)对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:

    const moduleA = {
    
      getters: {
        sumWithRootCount (state, getters, rootState) {
          return state.count + rootState.count
        }
      }
    }
    

    命名空间

    默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

    如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例如:

    const moduleA = {
      namespaced: true
      state: { ... },  //不影响
      mutations: { login () { ... } },  //名字变为a/login,则调用时commit('a/login')
      actions: { ... },
      getters: { ... }
    }
    

    重点原则:如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

    若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

    模块化+命名空间之后, 数据都是相对独立的, 如何在模块 A 调用 模块 B 的state, actions, mutations, getters(腾讯面试题)

    (关于这块内容不太好理解,请参考官方文档以及推荐一篇博客:大型Vuex项目 ,使用module后, 如何调用其他模块的 属性值和方法?

    项目中具体使用细节

    安装Vuex插件

    npm i vuex -s
    

    项目目录规范:

    store:.
    │  actions.js
    │  getters.js
    │  index.js
    │  mutations.js
    

    即把每个属性单独抽取成一个js文件,index.js文件中只放以下内容:

    import Vue from 'vue'
    import Vuex from 'vuex' //es6模块化指令,导入插件
    
    import mutations from './mutations'
    import actions from './actions'
    import getters from './getters'
    
    Vue.use(Vuex) //使用插件
    
    const state = {
      cartList: []
    }
    
    
    const store = new Vuex.Store({
      state,
      mutations,
      actions,
      getters
    })
    

    mutations.js文件举例:

    const mutations = {
      addCart(state, info) { }
    }
    
    export default mutations //es6模块化指令
    

    在Vue全局实例中添加store对象

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

    Vuex工作流程图
    在这里插入图片描述
    (官方Vuex流程图,非常重要,一定要掌握,有利于理解和记忆Vuex的使用,一直觉得组件与Mutions之间要多画一条线表示可以直接commit,而不用总是经过actions)

    什么情况下应该使用 Vuex?

    官方建议

    Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

    如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

    参考文献:
    Vuex官方文档
    VueX(Vue状态管理模式)

    展开全文
  • vuex的常见面试

    千次阅读 多人点赞 2021-09-29 14:17:17
    答:Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。(公共数据库) 当项目遇到以下两种场景时 1. 多个组件依赖于同一状态时。 2. 来自不同组件的行为需要变更同一状态。 解决的问题:多个视图依赖同一...

    1.vuex是什么?怎么使用?哪种功能场景使用它?

    答:Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。(公共数据库)

            当项目遇到以下两种场景时   

            1. 多个组件依赖于同一状态时。

            2. 来自不同组件的行为需要变更同一状态。

    解决的问题:多个视图依赖同一个状态来自不同视图的行为需要变更同一状态适用于中大型的单页面应用。

    2.vuex有哪几种属性?

    答:有五种,分别是 State、 Getter、Mutation 、Action、 Module

            state:存放公共数据的地方;

            getter:获取根据业务场景处理返回的数据;

            mutations:唯一修改state的方法,修改过程是同步的;

            action:异步处理,通过分发操作触发mutation;

            module:将store模块分割,减少代码臃肿;

    3.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

    答:如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。

    如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用。

    4.页面刷新后vuex的state数据丢失怎么解决?

    答:就是放在localStorage 或者就是sessionStorage ,或者借用辅助插vuex-persistedstate。

    5.使用vuex的优势是什么?

    答:其实vuex中的所有功能都能够通过其他的方式进行实现,只不过vuex对这些方法进行了整合处理,使用起来更加便捷,同时也便于维护。

    6.Vuex中状态储存在哪里,怎么改变它?

    答:存储在state中,改变Vuex中的状态的唯一途径就是显式地提交 (commit) mutation。

    7.Vuex中状态是对象时,使用时要注意什么?

    答:因为对象是引用类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许,所以先用深度克隆复制对象,再修改。

    8.怎么在组件中批量使用Vuex的state状态?

    答:使用mapState辅助函数, 利用对象展开运算符将state混入computed对象中

    import {mapState} from 'vuex'
    export default{
        computed:{
            ...mapState(['price','number'])
        }
    }

    9.Vuex中要从state派生一些状态出来,且多个组件使用它,该怎么做,?

    答:使用getter属性,相当Vue中的计算属性computed,只有原状态改变派生状态才会改变。

    getter接收两个参数,第一个是state,第二个是getters(可以用来访问其他getter)。

    const store = new Vuex.Store({
        state: {
            price: 10,
            number: 10,
            discount: 0.7,
        },
        getters: {
            total: state => {
                return state.price * state.number
            },
            discountTotal: (state, getters) => {
                return state.discount * getters.total
            }
        },
    });

    然后在组件中可以用计算属性computed通过this.$store.getters.total这样来访问这些派生转态。

    computed: {
        total() {
            return this.$store.getters.total
        },
        discountTotal() {
            return this.$store.getters.discountTotal
        }
    }

    10.vuex中 划分模块的好处

    答:

    1. state 更为 容易管理 保证了store完整的状态数 又避免了相互之间的state冲突
    2. 命名 操作 state 都变得 扁平 直观

    11.vuex的store特性

    答:

    1. vuex 就是一个仓库 仓库里放了很多对象 其中state就是数据源存放地
    2. state里面存放的数据是 响应式的 vue组件从store读取数据 若是 store中的数据发生改变 依赖这项数据的组件 也会发生更新
    3. 通过 mapState 把全局的state 和 getters 映射到当前组件的 computed中
       

    12.不使用Vuex会带来什么问题

    答:

    1. 可维护性会下降,想修改数据要维护三个地方;
    2. 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
    3. 增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

    13.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

    答:

    1. 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
    2. 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。

    14.页面刷新后vuex的state数据丢失怎么解决?

    答:localStorage 或者就是sessionStorage ,或者借用辅助插vuex-persistedstate

    15.vuex怎么知道state是通过mutation修改还是外部直接修改的?

    答:通过$watch监听mutation的commit函数中_committing是否为true

    16.Vuex中action和mutation有什么相同点?

    答:第二参数都可以接收外部提交时传来的参数。 this.$store.dispatch('ACTION_NAME',data)this.$store.commit('SET_NUMBER',10)

    17.用vue做的项目,用了vue的全家桶吗?vue里面为什么不用jq?

    答:vue+vue-router+vuex+axios+es6+sass

    18.Vuex中action通常是异步的,那么如何知道action什么时候结束呢?

    答:在action函数中返回Promise,然后再提交时候用then处理

    actions:{
        SET_NUMBER_A({commit},data){
            return new Promise((resolve,reject) =>{
                setTimeout(() =>{
                    commit('SET_NUMBER',10);
                    resolve();
                },2000)
            })
        }
    }
    this.$store.dispatch('SET_NUMBER_A').then(() => {
      // ...
    })

    19.Vuex中有两个action,分别是actionA和actionB,其内都是异步操作,在actionB要提交actionA,需在actionA处理结束再处理其它操作,怎么实现?

    答:利用ES6的asyncawait来实现。

    actions:{
        async actionA({commit}){
            //...
        },
        async actionB({dispatch}){
            await dispatch ('actionA')//等待actionA完成
            // ... 
        }
    }

    20.在模块中,getter和mutation接收的第一个参数state,是全局的还是模块的?

    答:第一个参数state是模块的state,也就是局部的state。

    21.在模块中,getter和mutation和action中怎么访问全局的state和getter?

    答:

    • 在getter中可以通过第三个参数rootState访问到全局的state,可以通过第四个参数rootGetters访问到全局的getter。
    • 在mutation中不可以访问全局的satat和getter,只能访问到局部的state。
    • 在action中第一个参数context中的context.rootState访问到全局的state,context.rootGetters访问到全局的getter。

    22.怎么在带命名空间的模块内提交全局的mutation和action?

    答:将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

    this.$store.dispatch('actionA', null, { root: true })
    this.$store.commit('mutationA', null, { root: true })

    23.怎么在带命名空间的模块内注册全局的action?

    答:

    actions: {
        actionA: {
            root: true,
            handler (context, data) { ... }
        }
      }

    24.怎么使用mapState,mapGetters,mapActions和mapMutations这些函数来绑定带命名空间的模块?

    答:首先使用createNamespacedHelpers创建基于某个命名空间辅助函数

    import { createNamespacedHelpers } from 'vuex';
    const { mapState, mapActions } = createNamespacedHelpers('moduleA');
    export default {
        computed: {
            // 在 `module/moduleA` 中查找
            ...mapState({
                a: state => state.a,
                b: state => state.b
            })
        },
        methods: {
            // 在 `module/moduleA` 中查找
            ...mapActions([
                'actionA',
                'actionB'
            ])
        }
    }

    25.Vuex插件有用过吗?怎么用简单介绍一下?

    答:Vuex插件就是一个函数,它接收 store 作为唯一参数。在Vuex.Store构造器选项plugins引入。 在store/plugin.js文件中写入

    export default function createPlugin(param){
        return store =>{
            //...
        }
    }

    然后在store/index.js文件中写入

    import createPlugin from './plugin.js'
    const myPlugin = createPlugin()
    const store = new Vuex.Store({
      // ...
      plugins: [myPlugin]
    })

    26.在Vuex插件中怎么监听组件中提交mutation和action?

    答:

    • 用Vuex.Store的实例方法subscribe监听组件中提交mutation
    • 用Vuex.Store的实例方法subscribeAction监听组件中提交action 在store/plugin.js文件中写入
    • export default function createPlugin(param) {
          return store => {
              store.subscribe((mutation, state) => {
                  console.log(mutation.type)//是那个mutation
                  console.log(mutation.payload)
                  console.log(state)
              })
              // store.subscribeAction((action, state) => {
              //     console.log(action.type)//是那个action
              //     console.log(action.payload)//提交action的参数
              // })
              store.subscribeAction({
                  before: (action, state) => {//提交action之前
                      console.log(`before action ${action.type}`)
                  },
                  after: (action, state) => {//提交action之后
                      console.log(`after action ${action.type}`)
                  }
              })
          }
      }

    然后在store/index.js文件中写入

    import createPlugin from './plugin.js'
    const myPlugin = createPlugin()
    const store = new Vuex.Store({
      // ...
      plugins: [myPlugin]
    })

     

    27.在v-model上怎么用Vuex中state的值?

    答:需要通过computed计算属性来转换。

    <input v-model="message">
    // ...
    computed: {
        message: {
            get () {
                return this.$store.state.message
            },
            set (value) {
                this.$store.commit('updateMessage', value)
            }
        }
    }

     28.Vuex的严格模式是什么,有什么作用,怎么开启?

    在严格模式下,无论何时发生了状态变更且不是由 mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

    在Vuex.Store 构造器选项中开启,如下:

    const store = new Vuex.Store({
        strict:true,
    })

    展开全文
  • 浅析Vuex及相关面试题答案

    千次阅读 2020-04-29 07:30:00
    自从学习了Vue框架,其中必不可少的会用到vuex这个核心插件,而且在做项目的时候,基本都会使用,可能你会使用vuex状态管理,但是对vuex原理存在着或多或少的的疑惑或不解,这篇文章就...

    自从学习了Vue框架,其中必不可少的会用到vuex这个核心插件,而且在做项目的时候,基本都会使用,可能你会使用vuex状态管理,但是对vuex原理存在着或多或少的的疑惑或不解,这篇文章就针对vuex原理进行研究,希望能帮助到大家,如果有不准确的地方,大家多多指教。。。

    Vuex是什么?

    Vuex是专门为Vue服务,用于管理页面的数据状态、提供统一数据操作的生态系统,相当于数据库mongoDB,MySQL等,任何组件都可以存取仓库中的数据。其中vuex类似的 还是有Redux,Redux大多用于React,针对Redux后续在做补充,现在就让我们好好了解下Vuex到底是个啥东西?

    概念理解性(必读)

    Vuex采用MVC模式中的Model层,规定所有的数据必须通过action--->mutaion--->state这个流程进行来改变状态的。再结合Vue的数据视图双向绑定实现页面的更新。统一页面状态管理,可以让复杂的组件交互变的简单清晰,同时在调试时也可以通过DEVtools去查看状态。

    在当前前端的spa模块化项目中不可避免的是某些变量需要在全局范围内引用,此时父子组件的传值,子父组件间的传值,兄弟组件间的传值成了我们需要解决的问题。虽然vue中提供了props(父传子)commit(子传父)兄弟间也可以用localstorage和sessionstorage。但是这种方式在项目开发中带来的问题比他解决的问题(难管理,难维护,代码复杂,安全性低)更多。vuex的诞生也是为了解决这些问题,从而大大提高我们vue项目的开发效率。

    抛出问题 使用Vuex只需执行 Vue.use(Vuex),并在Vue的配置中传入一个store对象的示例,store是如何实现注入的?state内部是如何实现支持模块配置和模块嵌套的?在执行dispatch触发action(commit同理)的时候,只需传入(type, payload),action执行函数中第一个参数store从哪里获取的?如何区分state是外部直接修改,还是通过mutation方法修改的?调试时的“时空穿梭”功能是如何实现的?

    vue和vuex的区别与联系

    看一下这个vue响应式的例子,vue中的data 、methods、computed,可以实现响应式。

    视图通过点击事件,触发methods中的increment方法,可以更改state中count的值,一旦count值发生变化,computed中的函数能够把getCount更新到视图。

    <div id="app">
            <button @click="increment"></button>
            {{getcount}}
        </app>
        new Vue({
            el: "#app",
            // state
            data () {
             return {
                count: 0
             }
            },
             // view
            computed: {
                getCount(){
                    return this.count
                }
            },
            // actions
            methods: {
             increment () {
                this.count++
             }
            },
        })
    

    那么vuex又和vue这个响应式的例子有什么关系呢?我们可以用vuex实现和vue同样的响应式功能。其实他们原理时一样的,vuex中也有四个属性值:state、getters、mutations、actions。。在没有actions的情况下:数据:state --> data 获取数据:getters --> computed 更改数据:mutations --> methods

    视图通过点击事件,触发mutations中方法,可以更改state中的数据,一旦state数据发生更改,getters把数据反映到视图。

    那么actions,可以理解处理异步,而单纯多加的一层。

    既然提到了mutions actions这时候 就不得不提 commit dispatch,这两个有什么作用呢?

    在vue例子中,通过click事件,触发methods中的方法。当存在异步时,而在vuex中需要dispatch来触发actions中的方法,actions中的commit可以触发mutations中的方法。同步,则直接在组件中commit触发vuex中mutations中的方法。

    下面我们看下vuex中能像vue中实现改变状态,更新视图的功能:

    Vuex.js

    const store =  new Vuex.Store({
        
        state: {
            count: 0
        },
        
        //state的值只能通过mutations来修改
        mutations: {
            increment(state) {
                state.count++
            }
        },
        
       //this.$store.commit("increment")触发mutations中函数"increment"
        actions: {
            increment({commit}) {
                 commit("increment"); //this.$store.commit("increment")
            }
         
        },
        
       //通过getter中的方法来获取state值
        getters: {
            getCount(state) {
                return state.count
            }
        }
        })
         
        export default store
    
    

    App.vue

        <template>
        <div id="app">
                <button @click="increment">增加</button>
                <!-- 有时候不能直接 强制使用store里面的状态 this.$store.state.count -->
                {{this.$store.getters.getCount}}
        </div>
        </template>
         
        <script>
        export default {
            methods: {
            increment(){
                    //this.$store.dispatch("increment")触发actions函数"increment"
                    this.$store.dispatch("increment")
                }
            }
        }
        </script>
    
    

    现在我们已经了解vuex能实现和像vue双向数据绑定--更新试图的功能,下面我们重点说说vuex源码的实现:

    store注入组件install方法

    解答问题:vuex的store是如何注入到组件中的?

    首先使用vuex,需要安装插件:

    Vue.use(Vuex); // vue的插件机制,安装vuex插件
    
    

    当ues(Vuex)时候,会调用vuex中的install方法,装在vuex! 下面时install的核心源码:

    Vue.mixin({
            beforeCreate() {
                if (this.$options && this.$options.store) {
                    //找到根组件 main 上面挂一个$store
                    this.$store = this.$options.store
                    // console.log(this.$store);
    
                } else {
                    //非根组件指向其父组件的$store
                    this.$store = this.$parent && this.$parent.$store
                }
            }
        })
    

    可见,store注入 vue的实例组件的方式,是通过vue的 mixin机制,借助vue组件的生命周期 钩子 beforeCreate 完成的。即 每个vue组件实例化过程中,会在 beforeCreate 钩子前调用 vuexInit 方法。

    解答问题:vuex的state和getters是如何映射到各个组件实例中响应式更新状态呢?

    new vue实现双向数据绑定:

            this._s = new Vue({
                data: {
                    // 只有data中的数据才是响应式
                    state: options.state
                }
            })
    

    getters实现

     //实现getters原理
            let getters = options.getters || {}
            // console.log(getters);
            // this.getters = getters; //不是直接挂载到 getters上 这样只会拿到整个 函数体
            this.getters = {};
            // console.log(Object.keys(getters))  // ["myAge","myName"]
            Object.keys(getters).forEach((getterName) => {
                // console.log(getterName)  // myAge
                // 将getterName 放到this.getters = {}中
                // console.log(this.state);
                Object.defineProperty(this.getters, getterName, {
                    // 当你要获取getterName(myAge)会自动调用get方法
                    // 箭头函数中没有this
                    get: () => {
                        return getters[getterName](this.state)
                    }
                })
            })
    

    从上面源码,我们可以看出Vuex的state状态是响应式,是借助vue的data是响应式,将state存入vue实例组件的data中;Vuex的getters则是借助vue的计算属性computed实现数据实时监听。

    mutations实现

    
    let mutations = options.mutations || {}
            // console.log(mutations);
            this.mutations = {};
            Object.keys(mutations).forEach(mutationName=>{
                // console.log(mutationName);
                
                this.mutations[mutationName] = (payload) =>{
                    this.mutations[mutationName](this.state,payload)
                }
            })
    

    实现同步加:动态效果图:

    actions实现

    // actions的原理
            let actions = options.actions || {}
            this.actions = {};
            forEach(actions,(actionName,value)=>{
                this.actions[actionName] = (payload)=>{
                    value(this,payload)
                }
            })
    

    commit dispatch的实现

        commit(type,payload){
            this.mutations[type](payload)
        }
    
        // type是actions的类型
        dispatch=(type,payload)=>{
            this.actions[type](payload)
        }
    

    原理总结:

    Vuex是通过全局注入store对象,来实现组件间的状态共享。在大型复杂的项目中(多级组件嵌套),需要实现一个组件更改某个数据,多个组件自动获取更改后的数据进行业务逻辑处理,这时候使用vuex比较合适。假如只是多个组件间传递数据,使用vuex未免有点大材小用,其实只用使用组件间常用的通信方法即可。

    常见面试题:

    1、vuex有哪几种属性?
    答:有五种,分别是 State、 Getter、Mutation 、Action、 Module

    2、vuex的State特性是?
    答:
    一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
    二、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
    三、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

    3、vuex的Getter特性是?
    答:
    一、getters 可以对State进行计算操作,它就是Store的计算属性
    二、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
    三、 如果一个状态只在一个组件内使用,是可以不用getters

    4、vuex的Mutation特性是?
    答:
    一、Action 类似于 mutation,不同在于:
    二、Action 提交的是 mutation,而不是直接变更状态。
    三、Action 可以包含任意异步操作

    5、Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
    答:
    一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
    二、如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。

    6、不用Vuex会带来什么问题?
    答:

    一、可维护性会下降,你要想修改数据,你得维护三个地方

    二、可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的

    三、增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

    但兄弟组件有大量通信的,建议一定要用,不管大项目和小项目,因为这样会省很多事

    参考:https://www.cnblogs.com/hjson/p/10500770.html

    展开全文
  • vuex管理状态仓库详解

    2020-08-10 08:31:00
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,...
  • vuex面试题总结

    2021-08-24 19:20:00
    Vuex 面试Vuex中如何异步修改数据 vuex基本使用流程为:在action中分发异步请求 在异步回调中 使用commit 提交mutation在mutation中修改state使用getters对state的值进行计算封装 如何在模块中 访问全局内容 ...
  • VueX是适用于在Vue项目开发时使用的状态管理工具。试想一下,如果在一个项目开发中频繁的使用组件传参的方式来同步data中的值,一旦项目变得很庞大,管理和维护这些值将是相当棘手的工作。为此,Vue为这些被多个组件...
  • Vuex状态管理

    2021-08-17 19:56:25
    state全局存储状态,只可以读,不能进行写操作getters对数据进行处理,类似计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。mutations 是vuex唯一一个可以修改...
  • 面试题(八)vuex常见面试

    千次阅读 2020-10-27 14:34:12
    答:vue框架中状态管理。在 main.js 引入 store,注入。 新建了一个目录store.js,…export。 场景有:单页应用中,组件之间的状态。音乐播放、登陆状态、加入购物车 2.vuex有哪几种属性? 答:有五种,分别是 State...
  • vuex的一些面试

    2021-05-06 18:00:22
    1、vuex有哪几种属性? ​ 答:有五种,分别是State、Getter、Mutation、Action、Module 2、vuex的State特性是? ​ Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面...
  • 前端Vuex面试

    千次阅读 2020-09-03 21:59:51
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法就是在mutaions里修改state,actions不能直接修改state vuex的组成结构示意图: uex的特点是把...
  • Vuex状态管理模式

    2021-08-03 19:14:16
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用**集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测**的方式发生变化。 vuex是采用集中式管理组件依赖的共享数据的一个工具...
  • vuex是一个vue.js应用程序开发的状态管理模式,他采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种预测的方式发生改变。 2.使用vuex的原因 当我们遇到多个组件共享状态时,多层组件的传值非常...
  • 遇见面试--vuex原理

    万次阅读 多人点赞 2019-09-22 17:20:48
    自从学习了VUE框架,其中必不可少的会用到vuex这个核心插件,而且在做项目的时候,基本都会使用,可能你会使用vuex状态管理,但是对vuex原理存在着或多或少的的疑惑或不解,这篇文章就针对vuex原理进行研究,希望能...
  • VUE之VUEX常见面试

    千次阅读 2021-01-15 10:18:42
    答:vue框架中状态管理。在main.js引入store,注入。 新建了一个目录store.js,….. export 。 解决的问题:多个视图依赖同一个状态来自不同视图的行为需要变更同一状态适用于中大型的单页面应用 2.vuex有哪几种...
  • vuex是一个专门为vue.js设计的集中式状态管理架构. 什么是状态?简单来说就是data中需要共用的属性.比如:我们有几个页面要显示用户名和用户等级,购物车信息,或者显示用户的地理位置.如果我们不把这些信息设置为状态,...
  • 它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地方就会自动更新。是不是很方便,很好用呢...
  • vuex面试

    2020-11-25 11:35:23
    在工作面试时,会问到好多关于vuex的知识点,KBK总结了一下,如下: 1. vuex中如何异步修改数据? 首先, 概括下 vuex基本使用流程为: 在action中分发异步请求, 在异步回调中使用commit提交mutation,在mutation中修改...
  • 面试官问道vuex的时候我们只说出它的含义,若想不会...vuex是一个专为vue.js应用程序开发的状态管理模式 2.vuex的核心概念; vuex的属性;vuex五大核心属性:state,getter,mutation,action,module state:存...
  • 面试题-对vuex的理解

    2020-09-16 15:11:51
    面试官问我们对vuex的理解的时候,我们不能只说“vuex是一个专为vue.js应用程序开发的状态管理模式”,尽量不要让面试官连续追问(总会问到自己不会的然后说你实力还差那么点来可以得降薪),应该从三个方面一次...
  • 面试官最喜欢问的Vuex

    2020-04-26 15:18:10
    前言 笔者希望本篇博客的阅读者是使用过Vuex的开发者...Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 文...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,086
精华内容 1,634
热门标签
关键字:

vuex状态管理面试

vue 订阅