zerojs前端面试题系列--vue3篇(2)

1. 请说说Vue的生命周期,和vue2的有什么区别?

Vue 的生命周期可以分为8个阶段:创建前后、挂载前后、更新前后、销毁前后,以及一些特殊场景的生命周期。Vue 3 中还新增了是3个用于调试和服务端渲染的场景。

Vue 2中的生命周期钩子Vue 3选项式API的生命周期选项Vue 3 组合API中生命周期钩子描述
beforeCreatebeforeCreatesetup()创建前,此时datamethods的数据都还没有初始化
createdcreatedsetup()创建后,data中有值,尚未挂载,可以进行一些Ajax请求
beforeMountbeforeMountonBeforeMount挂载前,会找到虚拟DOM,编译成Render
mountedmountedonMounted挂载后,DOM已创建,可用于获取访问数据和DOM元素
beforeUpdatebeforeUpdateonBeforeUpdate更新前,可用于获取更新前各种状态
updatedupdatedonUpdated更新后,所有状态已是最新
beforeDestroybeforeUnmountonBeforeUnmount销毁前,可用于一些定时器或订阅的取消
destroyedunmountedonUnmounted销毁后,可用于一些定时器或订阅的取消
activatedactivatedonActivatedkeep-alive缓存的组件激活时
deactivateddeactivatedonDeactivatedkeep-alive缓存的组件停用时
errorCapturederrorCapturedonErrorCaptured捕获一个来自子孙组件的错误时调用
renderTrackedonRenderTracked调试钩子,响应式依赖被收集时调用
renderTriggeredonRenderTriggered调试钩子,响应式依赖被触发时调用
serverPrefetchonServerPrefetch组件实例在服务器上被渲染前调用

父子组件的生命周期执行顺序:

  • 加载渲染阶段:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  • 更新阶段:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 销毁阶段:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

在Vue.js中,组件的生命周期可以分为加载渲染阶段、更新阶段和销毁阶段。下面是对每个阶段的优化的详细说明:

加载渲染阶段优化:

  • 在父组件的beforeCreatecreated阶段,可以进行一些初始化工作,例如设置初始数据、引入必要的插件等。
  • 在父组件的beforeMount阶段,可以在DOM挂载之前进行一些准备工作,例如获取远程数据、计算属性等。
  • 在子组件的beforeCreatecreated阶段,可以进行一些子组件的初始化操作,例如设置子组件的初始状态、注册事件等。
  • 在子组件的beforeMount阶段,可以在DOM挂载之前进行一些子组件的准备工作,例如计算子组件的样式、绑定事件等。
  • 在子组件的mounted阶段,可以进行一些与DOM相关的操作,例如操作DOM元素、启动定时器等。
  • 在父组件的mounted阶段,可以进行一些与整个组件相关的操作,例如监听事件、发送请求等。

更新阶段优化:

  • 在父组件的beforeUpdate阶段,可以在更新之前进行一些准备工作,例如保存一些需要保持的数据、做一些计算等。
  • 在子组件的beforeUpdate阶段,可以在更新之前进行一些子组件的准备工作,例如更新子组件的状态、计算子组件的样式等。
  • 在子组件的updated阶段,可以进行一些与DOM相关的操作,例如操作DOM元素、更新样式等。
  • 在父组件的updated阶段,可以进行一些与整个组件相关的操作,例如重新计算属性、发送请求等。

销毁阶段优化:

  • 在父组件的beforeDestroy阶段,可以进行一些清理工作,例如取消事件监听、销毁定时器等。
  • 在子组件的beforeDestroy阶段,可以进行一些子组件的清理工作,例如解绑事件、释放资源等。
  • 在子组件的destroyed阶段,可以进行一些与DOM相关的操作,例如移除DOM元素、清空缓存等。
  • 在父组件的destroyed阶段,可以进行一些与整个组件相关的操作,例如释放内存、取消请求等。

2. 在Vue3应该如何使用Composition API?

Vue3.x的Composition API可以让开发者更灵活地组合和封装逻辑代码。使用Composition API需要先在component中调用setup()函数,这个函数会在component创建前被调用。之后,在setup()函数中,你可以使用新的reactive()函数来创建响应式数据对象,使用computed()函数来创建计算属性,使用watch()函数来监听数据变化等等。

