• 三年经验前端vue面试记录


    router-link和router-view是如何起作用的

    分析

    vue-router中两个重要组件router-linkrouter-view,分别起到导航作用和内容渲染作用,但是回答如何生效还真有一定难度

    回答范例

    1. vue-router中两个重要组件router-linkrouter-view,分别起到路由导航作用和组件内容渲染作用
    2. 使用中router-link默认生成一个a标签,设置to属性定义跳转path。实际上也可以通过custom和插槽自定义最终的展现形式。router-view是要显示组件的占位组件,可以嵌套,对应路由配置的嵌套关系,配合name可以显示具名组件,起到更强的布局作用。
    3. router-link组件内部根据custom属性判断如何渲染最终生成节点,内部提供导航方法navigate,用户点击之后实际调用的是该方法,此方法最终会修改响应式的路由变量,然后重新去routes匹配出数组结果,router-view则根据其所处深度deep在匹配数组结果中找到对应的路由并获取组件,最终将其渲染出来。

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

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。vuex 就是一个仓库,仓库里放了很多对象。其中 state 就是数据源存放地,对应于一般 vue 对象里面的 data 里面存放的数据是响应式的,vue 组件从 store 读取数据,若是 store 中的数据发生改变,依赖这相数据的组件也会发生更新它通过 mapState 把全局的 stategetters 映射到当前组件的 computed 计算属性

    • vuex 一般用于中大型 web 单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用 vuex 的必要性不是很大,因为完全可以用组件 prop 属性或者事件来完成父子组件之间的通信,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据。
    • 使用Vuex解决非父子组件之间通信问题 vuex 是通过将 state 作为数据中心、各个组件共享 state 实现跨组件通信的,此时的数据完全独立于组件,因此将组件间共享的数据置于 State 中能有效解决多层级组件嵌套的跨组件通信问题

    vuexState 在单页应用的开发中本身具有一个“数据库”的作用,可以将组件中用到的数据存储在 State 中,并在 Action 中封装数据读写的逻辑。这时候存在一个问题,一般什么样的数据会放在 State 中呢? 目前主要有两种数据会使用 vuex 进行管理:

    • 组件之间全局共享的数据
    • 通过后端异步请求的数据

    包括以下几个模块

    • stateVuex 使用单一状态树,即每个应用将仅仅包含一个store 实例。里面存放的数据是响应式的,vue 组件从 store 读取数据,若是 store 中的数据发生改变,依赖这相数据的组件也会发生更新。它通过 mapState 把全局的 stategetters 映射到当前组件的 computed 计算属性
    • mutations:更改Vuexstore中的状态的唯一方法是提交mutation
    • gettersgetter 可以对 state 进行计算操作,它就是 store 的计算属性虽然在组件内也可以做计算属性,但是 getters 可以在多给件之间复用如果一个状态只在一个组件内使用,是可以不用 getters
    • actionaction 类似于 muation, 不同在于:action 提交的是 mutation,而不是直接变更状态action 可以包含任意异步操作
    • modules:面对复杂的应用程序,当管理的状态比较多时;我们需要将vuexstore对象分割成模块(modules)

    modules:项目特别复杂的时候,可以让每一个模块拥有自己的statemutationactiongetters,使得结构非常清晰,方便管理

    回答范例

    思路

    • 给定义
    • 必要性阐述
    • 何时使用
    • 拓展:一些个人思考、实践经验等

    回答范例

    1. Vuex 是一个专为 Vue.js 应用开发的 状态管理模式 + 库 。它采用集中式存储,管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
    2. 我们期待以一种简单的“单向数据流”的方式管理应用,即状态 -> 视图 -> 操作单向循环的方式。但当我们的应用遇到多个组件共享状态时,比如:多个视图依赖于同一状态或者来自不同视图的行为需要变更同一状态。此时单向数据流的简洁性很容易被破坏。因此,我们有必要把组件的共享状态抽取出来,以一个全局单例模式管理。通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。这是vuex存在的必要性,它和react生态中的redux之类是一个概念
    3. Vuex 解决状态管理的同时引入了不少概念:例如statemutationaction等,是否需要引入还需要根据应用的实际情况衡量一下:如果不打算开发大型单页应用,使用 Vuex 反而是繁琐冗余的,一个简单的 store 模式就足够了。但是,如果要构建一个中大型单页应用,Vuex 基本是标配。
    4. 我在使用vuex过程中感受到一些等

    可能的追问

    1. vuex有什么缺点吗?你在开发过程中有遇到什么问题吗?
    • 刷新浏览器,vuex中的state会重新变为初始状态。解决方案-插件 vuex-persistedstate
    1. actionmutation的区别是什么?为什么要区分它们?
    • action中处理异步,mutation不可以
    • mutation做原子操作
    • action可以整合多个mutation的集合
    • mutation 是同步更新数据(内部会进行是否为异步方式更新数据的检测) $watch 严格模式下会报错
    • action 异步操作,可以获取数据后调佣 mutation 提交最终数据
    • 流程顺序:“相应视图—>修改State”拆分成两部分,视图触发ActionAction再触发Mutation`。
    • 基于流程顺序,二者扮演不同的角色:Mutation:专注于修改State,理论上是修改State的唯一途径。Action:业务代码、异步请求
    • 角色不同,二者有不同的限制:Mutation:必须同步执行。Action:可以异步,但不能直接操作State
    三、分类

    slot可以分来以下三种:

    • 默认插槽
    • 具名插槽
    • 作用域插槽

    1. 默认插槽

    子组件用标签来确定渲染的位置,标签里面可以放DOM结构,当父组件使用的时候没有往插槽传入内容,标签内DOM结构就会显示在页面

    父组件在使用的时候,直接在子组件的标签内写入内容即可

    子组件Child.vue

    <template>
        <slot>
          <p>插槽后备的内容p>
        slot>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    父组件

    <Child>
      <div>默认插槽div>  
    Child>
    
    • 1
    • 2
    • 3

    2. 具名插槽

    子组件用name属性来表示插槽的名字,不传为默认插槽

    父组件中在使用时在默认插槽的基础上加上slot属性,值为子组件插槽name属性值

    子组件Child.vue

    <template>
        <slot>插槽后备的内容slot>
      <slot name="content">插槽后备的内容slot>
    template>
    
    • 1
    • 2
    • 3
    • 4

    父组件

    <child>
        <template v-slot:default>具名插槽template>
        
        <template v-slot:content>内容...template>
    child>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3. 作用域插槽

    子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件v-slot接受的对象上

    父组件中在使用时通过v-slot:(简写:#)获取子组件的信息,在内容中使用

    子组件Child.vue

    <template> 
      <slot name="footer" testProps="子组件的值">
              <h3>没传footer插槽h3>
        slot>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    父组件

    <child> 
        
        <template v-slot:default="slotProps">
          来⾃⼦组件数据:{{slotProps.testProps}}
        template>
        <template #default="slotProps">
          来⾃⼦组件数据:{{slotProps.testProps}}
        template>
    child>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    小结:

    • v-slot属性只能在