精华内容
下载资源
问答
  • Vue3面试题
    千次阅读
    2021-07-19 22:33:56

    1. Vue3 比 vue2 优势

    1. 性能更好
    2. 体积更小
    3. 更好的ts支持
    4. 更好的代码组织
    5. 更好的逻辑抽离
    6. 更多新的功能
    

    2. Vue3 生命周期

    1. Options API生命周期
    2. Composition  API生命周期
    

    3. 如何看待composition API 和options API

    1. Composition API 更好的代码组织,更好的逻辑复用,更好的类型推到
    2. 小型项目,业务逻辑简单,用Options API
    3. 中大型项目,业务逻辑复杂的,用Composition API
    4. Composition API 是为了解决复杂业务逻辑而设计的
    5. 类似React Hooks
    

    4. 如何理解ref toRef和toRefs?

    1. ref
        1. 生成值类型的响应式数据
        2. 可用于模板和reactive
        3. 通过.value修改值
    2. toRef
        1. 针对一个响应式对象(reactive封装)的prop
        2. 创建一个ref,具有响应式
        3. 两者保持引用关系
    3. toRefs,避免模板中导出都是state
        1. 将响应式对象(reactive封装)转换成普通对象
        2. 对象的每个prop都是对应的ref
        3. 两者保持引用关系
    4. 最佳使用方式
        1. 用reactive做对象的响应式,用ref做值类型的响应式
        2. setup中返回toRefs(state),或者toRef(state, 'prop')
        3. ref的变量命名都用xxxRef
        4. 合成函数返回响应式对象时,用toRefs
    

    5. ref toRef toRefs进阶,深入理解

    1. 为何需要ref?
        1. 返回值类型,会丢失响应式
        2. setup、computed、合成函数,都有可能返回值类型
        3. Vue如果不定义ref,用户将自定义ref,反而混乱
    2. 为何需要.value?
        1. ref是一个对象(不丢失响应式),value存储值
        2. 通过.value属性的get和set实现响应式
        3. 用于模板、reactive时,不需要.value,其他情况都需要
    3. 为何需要toRef toRefs
        1. 初衷:不丢失响应式的情况下,把对象数据进行分解和扩散
        2. 前提:针对的事响应式对象,不是普通对象
        3. 注意:不创造响应式,而是延续响应式
    

    6. Vue3 升级了哪些重要的功能?

    1. createApp:创建vue实例的方式
    2. emits属性,组件中的事件要先使用emits进行声明,然后在setup的形参引入
    3. 生命周期
    4. 多事件
    5. fragment:不再限制唯一根节点
    6. 移除.sync:
    7. 异步组件的写法:Vue2 直接import进来,Vue3需要使用defineAsyncComponent包裹一层
    8. 移除filter
    9. teleport:把组件直接to到某个dom
    10. suspense:fallback,就是一个具名插槽
    11. composition API
    

    7. Composition API如何实现代码逻辑复用?

    1. 抽离逻辑代码到一个函数
    2. 函数命名约定为useXXX格式(React Hooks也是)
    3. 在setup中引用useXXX函数
    

    8. Reflect作用

    1. 与proxy能力对应
    2. 规范化,标准化,函数式
    3. 替代Object上的工具函数
    

    9. Vue3 如何实现响应式?

    10. watch和watchEffect的区别是什么?

    1. 二者都可以监听属性变化
    2. watch需要明确监听哪个属性
    3. watchEffect会根据其中的属性,自动监听其变化
    

    11. setup中如何获取组件实例?

    1. setup和其他Composition API中都没有this
    2. 在Options API中仍然可以使用this
    3. Composition API中可以使用getCurrentInstance方法获取
    

    12. Vue3为何比Vue2快?

    1. Proxy实现响应式
    2. patchFlag https://vue-next-template-explorer.netlify.app/
        1. 编译模板时,动态节点做标记
        2. 标记,分为不同的类型,如TEXT,PROPS
        3. diff时,区分静态节点和不同类型的动态节点
    3. hoistStatic
        1. 将静态节点的定义,提升到父作用域,缓存起来,空间换时间
        2. 多个相邻的静态节点,会被合并起来,编译优化
    4. cacheHandler
        缓存事件
    5. SSR优化
        静态节点直接输出为dom,绕过vdom
    6. tree-shaking
        编译时,按需引入API
    

    13. Vite是什么?

    1. 前端打包工具
    2. 在开发环境下,使用ES6 Module,不打包,启动快
    3. 生产环境打包使用rollup
    

    14. Composition API和React Hooks的对比

    1. 前者setup(生命周期create)只会被调用一次,后者函数会被多次调用
    2. 前者无需useMemo,useCallback,因为setup只调用一次
    3. 前者无需考虑调用顺序,后者需要保证hooks的顺序一致
    4. 前者reactive + ref 比后者的useState,要难理解
    
    更多相关内容
  • Vue3 面试题

    千次阅读 2022-01-21 21:08:27
    一、vue3有了解过吗?能说说跟vue2的区别吗? 1. Vue3介绍 关于vue3的重构背景,尤大是这样说的: 「Vue 新版本的理念成型于 2018 年末,当时 Vue 2 的代码库已经有两岁半了。比起通用软件的生命周期来这好像也没...

    一、vue3有了解过吗?能说说跟vue2的区别吗?

    在这里插入图片描述

    1. Vue3介绍

    关于vue3的重构背景,尤大是这样说的:

    「Vue 新版本的理念成型于 2018 年末,当时 Vue 2 的代码库已经有两岁半了。比起通用软件的生命周期来这好像也没那么久,但在这段时期,前端世界已经今昔非比了
    在我们更新(和重写)Vue 的主要版本时,主要考虑两点因素:首先是新的 JavaScript 语言特性在主流浏览器中的受支持水平;其次是当前代码库中随时间推移而逐渐暴露出来的一些设计和架构问题」

    简要就是:

    • 利用新的语言特性(es6)
    • 解决架构问题

    哪些变化:

    • 速度更快
    • 体积减少
    • 更易维护
    • 更接近原生
    • 更易使用

    ⑴. 速度更快

    vue3相比vue2

    • 重写了虚拟Dom实现
    • 编译模板的优化
    • 更高效的组件初始化
    • undate性能提高1.3~2倍
    • SSR速度提高了2~3倍

    ⑵. 体积更小

    通过webpack的tree-shaking功能,可以将无用模块“剪辑”,仅打包需要的

    能够tree-shaking,有两大好处:

    • 对开发人员,能够对vue实现更多其他的功能,而不必担忧整体体积过大
    • 对使用者,打包出来的包体积变小了

    vue可以开发出更多其他的功能,而不必担忧vue打包出来的整体体积过多

    ⑶. 更易维护

    compositon Api

    • 可与现有的Options API一起使用
    • 灵活的逻辑组合与复用
    • Vue3模块可以和其他框架搭配使用

    更好的Typescript支持
    VUE3是基于typescipt编写的,可以享受到自动的类型定义提示

    编译器重写


    ⑷. 更接近原生

    可以自定义渲染 API


    ⑸. 更易使用

    • 响应式 Api 暴露出来
    • 轻松识别组件重新渲染原因

    2. Vue3新增特性

    Vue 3 中需要关注的一些新功能包括:

    • framents
    • Teleport
    • composition Api
    • createRenderer

    ⑴. framents

    在 Vue3.x 中,组件现在支持有多个根节点

    <!-- Layout.vue -->
    <template>
      <header>...</header>
      <main v-bind="$attrs">...</main>
      <footer>...</footer>
    </template>
    

    ⑵. Teleport

    Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术,就有点像哆啦A梦的“任意门”

    在vue2中,像 modals,toast 等这样的元素,如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难

    通过Teleport,我们可以在组件的逻辑位置写模板代码,然后在 Vue 应用范围之外渲染它

    <button @click="showToast" class="btn">打开 toast</button>
    <!-- to 属性就是目标位置 -->
    <teleport to="#teleport-target">
        <div v-if="visible" class="toast-wrap">
            <div class="toast-msg">我是一个 Toast 文案</div>
        </div>
    </teleport>
    

    ⑶. createRenderer

    通过createRenderer,我们能够构建自定义渲染器,我们能够将 vue 的开发模型扩展到其他平台

    我们可以将其生成在canvas画布上

    在这里插入图片描述
    关于createRenderer,我们了解下基本使用,就不展开讲述了

    import { createRenderer } from '@vue/runtime-core'
    
    const { render, createApp } = createRenderer({
      patchProp,
      insert,
      remove,
      createElement,
      // ...
    })
    
    export { render, createApp }
    
    export * from '@vue/runtime-core'
    

    ⑷. composition Api

    composition Api,也就是组合式api,通过这种形式,我们能够更加容易维护我们的代码,将相同功能的变量进行一个集中式的管理

    关于compositon api的使用,这里以下图展开

    在这里插入图片描述
    简单使用:

    export default {
        setup() {
            const count = ref(0)
            const double = computed(() => count.value * 2)
            function increment() {
                count.value++
            }
            onMounted(() => console.log('component mounted!'))
            return {
                count,
                double,
                increment
            }
        }
    }
    

    3. 非兼容变更

    ⑴. Global API

    • 全局 Vue API 已更改为使用应用程序实例
    • 全局和内部 API 已经被重构为可 tree-shakable

    ⑵. 模板指令

    • 组件上 v-model 用法已更改
    • 和 非 v-for节点上key用法已更改
    • 在同一元素上使用的 v-if 和 v-for 优先级已更改
    • v-bind=“object” 现在排序敏感
    • v-for 中的 ref 不再注册 ref 数组

    ⑶. 组件

    • 只能使用普通函数创建功能组件
    • functional 属性在单文件组件 (SFC)
    • 异步组件现在需要 defineAsyncComponent 方法来创建

    ⑷. 渲染函数

    • 渲染函数API改变
    • $scopedSlots property 已删除,所有插槽都通过 $slots 作为函数暴露
    • 自定义指令 API 已更改为与组件生命周期一致
    • 一些转换 class 被重命名了:
    • v-enter -> v-enter-from
    • v-leave -> v-leave-from
    • 组件 watch 选项和实例方法 $watch不再支持点分隔字符串路径,请改用计算函数作为参数
    • 在 Vue 2.x 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。VUE3.x 现在使用应用程序容器的 innerHTML。

    ⑸. 其他小改变

    • destroyed 生命周期选项被重命名为 unmounted
    • beforeDestroy 生命周期选项被重命名为 beforeUnmount
    • [prop default工厂函数不再有权访问 this 是上下文
    • 自定义指令 API 已更改为与组件生命周期一致
    • data 应始终声明为函数
    • 来自 mixin 的 data 选项现在可简单地合并
    • attribute 强制策略已更改
    • 一些过渡 class 被重命名
    • 组建 watch 选项和实例方法 $watch不再支持以点分隔的字符串路径。请改用计算属性函数作为参数。
    • 没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 现在被视为普通元素,并将生成原生的 元素,而不是渲染其内部内容。
    • 在Vue 2.x 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。Vue 3.x 现在使用应用容器的 innerHTML,这意味着容器本身不再被视为模板的一部分。

    ⑹. 移除 API

    • keyCode 支持作为 v-on 的修饰符
    • o n , on, onoff和$once 实例方法
    • 过滤filter
    • 内联模板 attribute
    • $destroy 实例方法。用户不应再手动管理单个Vue 组件的生命周期。



    二、Vue3.0的设计目标是什么?做了哪些优化

    在这里插入图片描述

    1. 设计目标

    不以解决实际业务痛点的更新都是耍流氓,下面我们来列举一下Vue3之前我们或许会面临的问题

    • 随着功能的增长,复杂组件的代码变得越来越难以维护
    • 缺少一种比较「干净」的在多个组件之间提取和复用逻辑的机制
    • 类型推断不够友好
    • bundle的时间太久了

    而 Vue3 经过长达两三年时间的筹备,做了哪些事情?

    我们从结果反推

    • 更小
    • 更快
    • TypeScript支持
    • API设计一致性
    • 提高自身可维护性
    • 开放更多底层功能

    ⑴. 更小

    Vue3移除一些不常用的 API

    引入tree-shaking,可以将无用模块“剪辑”,仅打包需要的,使打包的整体体积变小了


    ⑵. 更快

    主要体现在编译方面:

    • diff算法优化
    • 静态提升
    • 事件监听缓存
    • SSR优化

    ⑶. 更友好

    vue3在兼顾vue2的options API的同时还推出了composition API,大大增加了代码的逻辑组织和代码复用能力

    2. 优化方案

    vue3从很多层面都做了优化,可以分成三个方面:

    • 源码
    • 性能
    • 语法 API

    ⑴. 源码

    源码可以从两个层面展开:

    • 源码管理
    • TypeScript

    ⑵. 性能

    vue3是从什么哪些方面对性能进行进一步优化呢?

    • 体积优化
    • 编译优化
    • 数据劫持优化

    ⑶. 语法 API

    这里当然说的就是composition API,其两大显著的优化:

    • 优化逻辑组织
    • 优化逻辑复用



    三、Vue3.0性能提升主要是通过哪几方面体现的?

    在这里插入图片描述

    1. 编译阶段

    回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发生改变,触发setter,则会通知watcher,从而使关联的组件重新渲染

    在这里插入图片描述
    因此,Vue3在编译阶段,做了进一步优化。主要有如下:

    diff算法优化
    静态提升
    事件监听缓存
    SSR优化

    ⑴. diff算法优化

    vue3在diff算法中相比vue2增加了静态标记

    关于这个静态标记,其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较

    ⑵. 静态提升

    Vue3中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用

    这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用

    ⑵. 事件监听缓存

    默认情况下绑定事件@click行为会被视为动态绑定,所以每次都会去追踪它的变化

    ⑷. SSR优化

    当静态内容大到一定量级时候,会用createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染


    2. 源码体积

    相比Vue2,Vue3整体体积变小了,除了移出一些不常用的API,再重要的是Tree shanking

    任何一个函数,如ref、reavtived、computed等,仅仅在用到的时候才打包,没用到的模块都被摇掉,打包的整体体积变小


    3. 响应式系统

    vue2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式

    vue3采用proxy重写了响应式系统,因为proxy可以对整个对象进行监听,所以不需要深度遍历

    • 可以监听动态属性的添加
    • 可以监听到数组的索引和数组length属性
    • 可以监听删除属性



    四、Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

    在这里插入图片描述

    1. Object.defineProperty

    定义:Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

    为什么能实现响应式:

    通过defineProperty 两个属性,get及set

    get:
    属性的 getter 函数,当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值

    set:
    属性的 setter 函数,当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为 undefined

    小结:

    • 检测不到对象属性的添加和删除
    • 数组API方法无法监听到
    • 需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题

    2. proxy

    Proxy的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性了

    (在 ES6 面试题会会详细讲解 Proxy 的功能…)

    3. 总结

    • Object.defineProperty只能遍历对象属性进行劫持
    • Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的



    五、Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

    在这里插入图片描述

    1. 开始之前

    Composition API 可以说是Vue3的最大特点,那么为什么要推出Composition Api,解决了什么问题?

    通常使用Vue2开发的项目,普遍会存在以下问题:

    • 代码的可读性随着组件变大而变差
    • 每一种代码复用的方式,都存在缺点
    • TypeScript支持有限

    以上通过使用Composition Api都能迎刃而解

    2. Options Api

    Options API,即大家常说的选项API,即以vue为后缀的文件,通过定义methods,computed,watch,data等属性与方法,共同处理页面逻辑

    用组件的选项 (data、computed、methods、watch) 组织逻辑在大多数情况下都有效;然而,当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解

    3. Composition Api

    在 Vue3 Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合)

    即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API


    4. 对比

    面对Composition Api与Options Api进行两大方面的比较

    逻辑组织
    逻辑复用

    ⑴. 逻辑组织

    Options API
    假设一个组件是一个大型组件,其内部有很多处理逻辑关注点,这种碎片化使得理解和维护复杂组件变得困难

    选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块

    Compostion API
    而Compositon API正是解决上述问题,将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去

    再来一张图进行对比,可以很直观地感受到 Composition API在逻辑组织方面的优势,以后修改一个属性功能的时候,只需要跳到控制该属性的方法中即可
    在这里插入图片描述

    ⑵. 逻辑复用

    在Vue2中,我们是用过mixin去复用相同的逻辑

    下面举个例子,我们会另起一个mixin.js文件

    export const MoveMixin = {
      data() {
        return {
          x: 0,
          y: 0,
        };
      },
    
      methods: {
        handleKeyup(e) {
          console.log(e.code);
          // 上下左右 x y
          switch (e.code) {
            case "ArrowUp":
              this.y--;
              break;
            case "ArrowDown":
              this.y++;
              break;
            case "ArrowLeft":
              this.x--;
              break;
            case "ArrowRight":
              this.x++;
              break;
          }
        },
      },
    
      mounted() {
        window.addEventListener("keyup", this.handleKeyup);
      },
    
      unmounted() {
        window.removeEventListener("keyup", this.handleKeyup);
      },
    };
    

    然后在组件中使用

    <template>
      <div>
        Mouse position: x {{ x }} / y {{ y }}
      </div>
    </template>
    <script>
    import mousePositionMixin from './mouse'
    export default {
      mixins: [mousePositionMixin]
    }
    </script>
    

    使用单个mixin似乎问题不大,但是当我们一个组件混入大量不同的 mixins 的时候

    mixins: [mousePositionMixin, fooMixin, barMixin, otherMixin]
    

    会存在两个非常明显的问题:

    • 命名冲突
    • 数据来源不清晰

    现在通过Compositon API这种方式改写上面的代码
    import { onMounted, onUnmounted, reactive } from "vue";
    export function useMove() {
      const position = reactive({
        x: 0,
        y: 0,
      });
    
      const handleKeyup = (e) => {
        console.log(e.code);
        // 上下左右 x y
        switch (e.code) {
          case "ArrowUp":
            // y.value--;
            position.y--;
            break;
          case "ArrowDown":
            // y.value++;
            position.y++;
            break;
          case "ArrowLeft":
            // x.value--;
            position.x--;
            break;
          case "ArrowRight":
            // x.value++;
            position.x++;
            break;
        }
      };
    
      onMounted(() => {
        window.addEventListener("keyup", handleKeyup);
      });
    
      onUnmounted(() => {
        window.removeEventListener("keyup", handleKeyup);
      });
    
      return { position };
    }
    

    可以看到,整个数据来源清晰了,即使去编写更多的 hook 函数,也不会出现命名冲突的问题

    小结:

    • 在逻辑组织和逻辑复用方面,Composition API是优于Options API
    • 因为Composition API几乎是函数,会有更好的类型推断。
    • Composition API对 tree-shaking 友好,代码也更容易压缩
    • Composition API中见不到this的使用,减少了this指向不明的情况
    • 如果是小型组件,可以继续使用Options API,也是十分友好的



    六、说说Vue 3.0中Treeshaking特性?举例说明一下?

    在这里插入图片描述

    1. 是什么

    Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination

    简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码

    在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到

    而Vue3源码引入tree shaking特性,将全局 API 进行分块。如果您不使用其某些功能,它们将不会包含在您的基础包中


    2. 如何做

    Tree shaking是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量

    Tree shaking无非就是做了两件事:

    • 编译阶段利用ES6 Module判断哪些模块已经加载
    • 判断那些模块和变量未被使用或者引用,进而删除对应代码

    3. 作用

    通过Tree shaking,Vue3给我们带来的好处是:

    • 减少程序体积(更小)
    • 减少程序执行时间(更快)
    • 便于将来对程序架构进行优化(更友好)



    七、用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?

    在这里插入图片描述

    1. 组件设计

    组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式

    现在有一个场景,点击新增与编辑都弹框出来进行填写,功能上大同小异,可能只是标题内容或者是显示的主体内容稍微不同

    这时候就没必要写两个组件,只需要根据传入的参数不同,组件显示不同内容即可

    这样,下次开发相同界面程序时就可以写更少的代码,意义着更高的开发效率,更少的 Bug和更少的程序体积

    2. 需求分析

    实现一个Modal组件,首先确定需要完成的内容:

    • 遮罩层
    • 标题内容
    • 主体内容
    • 确定和取消按钮

    主体内容需要灵活,所以可以是字符串,也可以是一段 html 代码

    特点是它们在当前vue实例之外独立存在,通常挂载于body之上

    除了通过引入import的形式,我们还可通过API的形式进行组件的调用

    还可以包括配置全局样式、国际化、与typeScript结合


    3. 实现流程

    首先看看大致流程:

    • 目录结构
    • 组件内容
    • 实现 API 形式
    • 事件处理
    • 其他完善

    其他完善:

    关于组件实现国际化、与typsScript结合,大家可以根据自身情况在此基础上进行更改






    未完待续…

    展开全文
  • 经典面试题: 2021Vue经典面试题总结(含答案).pdf
  • 前端面试题: 精选Vue面试题及答案.pdf
  • 2022vue最新面试题.pdf

    2021-12-14 17:32:37
    2022vue最新面试题.pdf
  • 面试必备: 2021 Vue经典面试题总结.pdf
  • 2022前端面试系列——Vue面试题.pdf
  • Vue常见面试题及网友回答,收集来自阿里云社区,包括v-model, key, methods,错误处理,参数传递,父子组件,定时器,vue声明周期等问题
  • 2021年前端vue面试题大汇总(附答案).pdf
  • 多次面试整理的技术点,有效帮助快速面试
  • 转眼2019又要过去了,作为一名前端码农,又熬过一个没日没夜的年头,头发又少了不少,去年的学习计划一半也没完成,唉。。。现在为大家总结一下这一年面试的几家公司的关于前端面试题
  • 默认 Vue 在初始化数据时,会给 data 中的属性使用 Object.defineProperty 重新定义所有属 性,当页面取到对应属性时。会进行依赖收集(收集当前组件的watcher) 如果属性发生变化会通 知相关依赖进行更新操作。 原理...
  • Vue面试题合集下载.pdf

    2021-12-14 17:32:58
    Vue面试题合集下载.pdf
  • 2020 Vue经典面试题

    2021-01-03 13:57:54
     3.vue的两个核心点是什么?  4. 三大框架的优缺点?(vue、Angular、React)  5.vue和jQuery的区别?  6.渐进式框架的理解?  7.单页面应用和多页面应用区别及优缺点?  8.SPA首屏加载慢如何解决?  9.scss...
  • vue面试——2021最全面的vue基础面试题.pdf
  • 2022 最新 Vue 3.0 面试题

    千次阅读 多人点赞 2022-03-08 10:02:59
    2022 最新 Vue 3.0 面试题1、Vue 的最大的优势是什么?(必会)2、Vue 和 jQuery 两者之间的区别是什么?(必会)3、MVVM 和 MVC 区别是什么?哪些场景适合?(必会)4、Vue 数据双向绑定的原理是什么?(必会)5、...

    2022 最新 Vue 3.0 面试题

    1、Vue 的最大的优势是什么?(必会)

    Vue 作为一款轻量级框架、简单易学、双向数据绑定、组件化、数据和结构的分离、虚拟
    DOM、运行速度快,并且作者是中国人尤雨溪,对应的 API 文档对国内开发者优化,作为前端
    开发人员的首选入门框架
    Vue 的优势:
    1、Vue.js 可以进行组件化开发,使代码编写量大大减少,读者更加易于理解。
    2、Vue.js 最突出的优势在于可以对数据进行双向绑定。
    3、使用 Vue.js 编写出来的界面效果本身就是响应式的,这使网页在各种设备上都能
    显示出非常好看的效果。
    4、相比传统的页面通过超链接实现页面的切换和跳转,Vue 使用路由不会刷新页
    面。
    5、vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和
    dom,这样大大加快了访问速度和提升用户体验。
    6、而且他的第三方 UI 组件库使用起来节省很多开发时间,从而提升开发效率。

    2、Vue 和 jQuery 两者之间的区别是什么?(必会)

    1、jQuery 介绍:
    jQuery 曾经也是现在依然最流行的 web 前端 js 库,可是现在无论是国内还是国外他的使
    用率正在渐渐被其他的 js 库所代替,随着浏览器厂商对 HTML5 规范统一遵循以及 ECMA6 在浏
    览器端的实现,jQuery 的使用率将会越来越低
    2、vue 介绍:
    vue 是一个兴起的前端 js 库,是一个精简的 MVVM。从技术角度讲,Vue.js 专注于 MVVM
    模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数
    据的操作就可以完成对页面视图的渲染。当然还有很多其他的 mvmm 框架如 Angular,react 都
    是大同小异,本质上都是基于 MVVM 的理念,然而 vue 以他独特的优势简单,快速,组合,紧
    凑,强大而迅速崛起
    3、vue 和 jQuery 区别:
    3.1)vue 和 jQuery 对比 jQuery 是使用选择器()选取 DOM 对象,对其进行赋值、取
    值、事件绑定等操作,其实和原生的 HTML 的区别只在于可以更方便的选取和操作 DOM 对
    象,而数据和界面是在一起的

    3.2)比如需要获取 label 标签的内容:)选取 DOM 对象,对其进行赋值、取值、事件
    绑定等操作,其实和原生的 HTML 的区别只在于可以更方便的选取和操作 DOM 对象,而数据
    和界面是在一起的
    3.3)比如需要获取 label 标签的内容:(“lable”).val();,它还是依赖 DOM 元素的值。
    Vue 则是通过 Vue 对象将数据和 View 完全分离开来了
    3.4)对数据进行操作不再需要引用相应的 DOM 对象,可以说数据和 View 是分离的,
    他们通过 Vue 对象这个 vm 实现相互的绑定,这就是传说中的 MVVM

    3、MVVM 和 MVC 区别是什么?哪些场景适合?(必会)

    1、基本定义
    1.1)MVVM 基本定义
    MVVM 即 Model-View-ViewModel 的简写,即模型-视图-视图模型,模型(Model)
    指的是后端传递的数据,视图(View)指的是所看到的页面,视图模型(ViewModel)是 mvvm 模式
    的核心,它是连接 view 和 model 的桥梁。它有两个方向:
    1.1.1)一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到
    的页面,实现的方式是:数据绑定,
    1.1.2)二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。
    实现的方式是:DOM 事件监听,这两个方向都实现的,我们称之为数据的双向绑定
    1.2)MVC 基本定义
    MVC 是 Model-View- Controller 的简写。即模型-视图-控制器。M 和 V 指的意思和
    MVVM 中的 M 和 V 意思一样。C 即 Controller 指的是页面业务逻辑,使用 MVC 的目的就是将
    M 和 V 的代码分离。MVC 是单向通信。也就是 View 跟 Model,必须通过 Controller 来承上启

    2、使用场景
    主要就是 MVC 中 Controller 演变成 MVVM 中的 viewModel,MVVM 主要解决了 MVC
    中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验,vue 数据驱动,通
    过数据来显示视图层而不是节点操作, 场景:数据操作比较多的场景,需要大量操作 DOM 元
    素时,采用 MVVM 的开发方式,会更加便捷,让开发者更多的精力放在数据的变化上,解放繁
    琐的操作 DOM 元素
    3、两者之间的区别
    MVC 和 MVVM 其实区别并不大,都是一种设计思想, MVC 和 MVVM 的区别并不是
    VM 完全取代了 C,只是在 MVC 的基础上增加了一层 VM,只不过是弱化了 C 的概念,
    ViewModel 存在目的在于抽离 Controller 中展示的业务逻辑,而不是替代 Controller,其它视图
    操作业务等还是应该放在 Controller 中实现,也就是说 MVVM 实现的是业务逻辑组件的重用,
    使开发更高效,结构更清晰,增加代码的复用性

    4、Vue 数据双向绑定的原理是什么?(必会)

    V ue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫
    持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

    1、需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和
    getter,这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化
    2、compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将
    每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更
    新视图
    3、Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:
    3.1)在自身实例化时往属性订阅器(dep)里面添加自己
    3.2)自身必须有一个 update()方法
    3.3)待属性变动 dep.notice()通知时,能调用自身的 update()方法,并触发 Compile
    中绑定的回调,则功成身退。
    4、MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通 Observer
    来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起
    Observer 和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) ->
    数据 model 变更的双向绑定效果

    5、Object.defineProperty 和 Proxy 的区别(必会)

    Object.defineProperty 和 Proxy 的区别如下:
    1、Proxy 可以直接监听对象而非属性;
    2、Proxy 可以直接监听数组的变化;
    3、Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等
    是 Object.defineProperty 不具备的
    4、Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而
    Object.defineProperty 只能遍历对象属性直接修改
    5、Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准
    的性能红利
    6、Object.defineProperty 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,
    而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重

    6、Vue 生命周期总共分为几个阶段?(必会)

    Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模
    板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
    1、beforeCreate
    在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调

    2、created
    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data
    observer)属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目
    前不可见
    3、beforeMount

    在挂载开始之前被调用:相关的 render 函数首次被调用
    4、mounted
    el 被新创建的 vm. e l 替 换 , 并 挂 载 到 实 例 上 去 之 后 调 用 该 钩 子 , 如 果 r o o t 实 例 挂 载 了 一 个 文 档 内 元 素 , 当 m o u n t e d 被 调 用 时 v m . el 替换,并挂载到实例上去之后调用该钩子,如果 root 实例挂载了 一个文档内元素,当 mounted 被调用时 vm. elrootmountedvm.el 也在文档内
    5、beforeUpdate
    数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的
    DOM,比如手动移除已添加的事件监听器,该钩子在服务器端渲染期间不被调用,因为只有初
    次渲染会在服务端进行
    6、updated
    由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
    7、activated
    keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用
    8、deactivated
    keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用
    9、beforeDestroy
    实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被
    调用
    10、destroyed
    Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件
    监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用
    11、errorCaptured(2.5.0+ 新增)
    当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生
    错误的组件实例以及一个包含错误来源信息的字符串,此钩子可以返回 false 以阻止该错误继
    续向上传播

    7、第一次加载页面会触发哪几个钩子函数?(必会)

    当页面第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩
    子函数

    8、请说下封装 Vue 组件的过程?(必会)

    首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决
    了我们传统项目开发:效率低、难维护、复用性等问题
    1、分析需求:确定业务需求,把页面中可以服用的结构,样式以及功能,单独抽离成一
    个文件,实现复用
    2、具体步骤:使用 Vue.extend 方法创建一个组件,然后使用 Vue.component 方法注册组
    件,子组件需要数据,可以在 props 中接受定义,而子组件修改好数据后,想把数据传递给父
    组件,可以采用$emit 方法

    9、Vue 组件如何进行传值的? (必会)

    1、父组件向子组件传递数据
    父组件内设置要传的数据,在父组件中引用的子组件上绑定一个自定义属性并把数据
    绑定在自定义属性上,在子组件添加参数 props 接收即可
    2、子组件向父组件传递数据
    子组件通过 vue 实例方法 e m i t 进 行 触 发 并 且 可 以 携 带 参 数 , 父 组 件 监 听 使 用 @ ( v − o n ) 进 行 监 听 , 然 后 进 行 方 法 处 理 3 、 非 父 子 组 件 之 间 传 递 数 据 3.1 引 入 第 三 方 n e w v u e 定 义 为 e v e n t B u s 3.2 ) 在 组 件 中 c r e a t e d 中 订 阅 方 法 e v e n t B u s . emit 进行触发并且可以携带参数,父组件监听使用@(v- on)进行监听,然后进行方法处理 3、非父子组件之间传递数据 3.1 引入第三方 new vue 定义为 eventBus 3.2)在组件中 created 中订阅方法 eventBus. emit使@von33.1newvueeventBus3.2createdeventBus.on(“自定义事件名”,methods 中的方法
    名)
    3.3) 在另一个兄弟组件中的 methods 中写函数,在函数中发布 eventBus 订阅的方法
    eventBus.$emit("自定义事件名”)
    3.4) 在组件的 template 中绑定事件(比如 click)

    10、组件中写 name 选项有什么作用?(必会)

    1、项目使用 keep-alive 时,可搭配组件 name 进行缓存过滤
    2、DOM 做递归组件时需要调用自身 name
    3、vue-devtools 调试工具里显示的组见名称是由 vue 中组件 name 决定的

    11、Vue 组件 data 为什么必须是函数(必会)

    1、个组件都是 Vue 的实例
    2、组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一个会影响其他
    3、组件中的 data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就
    会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护
    各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变
    了全都会变的结果

    12、讲一下组件的命名规范(必会)

    给组件命名有两种方式,一种是使用链式命名 my-component,一种是使用大驼峰命名
    MyComponent 在字符串模板中 和
    都可以使用,在非字符串模板中最好使用
    ,因为要遵循 W3C 规范中的自定义组件名 (字母全小写且
    必须包含一个连字符),避免和当前以及未来的 HTML 元素相冲突

    13、怎么在组件中监听路由参数的变化?(必会)

    有两种方法可以监听路由参数的变化,但是只能用在包含的组件内。
    第一种
    watch: {
    ‘$route’(to, from) {
    // 在此处监听
    },
    },
    第二种
    beforeRouteUpdate (to, from, next) {
    //这里监听
    }

    14、怎么捕获 Vue 组件的错误信息?(必会)

    1、errorCaptured 是组件内部钩子,当捕获一个来自子孙组件的错误时被调用,接收
    error、vm、info 三个参数,return false 后可以阻止错误继续向上抛出
    2、errorHandler 为全局钩子,使用 Vue.config.errorHandler 配置,接收参数与
    errorCaptured 一致,2.6 后可捕捉 v-on 与 promise 链的错误,可用于统一错误处理与错误兜底

    15、Vue 组件里的定时器要怎么销毁?(必会)

    如果页面上有很多定时器,可以在 data 选项中创建一个对象 timer,给每个定时器取个名
    字一一映射在对象 timer 中, 在 beforeDestroy 构造函数中 for(let k in
    this.timer){clearInterval(k)};
    如果页面只有单个定时器,可以这么做
    const timer = setInterval(() =>{}, 500);
    this.$once(‘hook:beforeDestroy’, () => {
    clearInterval(timer);
    })

    16、Vue-cli 用自定义的组件?有遇到过哪些问题吗?(必

    会)
    1、在 components 目录新建你的组件文件(indexPage.vue),script 一定要 export default
    {}
    2、在需要用的页面(组件)中导入:import indexPage from
    ‘@/components/indexPage.vue’

    3、注入到 vue 的子组件的 components 属性上面,components:{indexPage}
    4、在 template 视图 view 中使用,例如有 indexPage 命名,使用的时候则 index-page

    17、Vue 中 solt 的使用方式,以及 solt 作用域插槽的用法

    (必会)
    使用方式
    当组件当做标签进行使用的时候,用 slot 可以用来接受组件标签包裹的内容,当给
    solt 标签添加 name 属性的 时候,可以调换响应的位置
    插槽作用域
    作用域插槽其实就是带数据的插槽,父组件接收来自子组件的 slot 标签上通过 v-bind
    绑定进而传递过来的数 据,父组件通过 scope 来进行接受子组件传递过来的数据

    18、Vue 该如何实现组件缓存?(必会)

    在面向组件化开发中,我们会把整个项目拆分为很多业务组件,然后按照合理的方式组
    织起来,那么自然会存在组件之前切换的问题,vue 中有个动态组件的概念,它能够帮助开发
    者更好的实现组件之间的切换,但是在面对需求频繁的变化,去要切换组件时,动态组件在切
    换的过程中,组件的实例都是重新创建的,而我们需要保留组件的状态,为了解决这个问题,
    需要使用到 vue 中内置组件
    包裹动态组件时,会缓存不活动的组件实例,主要用于保留组
    件状态或避免重新渲染,
    简答的说: 比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打
    开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不
    是重新渲染

    19、跟 keep-alive 有关的生命周期是哪些?(必会)

    1、前言:在开发 Vue 项目的时候,大部分组件是没必要多次渲染的,所以 Vue 提供了一
    个内置组件 keep-alive 来缓存组件内部状态,避免重新渲染,在开发 Vue 项目的时候,大部分
    组件是没必要多次渲染的,所以 Vue 提供了一个内置组件 keep-alive 来缓存组件内部状态,避
    免重新渲染
    2、生命周期函数:在被 keep-alive 包含的组件/路由中,会多出两个生命周期的钩
    子:activated 与 deactivated。
    2.1)activated 钩子:在在组件第一次渲染时会被调用,之后在每次缓存组件被激活
    时调用。
    2.2)Activated 钩子调用时机: 第一次进入缓存路由/组件,在 mounted 后面,
    beforeRouteEnter 守卫传给 next 的回调函数之前调用,并且给因为组件被缓存了,再次进入
    缓存路由、组件时,不会触发这些钩子函数,beforeCreate created beforeMount mounted 都
    不会触发

    2.3)deactivated 钩子:组件被停用(离开路由)时调用:deactivated 钩子调用时
    机:使用 keep-alive 就不会调用 beforeDestroy(组件销毁前钩子)和 destroyed(组件销毁),因为
    组件没被销毁,被缓存起来了,这个钩子可以看作 beforeDestroy 的替代,如果你缓存了组
    件,要在组件销毁的的时候做一些事情,可以放在这个钩子里,组件内的离开当前路由钩子
    beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子 afterEach => deactivated
    离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由)

    20、Vue 常用的修饰符都有哪些?(必会)

    .prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本
    身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

    21、Vue 常用的指令都有哪些?并且说明其作用(必会)

    1、v-model 多用于表单元素实现双向数据绑定(同 angular 中的 ng-model)
    2、v-for 格式: v-for=“字段名 in(of) 数组 json” 循环数组或 json(同 angular 中的 ng-
    repeat),需要注意从 vue2 开始取消了$index
    3、v-show 显示内容 (同 angular 中的 ng-show)
    4、v-hide 隐藏内容(同 angular 中的 ng-hide)
    5、v-if 显示与隐藏 (dom 元素的删除添加 同 angular 中的 ng-if 默认值为 false)v-
    else-if 必须和 v-if 连用 v-else 必须和 v-if 连用 不能单独使用 否则报错 模板编译错误
    6、v-bind 动态绑定 作用: 及时对页面的数据进行更改
    7、v-on:click 给标签绑定函数,可以缩写为@,例如绑定一个点击函数 函数必须写在
    methods 里面
    8、v-text 解析文本
    9、v-html 解析 html 标签
    10、v-bind:class 三种绑定方法 1、对象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、
    数组型 ‘[{red:“isred”},{blue:“isblue”}]’
    11、v-once 进入页面时 只渲染一次 不在进行渲染
    12、v-cloak 防止闪烁
    13、v-pre 把标签内部的元素原位输出

    22、自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?(必会)

    1、全局定义指令:在 vue 对象的 directive 方法里面有两个参数,一个是指令名称,另外
    一个是函数。
    2、组件内定义指令:directives:钩子函数:bind(绑定事件触发)、inserted(节点插入的时
    候触发)、update(组件内相关更新)钩子函数参数:el、binding

    23、指令 v-el 的作用是什么?(必会)

    提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标.可以是 CSS 选择器,
    也可以是一个 HTMLElement 实例

    24、v-show 和 v-if 指令的共同点和不同点?(必会)

    1、相同点:
    v-show 和 v-if 都能控制元素的显示和隐藏。
    2、不同点:
    2.1)实现本质方法不同
    v-show 本质就是通过设置 css 中的 display 设置为 none,控制隐藏
    v-if 是动态的向 DOM 树内添加或者删除 DOM 元素
    2.2)编译的区别
    v-show 其实就是在控制 css
    v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件
    监听和子组件
    2.3)编译的条件
    v-show 都会编译,初始值为 false,只是将 display 设为 none,但它也编译了
    v-if 初始值为 false,就不会编译了
    2.4)性能比较
    v-show 只编译一次,后面其实就是控制 css,而 v-if 不停的销毁和创建,故 v-
    show 性能更好一。
    3、注意点:
    因为 v-show 实际是操作 display:" "或者 none,当 css 本身有 display:none 时,v-
    show 无法让显示
    4、总结(适用场景):
    如果要频繁切换某节点时,使用 v-show(无论 true 或者 false 初始都会进行渲染,此
    后通过 css 来控制显示隐藏,因此切换开销比较小,初始开销较大),如果不需要频繁切换某
    节点时,使用 v-if(因为懒加载,初始为 false 时,不会渲染,但是因为它是通过添加和删除
    dom 元素来控制显示和隐藏的,因此初始渲染开销较小,切换开销比较大)

    25、为什么避免 v-if 和 v-for 用在一起(必会)

    vue2.x 中v-for优先级高于v-if,vue3.x 相反。所以2.x 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用,造成性能浪费;3.x 版本中 v-if 总是优先于 v-for 生效,导致v-if访问不了v-for中的变量。

    扩展;
    一般我们在两种常见的情况下会倾向于这样做:

    为了过滤一个列表中的项目 (比如 v-for=“user in users” v-if=“user.isActive”)。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。

    为了避免渲染本应该被隐藏的列表 (比如 v-for=“user in users” v-if=“shouldShowUsers”)。这种情形下,请将 v-if 移动至容器元素上 (比如 ul、ol)。

    当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,所以这个模板:

    <ul>
      <li
        v-for="user in users"
        v-if="user.isActive"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    

    将会经过如下运算:

    this.users.map(function (user) {
      if (user.isActive) {
        return user.name
      }
    })
    

    因此哪怕我们只渲染出一小部分用户的元素,也得在每次重渲染的时候遍历整个列表,不论活跃用户是否发生了变化。

    通过将其更换为在如下的一个计算属性上遍历:

    computed: {
      activeUsers: function () {
        return this.users.filter(function (user) {
          return user.isActive
        })
      }
    }
    
    <ul>
      <li
        v-for="user in activeUsers"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    

    我们将会获得如下好处:

    过滤后的列表只会在 users 数组发生相关变化时才被重新运算,过滤更高效。
    使用 v-for=“user in activeUsers” 之后,我们在渲染的时候只遍历活跃用户,渲染更高效。
    解耦渲染层的逻辑,可维护性 (对逻辑的更改和扩展) 更强。

    26、watch、methods 和 computed 的区别?(必会)

    1、基本说明
    1.1)computed:
    计算属性将被混入到 Vue 实例中,所有 getter 和 setter 的 this 上下文自动地绑
    定为 Vue 实例
    1.2)methods:
    methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者
    在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。
    1.3)watch:
    观察和响应 Vue 实例上的数据变动,一个对象,键是需要观察的表达式,值是对
    应回调函数,值也可以是方法名,或者包含选项的对象,Vue 实例将会在实例化时调,$watch(),
    遍历 watch 对象的每一个属性
    2、三者的加载顺序
    2.1)computed 是在 HTML DOM 加载后马上执行的,如赋值;(属性将被混入到 Vue 实
    例)
    2.2)methods 则必须要有一定的触发条件才能执行,如点击事件,watch 呢?它用于观
    察 Vue 实例上的数据变动,
    2.3)默认加载的时候
    先 computed 再 watch,不执行 methods;
    2.4)触发某一事件后
    先 computed 再 methods 再到 watch,computed 属性 vs method 方,
    computed 计算属性是基于它们的依赖进行缓存的
    3、总结
    计算属性 computed 只有在它的相关依赖发生改变时才会重新求值,当有一个性能开
    销比较大的的计算属性 A ,它需要遍历一个极大的数组和做大量的计算,然后我们可能有其
    他的计算属性依赖于 A ,这时候,我们就需要缓存,每次确实需要重新加载,不需要缓存时
    用 methods

    27、怎么在 watch 监听开始之后立即被调用?(必会)

    在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调

    28、watch 怎么深度监听对象变化?(必会)

    1、有个原则监听谁,写谁的名字,然后是对应的执行函数, 第一个参数为最新的改变值,第二
    个值为上一次改变的值, 注意: 除了监听 data,也可以监听计算属性 或者一个 函数的计算结果
    2、启用深度监听对象
    watch:{
    a:{
    handler:function(val,oldval){

    },
    deep:true
    }
    }

    29、computed 中的属性名和 data 中的属性名可以相同吗? (必会)

    不能同名,因为不管是 computed 属性名还是 data 数据名还是 props 数据名都会被挂载在
    vm 实例上,因此这三个都不能同名
    if (key in vm.KaTeX parse error: Expected '}', got 'EOF' at end of input: …uted property "{key}" is already defined in data., vm) } else if (vm.$options.props && key in vm.$options.props) { warn(The computed property “${key}” is already defined as a prop.`, vm)
    }

    30、什么是 Vue 的计算属性(必会)

    在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可
    能多次使用的情况下,尽量采取计算属性的方式,好处:使得数据处理结构清晰;
    依赖于数据,数据更新,处理结果自动更新;
    1、计算属性内部 this 指向 vm 实例
    2、在 template 调用时,直接写计算属性名即可
    3、常用的是 getter 方法,获取数据,也可以使用 set 方法改变数据
    4、相较于 methods,不管依赖的数据变不变,methods 都会重新计算,但是依赖数据不
    变的时候 computed 从缓存中获取,不会重新计算

    31、Vue 中 key 值的作用是什么?(必会)

    当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果
    数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处
    每个元素,并且确保它在特定索引下显示已被渲染过的每个元素,key 的作用主要是为了高效
    的更新虚拟 DOM

    32、Vue-loader 是什么?使用它的用途有哪些?(必会)

    vue-loader 会解析文件,提取出每个语言块,如果有必要会通过其他 loader 处理,最后将
    他们组装成一个 commonjs 模块;module.exports 出一个 vue.js 组件对象
    1、< temlate>语言块
    1,1)默认语言:html
    1,2)每个.vue 文件最多包含一个< template>块

    1,3)内容将被提取为字符串,将编译用作 VUE 组件的 template 选项
    2、< script>
    2,1)默认语言:JS(在监测到 babel-loader 或者 buble-loader 配置时,自动支持
    ES2015)
    2,2)每个.vue 文件最多包含一个< script>块
    2,3)该脚本在类 CommonJS 环境中执行(就像通过 webpack 打包的正常 JS 模块)。所以
    你可以 require()其他依赖。在 ES2015 支持下,也可以使用 import 跟 export 语法
    2,4)脚本必须导出 Vue.js 组件对象,也可以导出由 VUE.extend()创建的扩展对象;但是普
    通对象是更好的选择
    3、< style>
    默认语言:css
    3,1)一个.vue 文件可以包含多个< style>标签
    3,2)这个标签可以有 scoped 或者 module 属性来帮助你讲样式封装到当前组件;具有不
    同封装模式的多个< style>标签可以在同一个组件中混合使用
    3,3)默认情况下,可以使用 style-loader 提取内容,并且通过< style>标签动态假如文档
    的< head>中,也可以配置 webpack 将所有的 styles 提取到单个 CSS 文件中
    4、自定义块
    可以在.vue 文件中添加额外的自定义块来实现项目的特殊需求;例如< docs>块;vue-
    loader 将会使用标签名来查找对应的 webpack loaders 来应用到对应的模块上;webpack 需要
    在 vue-loader 的选项 loaders 中指定
    vue-loader 支持使用非默认语言,比如 CSS 预处理器,预编译的 HTML 模板语言,通过设置语
    言块的 lang 属性:

    33、Vue 中怎么自定义过滤器(必会)

    Vue.js 允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:
    双花括号插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符
    号指示
    可以用全局方法 Vue.filter() 注册一个自定义过滤器,它接收两个参数:过滤器 ID 和过滤
    器函数。过滤器函数以值为参数,返回转换后的值
    Vue .filter( ‘reverse’ , function (value) { return value.split( ‘’ ).reverse().join( ‘’ ) })

    过滤器也同样接受全局注册和局部注册

    34、你是怎么认识 Vuex 的?(必会)

    vuex 可以理解为一种开发模式或框架。比如 PHP 有 thinkphp,java 有 spring 等,通过状
    态(数据源)集中管理驱动组件的变化(好比 spring 的 IOC 容器对 bean 进行集中管理)
    1、应用级的状态集中放在 store 中

    2、改变状态的方式是提交 mutations,这是个同步的事物
    3、异步逻辑应该封装在 action 中

    35、Vuex 的 5 个核心属性是什么?(必会)

    分别是 State、 Getter、Mutation 、Action、 Module
    1、state
    state 为单一状态树,在 state 中需要定义我们所需要管理的数组、对象、字符串等等,
    只有在这里定义了,在 vue.js 的组件中才能获取你定义的这个对象的状态
    2、getter
    getter 有点类似 vue.js 的计算属性,当我们需要从 store 的 state 中派生出一些状态,
    那么我们就需要使用 getter,getter 会接收 state 作为第一个参数,而且 getter 的返回值会
    根据它的依赖被缓存起来,只有 getter 中的依赖值(state 中的某个需要派生状态的值)发
    生改变的时候才会被重新计算
    3、mutation
    更改 store 中 state 状态的唯一方法就是提交 mutation,就很类似事件。每个 mutation
    都有一个字符串类型的事件类型和一个回调函数,我们需要改变 state 的值就要在回调函
    数中改变。我们要执行这个回调函数,那么我们需要执行一个相应的调用方法
    store.commit
    4、action
    action 可以提交 mutation,在 action 中可以执行 store.commit,而且 action 中可以有
    任何的异步操作。在页面中如果我们要嗲用这个 action,则需要执行 store.dispatch
    5、module
    module 其实只是解决了当 state 中很复杂臃肿的时候,module 可以将 store 分割成
    模块,每个模块中拥有自己的 state、mutation、action 和 getter

    36、Vuex 的出现解决了什么问题?(必会)

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

    37、简述 Vuex 的数据传递流程(必会)

    当组件进行数据修改的时候我们需要调用 dispatch 来触发 actions 里面的方法。actions 里
    面的每个方法中都会 有一个
    1、commit 方法,当方法执行的时候会通过 commit 来触 mutations 里面的方法进行数据
    的修改
    2、mutations 里面的每个函数都会有一个 state 参数,这样就可以在 mutations 里面进行
    state 的数据修改 ,当数据修改完毕后,会传导给页面,页面的数据也会发生改变

    38、Vuex 的 Mutation 和 Action 之间的区别是什么?(必

    会)
    1、流程顺序
    “相应视图—>修改 State”拆分成两部分,视图触发 Action,Action 再触发 Mutation
    2、角色定位
    基于流程顺序,二者扮演不同的角色
    1)Mutation:专注于修改 State,理论上是修改 State 的唯一途径
    2)Action:业务代码、异步请求
    3、限制
    1)角色不同,二者有不同的限制
    2)Mutation:必须同步执行
    3)Action:可以异步,但不能直接操作 State

    39、Vue-router 是干什么的,原理是什么?(必会)

    Vue-router 是 Vue.js 官方的路由插件,它和 vue.js 是深度集成的,适合用于构建单页
    面应用,vue 的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映
    射起来,传统的页面应用,是用一些超链接来实现页面切换和跳转的,在 vue-router 单页面应
    用中,则是路径之间的切换,也就是组件的切换,路由模块的本质 就是建立起 url 和页面之间
    的映射关系
    “更新视图但不重新请求页面”是前端路由原理的核心之一,目前在浏览器环境中这一功
    能的实现主要有两种方式:
    1、利用 URL 中的 hash(“#”)
    2、利用 History interface 在 HTML5 中新增的方法

    40、路由之间是怎么跳转的?有哪些方式?(必会)

    1、
    2、this. r o u t e r . p u s h ( ) 跳 转 到 指 定 的 u r l , 并 在 h i s t o r y 中 添 加 记 录 , 点 击 回 退 返 回 到 上 一 个 页 面 3 、 t h i s . router.push()跳转到指定的 url,并在 history 中添加记录,点击回退返回到上一个 页面 3、this. router.push()urlhistory退3this.router.replace()跳转到指定的 url,但是 history 中不会添加记录,点击回退到上上
    个页面
    4、this.$touter.go(n)向前或者后跳转 n 个页面,n 可以是正数也可以是负数

    41、Vue-router 怎么配置路由(必会)

    在 vue 中配置路由分为 5 个步骤,分别是:

    北京市顺义区京顺路 99 号·黑马程序员 www.itheima.com
    第 237 页 共 353 页
    1、安装
    npm install --save vue-router
    2、引用
    import VueRouter from ‘vue-router’
    3、配置路由文件
    var router = new VueRouter({
    routes:[
    {
    path:“/hello”,
    component:HelloWorld
    },
    {
    path:“/wen”,
    component:HelloWen
    new Vue({
    el: ‘#app’,
    components: { App },
    router,
    template: ‘’
    })
    4、视图加载的位置
    默认 App.vue 文件中加
    5、跳转导航
    helloword(渲染出来的是 a 标签)

    42、Vue-router 有哪几种路由守卫?(必会)

    1、路由守卫为
    2、全局守卫:beforeEach
    3、后置守卫:afterEach
    4、全局解析守卫:beforeResolve
    5、路由独享守卫:beforeEnter

    43、Vue-router 的钩子函数都有哪些?(必会)

    关于 vue-router 中的钩子函数主要分为 3 类
    1、全局钩子函数要包含 beforeEach
    1,1)beforeEach 函数有三个参数,分别是
    1,2)to:router 即将进入的路由对象
    1,3)from:当前导航即将离开的路由
    1,4)next:function,进行管道中的一个钩子,如果执行完了,则导航的状态就是
    confirmed (确认的)否则为 false,终止导航

    2、单独路由独享组件
    2,1)beforeEnter
    3、组件内钩子
    3,1)beforeRouterEnter
    3,2)beforeRouterUpdate
    3,3)beforeRouterLeave

    44、路由传值的方式有哪几种(必会)

    Vue-router 传参可以分为两大类,分别是编程式的导航 router.push 和声明式的导航
    1、router.push
    1.1)字符串:直接传递路由地址,但是不能传递参数
    this. r o u t e r . p u s h ( " h o m e " ) 对 象 : 1.2 ) 命 名 路 由 这 种 方 式 传 递 参 数 , 目 标 页 面 刷 新 会 报 错 t h i s . router.push("home") 对象: 1.2)命名路由 这种方式传递参数,目标页面刷新会报错 this. router.push("home")1.2this.router.push({name:“news”,params:{userId:123})
    1.3)查询参数 和 name 配对的式 params,和 path 配对的是 query
    this.KaTeX parse error: Expected '}', got 'EOF' at end of input: … 1.4)接收参数 this.route.query
    2、声明式导航
    2.1)字符串 <router-link to:“news”>
    2.2)命名路由 <router-link :to:“{name:‘news’,params:{userid:1111}}”>
    2.3)查询参数

    45、怎么定义 Vue-router 的动态路由?怎么获取传过来的动态参数?

    我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件,例如,我们有一个
    User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染,那么,我们可以在
    vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果
    1、动态路径参数,使用“冒号”开头,一个路径参数,使用冒号标记,当匹配到一个路
    由时,参数会被设置到 this. r o u t e r . p a r a m s 中 , 并 且 可 以 在 每 个 组 件 中 使 用 2 、 现 在 我 们 知 道 了 可 以 通 过 动 态 路 由 传 参 , 在 路 由 中 设 置 了 , 多 段 路 径 参 数 后 , 对 应 的 值 分 别 都 会 设 置 到 router.params 中,并且可以在每个组件中使用 2、现在我们知道了可以通过动态路由传参,在路由中设置了,多段路径参数后,对应的 值分别都会设置到 router.params使2router.query 和$router.params 中

    46、JQuery 和 params 之间的区别是什么?(必会)

    1、query 要用 path 来引入,params 要用 name 来引入
    2、接收参数时,分别是 this. r o u t e . q u e r y . n a m e 和 t h i s . route.query.name 和 this. route.query.namethis.route.params.name(注意:是
    r o u t e 而 不 是 route 而不是 routerouter
    3、query 更加类似于我们 ajax 中 get 传参,params 则类似于 post,前者在浏览器的地址
    栏中显示,params 不显示
    4、params 传值一刷新就没了,query 传值刷新还存在

    47、 r o u t e 和 route 和 routerouter 的区别是什么?(必会)

    $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,
    name 等路由信息参数
    r o u t e r 为 V u e R o u t e r 的 实 例 , 相 当 于 一 个 全 局 的 路 由 器 对 象 , 里 面 含 有 很 多 属 性 和 子 对 象 , 例 如 h i s t o r y 对 象 , 经 常 用 的 跳 转 链 接 就 可 以 用 t h i s . r o u t e r . p u s h 会 往 h i s t o r y 栈 中 添 加 一 个 新 的 记 录 。 返 回 上 一 个 h i s t o r y 也 是 使 用 router 为 VueRouter 的实例,相当于一个全局的路由器对象,里面含有很多属性和子对 象,例如 history 对象,经常用的跳转链接就可以用 this.router.push 会往 history 栈中添加一个 新的记录。返回上一个 history 也是使用 routerVueRouterhistorythis.router.pushhistoryhistory使router.go 方法

    48、active-class 属于哪个组件中的属性?该如何使用?

    首先 active-class 是 vue-router 模块中 router-link 组件中的属性,主要作用是用来实现选
    中样式的切换,在 vue-router 中要使用 active-class 有两种方式:
    1、 在 router-link 中写入 active-class
    active-class 选择样式时根据路由中的路径(to=“/home”)去匹配,然后显示
    首页
    2、直接在路由 js 文件中配置 linkActiveClass
    export default new Router({
    linkActiveClass: ‘active’,
    })

    
    
    <div class="menu-btn">
    <router-link to="/" class="menu-home" active-class="active">
    首页
    </router-link >
    </div>   
    
    <div class="menu-btn">
    <router-link to="/my" class="menu-my" active-class="active">
    我的
    </router-link>
    </div>
    


    3、引起的问题
    因为 to=“/” 引起的,active-class 选择样式时根据路由中的路径去匹配,然后显示,
    例如在 my 页面中,路由为 localhost:8081/#/my,那么 to=“/”和 to=”/my"都可以匹配到,所
    有都会激活选中样式
    4、解决方法
    4,1)在 router-link 中写入 exact
    首页</router-
    link>
    4,2)在路由中加入重定向

    
    <router-link to="/" class="menu-home" active-class="active" exact>首页</router-link>
    {
    path: '/',
    redirect: '/home'
    }
    

    49、Vue 的路由实现模式:hash 模式和 history 模式(必

    会)
    1、hash 模式:在浏览器中符号“#”,#以及#后面的字符称之为 hash,
    用 window.location.hash 读取。特点:hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来
    指导浏览器动作,对服务端安全无用,hash 不会重加载页面
    2、history 模式:history 采用 HTML5 的新特性,且提供了两个新方法:
    2.1)pushState()
    2.2)replaceState()可以对浏览器历史记录栈进行修改,以及 popState 事件的监听到状
    态变更

    50、请说出路由配置项常用的属性及作用(必会)

    路由配置参数:
    1、path : 跳转路径
    2、component : 路径相对于的组件
    3、name:命名路由
    4、children:子路由的配置参数(路由嵌套)
    5、props:路由解耦
    6、redirect : 重定向路由

    51、编程式导航使用的方法以及常用的方法(必会)

    1、路由跳转:this. r o u t e r . p u s h ( ) 2 、 路 由 替 换 : t h i s . router.push() 2、路由替换: this. router.push()2:this.router.replace()
    3、后退: this. r o u t e r . b a c k ( ) 4 、 前 进 : t h i s . router.back() 4、前进 :this. router.back()4this.router.forward()

    52、Vue 怎么实现跨域(必会)

    1、什么是跨域
    跨域指浏览器不允许当前页面的所在的源去请求另一个源的数据。源指协议,端
    口,域名。只要这个 3 个中有一个不同就是跨域
    2、使用 vue-cli 脚手架搭建项目时 proxyTable 解决跨域问题
    打开 config/index.js,在 proxyTable 中添写如下代码:
    proxyTable: {
    ‘/api’: { // 使用"/api"来代替"http://f.apiplus.c"
    target: ‘http://f.apiplus.cn’, //源地址
    changeOrigin: true, //改变源
    pathRewrite: {
    ‘^/api’: ‘http://f.apiplus.cn’ //路径重写
    }
    3、使用 CORS(跨域资源共享)
    3.1)前端设置,vue 设置 axios 允许跨域携带 cookie(默认是不带 cookie)
    axios.defaults.withCredentials = true;
    3,2)后端设置:
    3.2.1)跨域请求后的响应头中需要设置
    3.2.2)Access-Control-Allow-Origin 为发起请求的主机地址
    3.2.3)Access-Control-Allow-Credentials,当它被设置为 true 时,允许跨域
    带 cookie,但此时 Access-Control- Allow-Origin 不能为通配符*
    3.2.4)Access-Control-Allow-Headers,设置跨域请求允许的请求头
    3.2.5)Access-Control-Allow-Methods,设置跨域请求允许的请求方式

    53、Vue 中动画如何实现(必会)

    1、哪个元素需要动画就给那个元素加 transition 标签
    2、进入时 class 的类型分为以下几种
    -enter -enter-active -enter-to
    3、离开时 class 的类型分为以下几种
    -leave -leave-active -leave-to
    如果需要一组元素发生动画需要用标签

    54、你对 Vue.js 的 template 编译的理解?(必会)

    简而言之,就是先转化成 AST 树,再得到的 render 函数返回 Vnode(Vue 的虚拟 DOM 节
    点)
    1、首先通过 compile 编译器把 template 编译成 AST 语法树(abstract syntax tree 即 源代
    码的抽象语法结构的树状表现形式),compile 是 createCompiler 的返回值,createCompiler 是
    用以创建编译器的,另外 compile 还负责合并 option
    2、然后 AST 会经过 generate(将 AST 语法树转化成 render funtion 字符串的过程)得到
    render 函数,render 的返回值是 Vnode,Vnode 是 Vue 的虚拟 DOM 节点,里面有(标签名、
    子节点、文本等等)

    55、Vue 渲染模板时怎么保留模板中的 HTML 注释呢?

    (必会)
    在组件中将 comments 选项设置为 true

    <template comments> ... <template>
    

    56、Vue2.0 兼容 IE 哪个版本以上吗?(必会)

    不支持 ie8 及以下,部分兼容 ie9 ,完全兼容 10 以上,因为 vue 的响应式原理是基于 es5
    的 Object.defineProperty(),而这个方法不支持 ie8 及以下

    57、Vue 如何去除 URL 中的#(必会)

    vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 URL 会自带 “#”,
    如果不想使用 “#”, 可以使用 vue-router 的另一种模式 history:new Router ({ mode :
    ‘history’, routes: [ ]})
    需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所
    以在路由跳转的时候,就会出现访问不到静态资源而出现 “404” 的情况,这时候就需要服
    务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一
    个 “index.html” 页面

    58、说一下你在 Vue 中踩过的坑(必会)

    1、第一个是给对象添加属性的时候,直接通过给 data 里面的对象添加属性然后赋值,新
    添加的属性不是响应式的
    1.1)解决办法:通过 Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属
    性是响应式的
    2、在 created 操作 dom 的时候,是报错的,获取不到 dom,这个时候实例 vue 实例没有挂

    2.2)解决办法:通过:Vue.nextTick(回调函数进行获取)

    59、在 Vue 中使用插件的步骤(必会)

    采用 ES6 的 import … from …语法或 CommonJS 的 require()方法引入插件
    使用全局方法 Vue.use( plugin )使用插件,可以传入一个选项对象 Vue.use(MyPlugin,
    { someOption: true })

    60、Vue 项目优化的解决方案都有哪些?(必会)

    1、 使用 mini-css-extract-plugin 插件抽离 css
    2、 配置 optimization 把公共的 js 代码抽离出来
    3、 通过 webpack 处理文件压缩
    4、 不打包框架、库文件,通过 cdn 的方式引入
    5、 小图片使用 base64
    6、 配置项目文件懒加载
    7、 UI 库配置按需加载
    8、 开启 Gzip 压缩

    61、使用 Vue 的时候一下加载造成页面卡顿,该如何解决?

    (必会)
    vue-router 解决首次加载缓慢的问题。懒加载简单来说就是按需加载
    1、像 vue 这种单页面应用,如果没有应用懒加载,运用 webpack 打包后的文件
    将会异常的大,造成进入首页时, 需要加载的内容过多,时间过长,会出现长时间的白
    屏,即使做了 loading 也是不利于用户体验,
    2、而运用懒加载 则可以将页面进行划分,需要的时候加载页面,可以有效的分
    担首页所承担的加载压力,减少首页加载用时。
    3、用法:在配置路由时使用:component:resolve=>require([“@components/路
    由的路径”],resolve)。 就是用了懒加载后打完包直接运行那个 index.html 会报错,报文
    件引用错误其实是打包时候路径配置有点问 题,找到 build 下面的
    webpack.prod.conf.js 添加 publicPath:“./”,

    62、请说出 Vue.cli 项目中 src 目录每个文件夹和文件的用

    法?(必会)
    1、assets 文件夹是放静态资源
    2、components 是放组件
    3、router 是定义路由相关的配置
    4、view 视图
    5、app.vue 是一个应用主组件
    6、main.js 是入口文件

    63、你知道 style 上加 scoped 属性的原理吗?(必会)

    1、什么是 scoped
    在 Vue 组件中,为了使样式私有化(模块化),不对全局造成污染,可以在 style 标
    签上添加 scoped 属性以表示它的只属于当下的模块,局部有效。如果一个项目中的所有 vue
    组件 style 标签全部加上了 scoped,相当于实现了样式的私有化。如果引用了第三方组件,需
    要在当前组件中局部修改第三方组件的样式,而又不想去除 scoped 属性造成组件之间的样式
    污染。此时只能通过穿透 scoped 的方式来解决,选择器。
    2、scoped 的实现原理:
    Vue 中的 scoped 属性的效果主要通过 PostCSS 转译实现,如下是转译前的 Vue 代码:

    `

    Vue.js scoped

    `

    浏览器渲染后的代码:

    
    <div data-v-fed36922>Vue.js scoped</div>
    

    .scoped[data-v-fed36922]{font-size:14px;}
    即:PostCSS 给所有 dom 添加了一个唯一不重复的动态属性,然后,给 CSS 选择器额外添加一
    个对应的属性选择器来选择该组件中 dom,这种做法使得样式私有化

    64、说说你对 SPA 单页面的理解,它的优缺点分别是什么?(必会)

    单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用,它将
    所有的活动局限于一个 Web 页面中,仅在该 Web 页面初始化时加载相应的 HTML、JavaScript
    和 CSS,一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转,取而
    代之的是利用 JavaScript 动态的变换 HTML 的内容,从而实现 UI 与用户的交互,由于避免了
    页面的重新加载,SPA 可以提供较为流畅的用户体验,得益于 ajax,我们可以实现无跳转刷
    新,又多亏了浏览器的 histroy 机制,我们用 hash 的变化从而可以实现推动界面变化,从而模
    拟元素客户端的单页面切换效果:
    SPA 被人追捧是有道理的,但是它也有不足之处,当然任何东西都有两面性,以下是卤煮
    总结的一些目前 SPA 的优缺点:
    1、 优点:
    1,1)无刷新界面,给用户体验原生的应用感觉
    1,2)节省原生(android 和 ios)app 开发成本
    1,3)提高发布效率,无需每次安装更新包
    1,4)容易借助其他知名平台更有利于营销和推
    1,5)符合 web2.0 的趋势
    2、 缺点:
    1) 效果和性能确实和原生的有较大差距
    2) 各个浏览器的版本兼容性不一样

    3) 业务随着代码量增加而增加,不利于首屏优化
    4) 某些平台对 hash 有偏见,有些甚至不支持 pushstate
    5) 不利于搜索引擎抓取

    65、怎样理解 Vue 的单向数据流?(必会)

    1、数据从父级组件传递给子组件,只能单向绑定
    2、子组件内部不能直接修改从父级传递过来的数据
    3、所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新
    会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外改变父级组件的状态,
    从而导致你的应用的数据流向难以理解。
    4、每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值,这意味着
    你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警

    5、子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件
    修改

    66、VNone 是什么?什么是虚拟 DOM?(高薪常问)

    1、Vnode 是什么
    Vnode 是 JavaScript 对象,Vnode 表示 Virtual DOM,用 JavaScript 对象来描述真实的
    DOM 把 DOM 标签,属性,内容都变成对象的属性。就像使用 JavaScript 对象对一种动物进行
    说明一样{name: ‘Hello Kitty’, age: 1, children: null}。
    1)Vnode 的作用
    通过 render 将 template 模版描述成 Vnode,然后进行一系列操作之后形成真实
    的 DOM 进行挂载。
    2) Vnode 的优点
    2-1) 兼容性强,不受执行环境的影响。Vnode 因为是 JS 对象,不管 node 还是
    浏览器,都可以统一操作,从而获得了服务端渲染、原生渲染、手写渲染函数等能力。
    2-2) 减少操作 DOM,任何页面的变化,都只使用 Vnode 进行操作对比,只需要
    在最后一步挂载更新 DOM,不需要频繁操作 DOM,从而提高页面性能。
    3、 什么是虚拟 DOM?
    1、文档对象模型或 DOM 定义了一个接口,该接口允许 JavaScript 之类的语言访问和操
    作 HTML 文档。元素由树中的节点表示,并且接口允许我们操纵它们。但是此接口需要付出
    代价,大量非常频繁的 DOM 操作会使页面速度变的非常缓慢
    2、Vue 通过在内存中实现文档结构的虚拟表示来解决此问题,其中虚拟节点(Vnode)
    表示 DOM 树中的节点。当需要操纵时,可以在虚拟 DOM 的 内存中执行计算和操作,而不
    是在真实 DOM 上进行操纵。这自然会更快,并且允许虚拟 DOM 算法计算出最优化的方式
    来更新实际 DOM 结构,一旦计算出,就将其应用于实际的 DOM 树,这就提高了性能,这就
    是为什么基于虚拟 DOM 的框架(例如 Vue 和 react)如此突出的原因。

    67、Vue 中如何实现一个虚拟 DOM?说说你的思路(高薪

    常问)
    首先要构建一个 Vnode 的类,DOM 元素上的所有属性在 Vnode 类实例化出来的对象上都
    存在对应的属性。例如 tag 表示一个元素节点的名称,text 表示一个文本节点的文本,chlidren
    表示子节点等。将 Vnode 类实例化出来的对象进行分类,例如注释节点、文本节点、元素节
    点、组件节点、函数式节点、克隆节点。
    然后通过编译将模板转成渲染函数 render,执行渲染函数 render,在其中创建不同类型的
    Vnode 类,最后整合就可以得到一个虚拟 DOM(vnode),最后通过 patch 将 vnode 和
    oldVnode 进行比较后,生成真实 DOM

    68、Vue 中操作 data 中数组的方法中哪些可以触发视图更新,哪些不可以,不可以的话有什么解决办法?(高薪常

    问)
    1、可以被改变的
    push()、pop()、shift()、unshift()、splice()、sort()、reverse()这些方法会改变被操作的数
    组;
    2、不可以改变的
    filter()、concat()、 slice()这些方法不会改变被操作的数组,并且返回一个新的数组,以上
    方法都可以触发视图更新
    3、解决方案
    1、利用索引直接设置一个数组项,例:this.array[index] = newValue,直接修改数组
    的长度,例:this.array.length = newLength
    2、以上两种方法不可以触发视图更新
    1)可以使用 this.$set(this.array,index,newValue),this.array.splice(index,1,newValue)
    2)可以使用 this.array.splice(newLength)

    69、Vue 中如何重置 data? (高薪常问)

    要初始化 data 中的数据,可以使用 Object.assign()方法,实现重置 data 中的数据,以下就
    是对该方法的详细介绍,以及如何使用该方法,重置 data 中的数据
    1、Object.assign()方法基本定义
    1,1)Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目
    标对象。它将返回目标对象。
    1,2)用法: Object.assign(target, …sources),第一个参数是目标对象,第二个参数
    是源对象,就是将源对象属性复制到目标对象,返回目标对象

    2、具体使用方式
    使用 Object.assign(),vm. d a t a 可 以 获 取 当 前 状 态 下 的 d a t a , v m . data 可以获取当前状态下的 data,vm. datadatavm.options.data(this)
    可以获取到组件初始化状态下的 data,复制 Object.assign(this. d a t a , t h i s . data, this. data,this.options.data(this))
    // 注意加 this,不然取不到 data() { a: this.methodA } 中的 this.methodA

    70、如何对 Vue 首屏加载实现优化? (高薪常问)

    1、把不常改变的库放到 index.html 中,通过 cdn 引入
    2、vue 路由的懒加载
    3、不生成 map 文件
    4、vue 组件尽量不要全局引入
    5、使用更轻量级的工具库
    6、开启 gzip 压缩
    7、首页单独做服务端渲染

    71、Vue 的 nextTick 的原理是什么? (高薪常问)

    1、为什么需要 nextTick
    Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM,但有时候业务需要必须
    对数据更改–刷新后的 DOM 做相应的处理,这时候就可以使用 Vue.nextTick(callback)这个
    api 了
    2、理解原理前的准备
    首先需要知道事件循环中宏任务和微任务这两个概念
    2,1)常见的宏任务有:script, setTimeout, setInterval, setImmediate, I/O, UI rendering
    2,2)常见的微任务有:process.nextTick(nodejs),Promise.then(), MutationObserver
    3、理解 nextTick 的原理
    正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式。如果
    大家看过这部分的源码,会发现其中做了很多 isNative()的判断,因为这里还存在兼容性
    优雅降级的问题

    72、在 Vue 实例中编写生命周期 hook 或其他

    option/propertie 时,为什么不使用箭头函数?(高薪常
    问)
    箭头函数自己没有定义 this 上下文,而是绑定到其父函数的上下文中,当你在 Vue 程序
    中使用箭头函数(=>)时,this 关键字病不会绑定到 Vue 实例,因此会引发错误,所以强烈
    建议改用标准函数声明

    73、is 这个特性你有用过吗?主要用在哪些方面?(高薪常

    问)

    1、动态组件
    <component :is="componentName"></component>, componentName 可以是在本页面
    已经注册的局部组件名和全局组件名,也可以是一个组件的选项对象。 当控制 componentName
    改变时就可以动态切换选择组件

    2、is 的用法
    有些 HTML 元素,诸如

      1. 、和,对于哪些元素可以出现在其内
        部是有严格限制的
        而有些 HTML 元素,诸如
      2. 和 ,只能出现在其它某些特定的元素内

    <ul>
    <card-list></card-list>
    </ul>
    

    所以上面会被作为无效的内容提升到外部,并导致最终渲染结果出
    错。应该这么写:

     <ul>
    <li is="cardList"></li>
    </ul>
    

    74、scss 是什么?在 Vue-cli 中的安装使用步骤是?有哪几大特性?(高薪常问)

    1、基本定义
    SCSS 即是 SASS 的新语法,是 Sassy CSS 的简写,是 CSS3 语法的超集,也就是说
    所有有效的 CSS3 样式也同样适合于 SASS,SASS 是 CSS3 的一个扩展,增加了规则嵌套、
    变量、混合、选择器继承等等,通过使用命令行的工具或 WEB 框架插件把它转换成标准
    的、格式良好的 CSS 代码
    2、使用步骤:
    1,1)先装 css-loader、node-loader、sass-loader 等加载器模块
    1,2)在 build 目录找到 webpack.base.config.js,在那个 extends 属性中加一个拓
    展.scss
    1,3)在同一个文件,配置一个 module 属性
    1,4)然后在组件的 style 标签加上 lang 属性 ,例如:lang=”scss”
    3、特性:
    3,1)可以用变量,例如($变量名称=值)
    3,2)可以用混合器,例如()
    3,3)可以嵌套

    75、请详细介绍一些 package.json 中的配置的作用(了解)

    1、Name:项目名称
    3、 Version: 项目版本
    3、Description: 项目描述
    4、 Author:作者
    5、 Prinate:项目是否私有
    6、 Scripts:npm run *** 命令用于调用 node 执行的.js 文件

    在这里插入图片描述

    如果大家觉得还不错,点赞,收藏,分享,一键三连支持我一下~

    展开全文
  • vue3.0 面试题总结

    千次阅读 2020-12-09 20:08:56
    vue3使用proxy对象重写响应式。proxy的性能本来比defineproperty好,proxy可以拦截属性的访问、赋值、删除等操作,不需要初始化的时候遍历所有属性,另外有多层属性嵌套的话,只有访问某个属性的时候,才会递

    一、Vue 3.0 性能提升主要是通过哪几方面体现的?

    1. 响应式系统提升

    • vue2在初始化的时候,对data中的每个属性使用definepropery调用getter和setter使之变为响应式对象。如果属性值为对象,还会递归调用defineproperty使之变为响应式对象。
    • vue3使用proxy对象重写响应式。proxy的性能本来比defineproperty好,proxy可以拦截属性的访问、赋值、删除等操作,不需要初始化的时候遍历所有属性,另外有多层属性嵌套的话,只有访问某个属性的时候,才会递归处理下一级的属性。

    优势:
    可以监听动态新增的属性;
    可以监听删除的属性 ;
    可以监听数组的索引和 length 属性;

    2. 编译优化

    • 优化编译和重写虚拟dom,让首次渲染和更新dom性能有更大的提升
      vue2 通过标记静态根节点,优化 diff 算法
      vue3 标记和提升所有静态根节点,diff 的时候只比较动态节点内容

    • Fragments, 模板里面不用创建唯一根节点,可以直接放同级标签和文本内容

    • 静态提升

    • patch flag, 跳过静态节点,直接对比动态节点

    • 缓存事件处理函数

    3. 源码体积的优化

    • vue3移除了一些不常用的api,例如:inline-template、filter等
    • 使用tree-shaking

    二. Vue 3.0 所采用的 Composition Api 与 Vue 2.x使用的Options Api 有什么区别?

    Options Api

    包含一个描述组件选项(data、methods、props等)的对象 options;
    API开发复杂组件,同一个功能逻辑的代码被拆分到不同选项 ;
    使用mixin重用公用代码,也有问题:命名冲突,数据来源不清晰;

    composition Api

    vue3 新增的一组 api,它是基于函数的 api,可以更灵活的组织组件的逻辑。
    解决options api在大型项目中,options api不好拆分和重用的问题。

    三. Proxy 相对于 Object.defineProperty 有哪些优点?

    proxy的性能本来比defineproperty好,proxy可以拦截属性的访问、赋值、删除等操作,不需要初始化的时候遍历所有属性,另外有多层属性嵌套的话,只有访问某个属性的时候,才会递归处理下一级的属性。

    可以监听数组变化
    可以劫持整个对象
    操作时不是对原对象操作,是 new Proxy 返回的一个新对象
    可以劫持的操作有 13 种

    四. Vue 3.0 在编译方面有哪些优化?

    • vue.js 3.x中标记和提升所有的静态节点,diff的时候只需要对比动态节点内容;
    • Fragments(升级vetur插件): template中不需要唯一根节点,可以直接放文本或者同级标签
    • 静态提升(hoistStatic),当使用 hoistStatic 时,所有静态的节点都被提升到 render 方法之外.只会在应用启动的时候被创建一次,之后使用只需要应用提取的静态节点,随着每次的渲染被不停的复用。
    • patch flag, 在动态标签末尾加上相应的标记,只能带 patchFlag 的节点才被认为是动态的元素,会被追踪属性的修改,能快速的找到动态节点,而不用逐个逐层遍历,提高了虚拟dom diff的性能。
    • 缓存事件处理函数cacheHandler,避免每次触发都要重新生成全新的function去更新之前的函数
    • tree shaking 通过摇树优化核心库体积,减少不必要的代码量

    五. Vue.js 3.0 响应式系统的实现原理?

    1. reactive

    设置对象为响应式对象。接收一个参数,判断这参数是否是对象。不是对象则直接返回这个参数,不做响应式处理。
    创建拦截器handerler,设置get/set/deleteproperty。
    get
    收集依赖(track);
    如果当前 key 的值是对象,则为当前 key 的对象创建拦截器 handler, 设置 get/set/deleteProperty;
    如果当前的 key 的值不是对象,则返回当前 key 的值。
    set
    设置的新值和老值不相等时,更新为新值,并触发更新(trigger)。
    deleteProperty
    当前对象有这个 key 的时候,删除这个 key 并触发更新(trigger)。

    2. effect

    接收一个函数作为参数。作用是:访问响应式对象属性时去收集依赖

    3. track

    接收两个参数:target 和 key
    -如果没有 activeEffect,则说明没有创建 effect 依赖
    -如果有 activeEffect,则去判断 WeakMap 集合中是否有 target 属性
    -WeakMap 集合中没有 target 属性,则 set(target, (depsMap = new Map()))
    -WeakMap 集合中有 target 属性,则判断 target 属性的 map 值的 depsMap 中是否有 key 属性
    -depsMap 中没有 key 属性,则 set(key, (dep = new Set()))
    -depsMap 中有 key 属性,则添加这个 activeEffect

    4.trigger

    判断 WeakMap 中是否有 target 属性,WeakMap 中有 target 属性,则判断 target 属性的 map 值中是否有 key 属性,有的话循环触发收集的 effect()。

    展开全文
  • 最全vue面试题+详解答案.pdf
  • 由于疫情原因,原本每年的“金三银四”仿佛消失,随之而来的是找工作的压力,这里给要面试的小伙伴们总结了到目前为止我遇到的前端面试题,仅供参考哦,第一次写博客,如有错误之处,还请指出。 一. vue方面 1.vue-...
  • Vue3 一些面试题

    千次阅读 2021-12-31 17:29:08
    Vue3 新功能 createApp emits 属性 多事件处理 Fragment 不再限于模板中的单个根节点 移除 .sync 改为 v-model 参数 异步组件的引用方式 移除 filter Teleport 以前称为 <Portal>,译作传送门...
  • Vue-loader 是 Webpack 的加载模块,它使我们可以用 Vue 文件格式编写单文件组件。 单文件组件文件有三个部分,(模板、脚本和样式)。 vue-loader 模块允许 webpack 使用单独的加载模块 (例如 SASS 或 SCSS 加载器) ...
  • 前端框架vue面试题.pdf

    2021-07-16 17:44:14
    前段VUE面试题
  • vue面试题_vue常见面试题和答案[文].pdf
  • 2022vue经典面试题.pdf

    2021-12-14 17:32:34
    2022vue经典面试题.pdf
  • vue中computed和watch的区别 1.computed的用法 是一个计算属性,类似于过滤器,对绑定到view的数据进行处理。computed上面的属性不可在vue data中声明,不能做异步处理 data: { firstName: 'Foo', lastName: 'Bar' ...
  • vue常见的面试题

    2021-01-07 04:40:30
    vue面试题汇集 vue面试题汇总二 vue面试总结三 vue面试题汇总四 vue面试题汇总五 vue面试题汇总六 axios是什么?怎么使用?描述使用它来实现登录功能的流程 1.axios是基于promise使用浏览器好node.js的一个http客服...
  • 总结vue前端面试题

    2020-10-27 15:52:46
    本人总结前端vue面试,包含vue的基础,以及vue的高级和组件话开发,和vue的2.0 版本,包含vue指令,插槽路由vuex等
  • 整理的vue20道经典面试题,由初级到中高级,高级部分可以忽略
  • 2022年最新面试题整理(包答案) 总结最近我和几个同事遇到的面试题,希望对大家有帮助,面试题我分为两类,经常遇到,很少遇到。 1、vue的生命周期 2、computed和watch区别?3、深度监听怎么做? 4、父子组件的生命...
  • 看了很多关于vue组件传值的文章,于是想把文章总结一下,把关于vue组件传值好好聊聊,欢迎大家指正。 组件之间传值主要分两种 1、父子组件:props方法、ref方法、children和parent方法、 emit方法 2、非父子组件:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,576
精华内容 12,630
关键字:

vue3面试题