import { reactive, computed, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
    });

    const doubleCount = computed(() => state.count * 2);

    watch(
      () => state.count,
      (newCount, oldCount) => {
        console.log(`state.count changed from ${oldCount} to ${newCount}`);
      }
    );

    function increment() {
      state.count++;
    }

    return {
      state,
      doubleCount,
      increment,
    };
  },
};

3. 在Vue3 中 computed 属性是如何工作的?它和一个函数方法有什么不同?

在Vue3中,computed属性仍然是一个函数,但是它的定义方式有所不同,可以使用 computed() 函数进行定义。

和一个普通的函数方法相比,computed属性的主要不同在于它具有缓存功能。当computed属性依赖的响应式数据发生变化时,computed函数会重新执行,但是在下一次访问computed属性时,会直接返回上一次执行的结果,而不是重新计算一遍。

例如,下面是一个计算税收的computed属性的示例:

import { computed, reactive } from 'vue'

const state = reactive({
  price: 100,
  taxRate: 0.1
})

const totalPrice = computed(() => {
  return state.price * (1 + state.taxRate)
})

console.log(totalPrice.value) // 110

state.price = 200

console.log(totalPrice.value) // 220
此外,computed属性也有一些其他的特点:
  1. computed属性必须返回一个值,而不能有副作用。computed属性只能用于计算数据(即根据已有的响应式数据计算出一个新的值),而不能在computed属性中直接修改其他响应式数据或引起其他副作用。
  2. computed属性可以被设置为只读或可写,如果需要在computed属性中修改其他响应式数据,可以使用 getset 方法。在定义computed属性时,可以通过设置get和set方法来控制computed属性的只读或可写状态,并且可以在set方法中修改其他响应式数据。
<template>
  <div>
    <p>Product name: {{productName}}</p>
    <button @click="updateProductName">Update</button>
  </div>
</template>

<script>
  import { computed, reactive } from "vue";

  export default {
    setup() {
      const data = reactive({
        count: 0,
        name: "Product"
      });

      const productName = computed({
        get() {
          return data.name + " " + data.count;
        },
        set(value) {
          [data.name, data.count] = value.split(" ");
        }
      });

      function updateProductName() {
        productName.value = "New Product 1";
      }

      return {
        productName,
        updateProductName
      };
    }
  };
</script>

4. 解释一下 Vue3中的 watch 和 watchEffect 的区别和用法。

Vue3中的 watchwatchEffect 都是用于监听数据变化的方法,但是二者的用法和实现方式略有不同。

watch是Vue2中的一个API,在Vue3中也有保留并进行了一些优化,它可以监听指定的数据变化,并执行对应的回调函数。 watch 接收两个参数,第一个参数是需要监听的数据,可以是一个函数,返回需要监听的数据值;第二个参数是回调函数,当监听的数据发生变化时,回调函数被调用。watch的代码示例如下:

const state = Vue.reactive({ count: 0 })
Vue.watch(() => state.count, (newVal, oldVal) => {
  console.log(`count变化了:${oldVal} -> ${newVal}`);
})
state.count++ // 在控制台输出:‘count变化了:0 -> 1’

watchEffect (API新增)是基于 reactive 实现的自动侦测响应式依赖的函数,其内部会自动收集响应式数据的依赖,当依赖发生变化时,自动重新执行回调函数并更新组件。watchEffect 只接收一个参数,就是需要执行的回调函数。watchEffect的代码示例如下:

const state = Vue.reactive({ count: 0 })
Vue.watchEffect(() => {
  console.log(`count变化了:${state.count}`);
})
state.count++ // 在控制台输出:‘count变化了:1’

相比于 watchwatchEffect 有着更强大的自动侦测能力,并且可以省略对监听数据的声明,使用起来更加方便。但是需要注意的是,watchEffect中的回调函数应该是纯函数,不能直接修改响应式数据的值,否则会造成无限循环更新的危险。同时,watchEffect 也不支持监听特定的响应式数据,只能监听所有响应式数据的变化。

5. 如何使用 Vue3 中的 watchEffect 来实现响应式数据的监听和更新?有什么注意事项?

watchEffect 是 Vue3 中新增的一个响应式 API,用于监听和响应状态的变化。它的用法类似于 computed,但是它不会返回计算结果,而是直接执行函数并收集依赖,当依赖发生变化时,会重新执行函数。

