当前位置:   article > 正文

vuex的一些面试题_vue x面试题

vue x面试题

1、vuex有哪几种属性?

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

2、vuex的State特性是?

​ Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的datastate里面存放的数据是响应式的,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?

​ Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法是提交mutation,

​ 例:

this.$store.commit('SET_VIDEO_PAUSE', video_pause),SET_VIDEO_PAUSE为mutations属性中定义的方法 。
  • 1

Vuex解决了什么问题?

解决两个问题

  • 多个组件依赖于同一状态时,对于多层嵌套的组件的传参将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
  • 来自不同组件的行为需要变更同一状态。以往采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

什么时候用Vuex?

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

  • 多个组件依赖于同一状态时。
  • 来自不同组件的行为需要变更同一状态。

怎么引用Vuex?

  • 先安装依赖nnpm install vuex --save

  • 在项目目录src中建立store文件夹

  • 在store文件夹下新建index.js文件,写入

import Vuex from 'vuex';
Vue.use(Vuex);
// 不是在生产环境debug为true
const debug = process.env.NODE_ENV !== 'production';
// 创建Vuex实例对象
const store = new Vuex.Store({
  strict:debug,// 在不是生产环境下都开启严格模式
  state:{
  },
  getters:{
  },
  mutations:{
  },
  actions:{
  }
})
export default store;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

· 然后再main.js文件中引入Vuex,这么写

import Vue from 'vue';
import App from './App.vue';
import store from './store';
const vm = new Vue({
  store:store,
  render: h => h(App)
}).$mount('#app') 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Vuex的5个核心属性是什么?

​ 分别是 state、getters、mutations、actions、modules 。

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

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

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

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

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

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

