• 八股文-Vue篇(持续更新)


    八股文-Vue篇

    一、Vue2

    1. 关于生命周期

    1.1 生命周期有哪些?发送请求在created还是mounted?

    生命周期描述
    beforeCreate组件实例被创建之前(没有dom,没有$data)
    created组件实例已经完全创建(没有dom,有$data)
    beforeMount组件挂载之前(没有dom,有$data)
    mounted组件被挂载到实例上之后(有dom,有$data)
    beforeUpdate组件数据发生变化,更新之前
    updated组件数据更新之后
    beforeDestroy组件实例销毁之前
    destroyed组件实例销毁之后

    mounted可以操作dom又可以操作data,还可以操作子组件;而在created的时候不能操作dom也不能操作子组件。
    发送请求是异步任务,会在同步任务执行完毕之后执行,即获取到数据也是会在mounted执行完之后。
    这个问题具体要看项目和业务情况,因为组件的加载顺序是,会先执行父组件的前3个生命周期,再执行子组件的前4个生命周期。如果业务是父组件引入子组件,并且优先加载子组件的数据,那么在父组件中当前请求要放在mounted中,让子组件的请求先去执行,让子组件的数据先加载出来。

    1.2 为什么发送请求不在beforeCreate里?beforeCreate和created有什么区别?

    如果请求是在methods里封装好的,在beforeCreate里是拿不到methods的方法的。
    beforeCreate阶段没有$data ,拿不到methods方法,created阶段有$data,拿得到methods方法。

    1.3 在created中如何获取dom?

    1. 异步代码获取,例如setTimeout
    2. 使用vue的this.$nextTick

    1.4 一旦进入到组件会执行哪些生命周期?

    beforeCreatecreatedbeforeMountmounted

    1.5 第二次或者第N次进去组件会执行哪些生命周期?

    如果当前组件加入了keep-alive,只会执行activated
    如果没有加入keep-alive依然执行前四个生命周期beforeCreatecreatedbeforeMountmounted

    1.6 父子组件生命周期执行顺序?

    父组件 beforeCreate created beforeMount
    子组件 beforeCreate created beforeMount mounted
    父组件 mounted

    1.7 加入keep-alive会执行哪些生命周期?

    如果使用了keep-alive组件,当前组件会额外增加两个生命周期。
    activated:被 keep-alive 缓存的组件激活时调用
    deactivated:被 keep-alive 缓存的组件失活时调用。

    如果当前组件加入了keep-alive,第一次进入这个组件会执行5个生命周期:beforeCreate created beforeMount mounted activated

    1.8 你在什么情况下用过哪些生命周期?说一说生命周期使用场景?

    created:单一组件进行请求
    mounted:有父子组件关系的时候,进行请求;同步操作dom
    activated:处理缓存
    beforeDestroy:关闭页面的时候进行数据记录

    2. 关于组件

    2.1 组件通讯方式

    父传子:

    1. v-bind绑定props。不能传孙,且有多个子组件时需要一个一个操作;子不能直接修改父组件的数据
    2. 子组件直接使用父组件数据 this.$parent。子能直接修改父组件的数据
    3. 依赖注入provide、inject。不用逐级传递,可以实现直接传递给孙

    子传父:

    1. 子组件自定义事件 this.$emit
    2. 父组件直接使用子组件数据:this.$children[index].xxxthis.$refs[name].xxx

    兄弟互传:

    1. EventBus($on接收方,$emit发送方)

    2.2 父组件如何直接修改子组件的值

    this.$children[index].xxxthis.$refs[name].xxx

    2.3 子组件如何直接修改父组件的值

    this.$parent.xxx

    2.4 如何找到父组件

    this.$parent

    2.5 如何找到根组件

    this.$root

    2.6 keep-alive

    用来缓存当前组件

    2.7 slot插槽

    • 匿名插槽
    • 具名插槽
    • 作用域插槽:对组件传递 props 那样,向一个插槽的出口上传递 attributes

    2.8 provide、inject

    依赖注入,用来实现给后辈组件传递数据

    2.9 如何封装组件

    抽取复用部分内容,用slot插槽去实现父组件可以自定义部分特殊的内容;通过v-bind绑定props去实现获取父组件数据;通过自定义事件去实现给父组件传递数据。

    3. 关于Vuex

    3.1 vuex有哪些属性

    Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。

    • State用来存储公共数据源。全局共享属性。
    • Mutation用于同步变更state中的数据。
    • Action用于异步变更state中的数据,但是在Action中还是要用过触发Mutation的方式间接变更数据。
    • Getter用于对Store中的数据进行加工处理形成新的数据(类似于计算属性),Store中数据发生变化,Getter中的数据也会变化。针对state数据进行二次计算。
    • moudle属性是将store分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

    3.2 vuex使用state值

    this.$store.state.xxx

    computed: { ...mapState(['全局数据名称1','全局数据名称2',...]) }
    区别:使用this.$store的方式可以直接修改(不推荐),使用辅助函数的方式不能直接修改

    3.3 vuex的getters值修改

    getters不可以修改

    3.4 vuex的mutations和actions的区别

    相同点:都是来存放全局方法的;不能有return值
    区别:mutation是同步的,actions是异步的;mutation是用来修改state的,action是用来提交mutation的

    3.5 vuex持久化存储

    vuex本身不是持久化存储,它只是一个全局数据管理仓库。

    实现方式:

    1. 自己写localStorage
    2. 使用vuex-persistedstate插件

    3.6 vuex是单向数据流还是双向数据流

    vuex是单向数据流

    4. 关于路由

    4.1 路由的模式和区别

    路由模式:history、hash

    区别:

    • 表象不同:hash路径有一个#,history/
    • history找不到当前页面会发送请求,而hash不会
    • 项目打包前端自测的时候,hash可以看到内容,hsitory默认情况是看不到内容的

    4.2 子路由和动态路由

    详请-> Vue Router基础知识整理

    4.3 路由传值

    详请-> Vue Router基础知识整理

    4.4 路由故障

    当前页跳当前页,路径不变,参数变

    import Vue from 'vue'
    import VueRouter from 'vue-router'
     
    // 解决路由重复跳转错误
    const routerPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function (location) {
        return routerPush.call(this, location).catch(err => { })
    };
     
    Vue.use(VueRouter)
    

    4.5 $router 和 $route的区别

    • $router 路由管理对象(路由跳转)
    • $route 路由单体对象,指某一条路由(获取当前路径相关)

    4.6 导航守卫

    1. 全局守卫:全局前置守卫 router.beforeEach:路由进入前;全局后置钩子 router.afterEach:路由进入后

    2. 路由独享守卫: beforeEnter 只在进入路由时触发

    3. 组件内守卫:beforeRouteEnter在渲染该组件的对应路由被验证前调用、 beforeRouteUpdate在当前路由改变,但是该组件被复用时调用、 beforeRouteLeave在导航离开渲染该组件的对应路由时调用

    5. 关于API

    5.1 $set

    场景:直接通过数组下标去修改数组造成相应丢失
    this.$set(target,key,value)

    5.2 $nextTick

    等待下一次 DOM 更新刷新的工具方法。异步的。
    获取更新后的dom;等待dom更新完再执行后续操作。
    官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。

    5.3 $refs

    用来获取dom

    5.4 $el

    获取当前组件的节点

    5.5 $data

    获取当前组件的data数据

    5.6 $children

    获取当前组件的所有子组件(一个数组)

    5.7 $parent

    找到当前组件的父组件,无则返回自身

    5.8 $root

    找到当前组件的根组件,无则返回自身

    5.9 data定义数据

    return里外的区别
    外:需要用this;不被劫持(没有get/set),不支持双向绑定
    内:被劫持,双向绑定

    5.10 computed计算属性

    计算结果要修改的话要通过set写法
    在这里插入图片描述
    计算属性computed:(可依赖多个属性):

    • 缓存:计算属性基于其依赖进行缓存。
    • 性能优化:当依赖没有改变时,多次访问计算属性不会触发重新计算
    • 同步:计算属性是同步的,并在渲染过程中进行计算。
    • 简洁性:对于简单的数据转换和组合,计算属性提供了更简洁的语法。

    5.11 watch

    监听属性watch:(只监听一个属性,可监听到数据变化前的值):

    • 异步:监听属性允许你在数据变化后执行异步操作。
    • 执行机制:监听属性在数据改变后触发,而不是在渲染过程中。
    • 可访问DOM:在监听属性函数中,你可以访问组件的DOM。
    • 对复杂逻辑的支持:如果你需要进行复杂的逻辑判断或操作,监听属性是更好的选择。

    初始化的时候先执行一次:immediate:true
    对象数据深层监听:deep:true

    5.12 methods和computed的区别

    computed返回结果有缓存, methods没有。当返回结果在dom中多次用到的时候,用computed性能更佳。

    5.13 computed、watch的区别

    监听属性watch:(只监听一个属性,可监听到数据变化前的值):

    • 异步:监听属性允许你在数据变化后执行异步操作。
    • 执行机制:监听属性在数据改变后触发,而不是在渲染过程中。
    • 可访问DOM:在监听属性函数中,你可以访问组件的DOM。
    • 对复杂逻辑的支持:如果你需要进行复杂的逻辑判断或操作,监听属性是更好的选择。

    计算属性computed:(可依赖多个属性):

    • 缓存:计算属性基于其依赖进行缓存。
    • 性能优化:当依赖没有改变时,多次访问计算属性不会触发重新计算
    • 同步:计算属性是同步的,并在渲染过程中进行计算。
    • 简洁性:对于简单的数据转换和组合,计算属性提供了更简洁的语法。

    5.14 props和data谁的优先级更高

    props > methods > data > computed > watch

    6. 过关于指令

    6.1 如何自定义指令

    全局:main.js
    局部:组件内
    Vue2自定义指令说明文档
    Vue3自定义指令说明文档
    vue2vue3指令钩子有所区别

    6.2 vue单向绑定

    双向绑定:v-model
    单向绑定:v-bind,props接收

    6.3 v-if 和 v-for 优先级

    vue2中v-for的优先级高于v-if
    vue3中v-if的优先级高于v-for
    不建议在同一节点一起用

    6.4 v-if 和 v-show的区别

    • 控制手段:v-show隐藏则是为该元素添加css–display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除
    • 编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换
    • 编译条件:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染
    • 初次加载v-i

    7. 关于原理

    7.1 $nextTick原理

    功能:等待下一次 DOM 更新刷新的工具方法。获取更新后的dom。异步。

    $nextTick(callback) {
    	return Promise.resolve().then(() => {
    		callback();
    	})
    }
    

    官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。

    7.2 双向绑定原理

    通过Object.defineProperty劫持数据发生的改变,如果数据发生了改变(在set进行赋值的),触发update方法进行更新节点内容({{str}}),从而实现数据双向绑定的原理。

    双向数据绑定是采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据发生变动时发布消息给订阅者,触发相应的监听回调。这样就可以实现数据的双向绑定 关键点是Object.defineProperty()劫持属性。

    8. 其他相关

    8.1 什么是渐进式框架

    渐进式框架(Progressive Framework)是一种软件开发框架的设计理念,它允许开发者根据项目需求逐步引入和应用框架的不同特性和功能。

    8.2 scoped原理

    **作用:**让样式在本组件中生效,不影响其他组件
    **原理:**给元素节点新增自定义属性,然后css根据属性选择器添加样式

    8.3 vue中怎么做样式穿透

    ::v-deep
    

    【博主:努力的小朱同学】vue 之 CSS进行样式穿透的方法(/deep/、::v-deep、>>> 、:deep、额外的全局<style>)

    二、Vue3

    1. Vue2和Vue3的区别

    双向绑定原理

    • Vue2.0x 的响应式是通过 Object.defineProperty 对数据进行劫持,并结合发布订阅者模式实现。 Vue 利用 Object.defineProperty 创建一个 observe 来劫持监听所有的属性,把这些属性(遍历data)全部转为 getter 和 setter。Vue 中每个组件实例都会对应一个 watcher 实例,它会在组件渲染的过程中把使用过的数据属性通过 getter 收集为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。(Vue2后期添加的属性劫持不到,会造成数据更新但视图没有更新)
    • vue3.0x的响应式是通过ES6种的Proxy代理,Proxy能够拦截目标对象上的操作(如获取、设置等),从而实现对数据的追踪和更新。与之前版本不同的是,Vue.js 3无需再手动编写getter和setter函数,只需要将原始数据包装成Proxy对象后就可以开始追踪和更新。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。

    生命周期

    在这里插入图片描述
    tip:setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地去定义

    根节点

    Vue3 支持多个根节点,也就是 fragment;而Vue2只支持一个根节点

    API风格

    • Vue2选项API(Options API),一个逻辑会散乱在文件不同位置(data、props、computed、watch、生命周期钩子等),导致代码的可读性变差。当需要修改某个逻辑时,需要上下来回跳转文件位置。

    • Vue3 除了选项式API外还支持组合式API(Composition API)则很好地解决了这个问题,可将同一逻辑的内容写到一起,增强了代码的可读性、内聚性,其还提供了较为完美的逻辑复用性方案。

    2. Vue3如果用setup怎么组织代码?

    用hooks,就是让功能模块细分(提升项目的可维护性)

    3. Vue3的setup写法怎么使用this?

    import { getCurrentInstanc e} from "vue";
    const this = getCurrentInstance();
    const { ctx } = getCurrentInstance();
    

    4. Vue3常用api

    API 参考:https://cn.vuejs.org/api/

    5. Vue3常用的响应式数据类型

    • ref():接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。(基本类型)
    • reactive():返回一个对象的响应式代理。(复杂类型)
    • toRef():可以将值、refs 或 getters 规范化为 refs (3.3+)。也可以基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。(解构一个值)
    • toRefs():将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。(解构多个值)

    6. Teleport组件

    Vue3 提供 Teleport 组件可将部分 DOM 移动到 Vue app 之外的位置。比如项目中常见的 Dialog 弹窗

    <button @click="dialogVisible = true">显示弹窗button>
    <teleport to="body">
      <div class="dialog" v-if="dialogVisible">
        我是弹窗,我直接移动到了body标签下  div>
    teleport>
    
  • 相关阅读:
    js将后端返回的blob请求下载
    【QT配置第三方MQTT协议】
    kotlin实践笔记
    Token身份验证
    C盘满了,应该清理哪些地方
    RequestContextHolder详解
    Java数组练习题
    Python必备学习资源(附链接)
    小技巧 - 中文detokenize(基于规则)
    鸿蒙即将抛弃Android,你还不来学习一下?
  • 原文地址:https://blog.csdn.net/hsy0827/article/details/139462420