使用 watchEffect 监听响应式数据的变化非常简单,只需要在一个函数中使用 reactiveref 定义响应式数据,并在函数中使用 watchEffect 监听数据的变化即可。例如:

import { reactive, watchEffect } from 'vue'

const state = reactive({
  count: 0
})

watchEffect(() => {
  console.log(state.count)
})

上面的代码中,我们定义了一个响应式数据 state,然后使用 watchEffect 监听 state.count 的变化并输出变化后的值。当 state.count 的值发生变化时,watchEffect 会自动重新执行函数并输出最新的值。

注意事项:

  1. watchEffect 只能用在 setup 函数或单独的函数中,不能用在模板中。
  2. watchEffect 只能监听响应式数据的变化,不能监听非响应式数据的变化。
  3. watchEffect 返回的是一个停止监听的函数,可以在组件卸载时使用。
  4. watchEffect 中的依赖收集是自动的,不需要手动添加依赖,但是也要注意不要使用局部变量或闭包中的变量,因为它们不会被自动收集。

6. Vue3 中引入了 setup 方法,它有什么作用?它的执行时机是什么时候?

Vue3 中的 setup 方法是一个新的组件选项,用于代替 Vue2 中的 beforeCreatecreated 钩子函数以及 datamethods 等选项。它可以在组件实例创建之前执行,并且在组件实例创建之后,返回一个对象,将这个对象中的响应式数据以及函数暴露给组件模板使用。

以下是 setup 函数的简单示例:

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  setup() {
    const count = Vue.ref(0)

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}
</script>

setup 函数中,首先定义了一个 count 变量和一个 increment 函数,通过 Vue.ref() 创建了一个响应式的 count,并将其暴露给组件模板中使用。同时,将 increment 函数也暴露给模板,当按钮被点击时,将会触发 increment 函数,修改 count 的值。

此外,setup 函数还可以接收 props 对象和 context 对象作为参数,这两个参数分别包含了组件的属性以及组件实例的上下文信息。

  • props 参数包含了通过组件标签传入的属性值,可以通过解构赋值的方式使用。

  • context 参数包含了一些常用的 Vue 实例方法和属性,比如 emit 用于触发父组件事件、attrs 用于获取非 prop 特性、slots 用于获取插槽等。

setup 函数的执行时机在组件实例创建之前,它会在 Vue 内部先进行一次 beforeCreate 钩子函数的调用,而在组件实例创建之后,它会在 created 钩子函数调用之前被执行。
  • 需要注意的是,只有在 setup 函数中返回的对象中包含的属性和方法才能在组件模板中使用。如果在 setup 函数之外定义属性和方法,就算在 setup 函数内部使用,也不能在模板中直接使用。

  • 总的来说,setup 函数为 Vue 3 中的组件开发带来了更好的灵活性和可维护性,让我们能够更加方便地编写代码,提高开发效率。

7. Vue3 中的 <template v-for>v-for 指令的区别和用法。

在Vue3中,<template v-for>v-for 指令都可以用来遍历数组或对象并生成多个元素。它们的主要区别在于语法和用法。

<template v-for>是一种特殊的语法,它允许我们在一个 <template> 标签内编写多个元素,然后使用 v-for 指令来循环渲染这些元素。例如:

<template v-for="(item, index) in items">
  <li :key="index">{{ item }}</li>
</template>

在上面的例子中,<template>标签内包含了一个<li>元素,当v-for循环执行时,会根据items数组的长度生成多个<li>元素。使用<template v-for>的好处是可以避免在循环体内添加额外的标签,使得代码更简洁。

v-for指令的用法与Vue2相同。我们可以将v-for指令应用在任何元素上,例如:

<ul>
  <li v-for="(item, index) in items" :key="index">{{ item }}</li>
</ul>

在上面的例子中,v-for指令被应用在<li>元素上,当循环执行时,会根据items数组的长度生成多个<li>元素。v-for指令的优点是可以应用在任何元素上,使得我们可以更灵活地控制循环生成的元素。

总的来说,<template v-for>v-for指令都可以用来循环生成多个元素,选择使用哪种方式取决于具体的需求和习惯。

小程序刷题

搜索: zerojs零技术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值