import {mapState} from 'vuex'
export default{
  computed:{
    ...mapState(['price','number'])
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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
    }
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

computed: {
  total() {
    return this.$store.getters.total
  },
  discountTotal() {
    return this.$store.getters.discountTotal
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

怎么通过getter来实现在组件内可以通过特定条件来获取state的状态?

​ 通过让getter返回一个函数,来实现给getter传参。然后通过参数来进行判断从而获取state中满足要求的状态。

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    getTodoById: (state) => (id) =>{
      return state.todos.find(todo => todo.id === id)
    }
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

computed: {
  getTodoById() {
    return this.$store.getters.getTodoById
  },
}
mounted(){
  console.log(this.getTodoById(2).done)//false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

怎么在组件中批量使用Vuex的getter属性

​ 使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中

import {mapGetters} from 'vuex'
export default{
  computed:{
    ...mapGetters(['total','discountTotal'])
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

怎么在组件中批量给Vuex的getter属性取别名并使用

​ 使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中

import {mapGetters} from 'vuex'
export default{
  computed:{
    ...mapGetters({
      myTotal:'total',
      myDiscountTotal:'discountTotal',
    })
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在Vuex的state中有个状态number表示货物数量,在组件怎么改变它。

​ 首先要在mutations中注册一个mutation

const store = new Vuex.Store({
  state: {
    number: 10,
  },
  mutations: {
    SET_NUMBER(state,data){
      state.number=data;
    }
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

​ 在组件中使用this.$store.commit提交mutation,改变number

this.$store.commit('SET_NUMBER',10)
  • 1

在Vuex中使用mutation要注意什么。

​ mutation 必须是同步函数

在组件中多次提交同一个mutation,怎么写使用更方便。

​ 使用mapMutations辅助函数,在组件中这么使用

import { mapMutations } from 'vuex'
methods:{
  ...mapMutations({
    setNumber:'SET_NUMBER',
  })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

​ 然后调用this.setNumber(10)相当调用this.$store.commit(‘SET_NUMBER’,10)

Vuex中action和mutation有什么区别?

  • action 提交的是 mutation,而不是直接变更状态。mutation可以直接变更状态。
  • action 可以包含任意异步操作。mutation只能是同步操作。
  • 提交方式不同,action 是用this. s t o r e . d i s p a t c h ( ′ A C T I O N N A M E ′ , d a t a ) 来 提 交 。 m u t a t i o n 是 用 t h i s . store.dispatch('ACTION_NAME',data)来提交。mutation是用this. store.dispatch(ACTIONNAME,data)mutationthis.store.commit(‘SET_NUMBER’,10)来提交。
  • 接收参数不同,mutation第一个参数是state,而action第一个参数是context,其包含了
{
  state,   // 等同于 `store.state`,若在模块中则为局部状态
  rootState, // 等同于 `store.state`,只存在于模块中
  commit,   // 等同于 `store.commit`
  dispatch,  // 等同于 `store.dispatch`
  getters,  // 等同于 `store.getters`
  rootGetters // 等同于 `store.getters`,只存在于模块中
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

​ 第二参数都可以接收外部提交时传来的参数。this. s t o r e . d i s p a t c h ( ′ A C T I O N N A M E ′ , d a t a ) 和 t h i s . store.dispatch('ACTION_NAME',data)和this. store.dispatch(ACTIONNAME,data)this.store.commit(‘SET_NUMBER’,10)

在组件中多次提交同一个action,怎么写使用更方便。

​ 使用mapActions辅助函数,在组件中这么使用

methods:{
  ...mapActions({
    setNumber:'SET_NUMBER',
  })
}
  • 1
  • 2
  • 3
  • 4
  • 5

​ 然后调用this.setNumber(10)相当调用this.$store.dispatch(‘SET_NUMBER’,10)

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(() => {
 // ...
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

​ 利用ES6的async和await来实现。

actions:{
  async actionA({commit}){
    //...
  },
  async actionB({dispatch}){
    await dispatch ('actionA')//等待actionA完成
    // ...
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

有用过Vuex模块吗,为什么要使用,怎么使用。

​ 有,因为使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。所以将 store 分割成模块(module)。每个模块拥有自己的 state、mutations、actions、getters,甚至是嵌套子模块,从上至下进行同样方式的分割。

​ 在module文件新建moduleA.js和moduleB.js文件。在文件中写入

const state={
  //...
}
const getters={
  //...
}
const mutations={
  //...
}
const actions={
  //...
}
export default{
  state,
  getters,
  mutations,
  actions
}

然后再index.js引入模块

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import moduleA from './module/moduleA'
import moduleB from './module/moduleB'
const store = new Vuex.Store({
  modules:{
    moduleA,
    moduleB
  }
})
export default store
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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

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

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

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

在组件中怎么访问Vuex模块中的getter和state,怎么提交mutation和action?

  • 直接通过this. s t o r e . g e t t e r s 和 t h i s . store.getters和this. store.gettersthis.store.state来访问模块中的getter和state。
  • 直接通过this.$store.commit(‘mutationA’,data)提交模块中的mutation。
  • 直接通过this.$store.dispatch(‘actionA,data’)提交模块中的action。

用过Vuex模块的命名空间吗?为什么使用,怎么使用。

​ 默认情况下,模块内部的action、mutation和getter是注册在全局命名空间,如果多个模块中action、mutation的命名是一样的,那么提交mutation、action时,将会触发所有模块中命名相同的mutation、action。

​ 这样有太多的耦合,如果要使你的模块具有更高的封装度和复用性,你可以通过添加namespaced: true 的方式使其成为带命名空间的模块。

export default{
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

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

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

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

actions: {
  actionA: {
    root: true,
    handler (context, data) { ... }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

组件中怎么提交modules中的带命名空间的moduleA中的mutationA?

this.$store.commit('moduleA/mutationA',data)
  • 1

怎么使用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'
    ])
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在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]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

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

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

<input v-model="message">
// ...
computed: {
  message: {
    get () {
      return this.$store.state.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

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

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

const store = new Vuex.Store({
  strict:true,
})
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/257111
推荐阅读
相关标签
  

闽ICP备14008679号