2024.09.17 - 2024.09.22 更新前端面试问题总结(20 道题)
获取更多面试相关问题可以访问
github 地址: https://github.com/pro-collection/interview-question/issues
gitee 地址: https://gitee.com/yanleweb/interview-question/issues

目录:

  • 中级开发者相关问题【共计 10 道题】

      1. [Vue] vue 全局注册组件很方便,为何不都是用全局注册【热度: 592】【web 框架】【出题公司: TOP100 互联网】
      1. [Vue] 子组件定义接受的 props 方式有哪些【热度: 465】【web 框架】【出题公司: TOP100 互联网】
      1. [Vue] 子组件是否能使用 未定义的 props 【热度: 266】【web 框架】【出题公司: TOP100 互联网】
      1. [Vue] 介绍一下 defineModel【热度: 433】【web 框架】【出题公司: TOP100 互联网】
      1. [Vue] 介绍一下 defineEmits【热度: 346】【web 框架】
      1. [Vue] 介绍一下 Provide【热度: 633】【web 框架】
      1. [Vue] 如何自定义指令【热度: 159】【web 框架】
      1. [Vue] 插件是什么概念,有什么作用,该怎么用【热度: 550】【web 框架】
      1. [Vue] 有哪些内置组件【热度: 355】【web 框架】
      1. [Vue] 介绍一下 vue 工具链【热度: 53】【web 框架】
  • 高级开发者相关问题【共计 10 道题】

      1. [Vue] vue3 里面 <script setup> 作用是啥【热度: 210】【web 框架】
      1. [Vue] 都是支持响应式, defineModel 和 reactive 有何不同【热度: 344】【web 框架】【出题公司: TOP100 互联网】
      1. [Vue] 介绍一下条件插槽【热度: 100】【web 框架】
      1. [Vue] 介绍一下动态插槽名【web 框架】
      1. [Vue] 如何提升复用逻辑【热度: 671】【web 框架】
      1. [Vue] 组合式函数 和 vue2 mixins 对比, 有何优劣【热度: 311】【web 框架】
      1. [Vue] vue 如何配置全局使用的定义或者常量【热度: 337】【web 框架】
      1. [Vue] 实现一个简单的 i18n (国际化 (Internationalization) 的缩写) 插件【热度: 166】【web 框架】
      1. [Vue] 详细介绍一下 teleport 内置组件【热度: 100】【web 框架】
      1. [Vue] 介绍一下 component 动态组件【热度: 184】【web 框架】

917. [Vue] vue 全局注册组件很方便,为何不都是用全局注册【热度: 592】【web 框架】【出题公司: TOP100 互联网】

Vue 的全局注册组件确实提供了便利,特别是在组件需要跨多个视图或组件重复使用时。但是,如果全部或大量使用全局注册,也会带来一些缺点或问题。下面列举了几个不推荐全面使用全局注册组件的原因:

全局注册的组件会在应用启动时全部加载和注册,这对于小至中等规模的应用可能不是问题。但对于大型或超大型的应用,过多的全局注册会增加应用的启动时间和初始加载时间,对性能造成影响。

如果使用全局注册,就很难对组件进行代码分割和懒加载,这意味着即使用户当前不需要该组件,它们仍然会被加载。相反,局部注册组件可以结合 Vue 的动态组件和 Webpack 的代码分割特性,按需加载组件,减少首屏加载时间。

全局注册所有组件可能会导致组件命名冲突。在大型项目中,维护一个不冲突的全局命名空间会变得非常困难。局部注册可以在组件内解决名称冲突,更加灵活。

使用全局注册,开发者可能难以追踪某个组件的使用情况,因为它可以在任何地方被引用。相比之下,局部注册组件会在使用它的组件文件中明显显示出来,这使得项目结构更清晰,便于团队成员理解和维护。

对于基于模块的工具链(如 Webpack),局部注册的组件更容易被优化,因为未使用的组件可以在构建阶段被摇掉(Tree Shaking),减少最终的包大小。而全局注册的组件则更难被摇掉,因为构建工具很难确定它们是否在某处被使用。

虽然全局注册的组件更易于在任何地方重用,但其实使用局部注册也可以通过将组件导入到需要的组件中来重用组件,同时还能享受前面提到的好处。

918. [Vue] 子组件定义接受的 props 方式有哪些【热度: 465】【web 框架】【出题公司: TOP100 互联网】

关键词:组件定义 props

在 Vue 中,子组件可以通过 props 接收来自父组件的数据。props 是组件的可配置项之一,它允许外部环境传递数据给组件。有几种不同的方式来定义组件的 props,这些方式提供了不同级别的验证和默认值设置。以下是 Vue 中定义 props 的不同方式及其特点:

直接使用字符串数组列出所有想要接受的 props。这种方式最简单,但不提供额外的验证。

 1props: ["title", "likes", "isPublished", "commentIds", "author"];

使用对象形式,你可以为每个 prop 指定类型,这提供了基本的类型检查。type 可以是下列原生构造函数之一:StringNumberBooleanArrayObjectDateFunctionSymbol,或者这些构造函数组成的数组,表示多种可能的类型。

 1props: {
 2  title: String,
 3  likes: Number,
 4  isPublished: Boolean,
 5  commentIds: Array,
 6  author: Object,
 7  callback: Function,
 8  contactsPromise: Promise // 仅在 Vue 3 中可用
 9}

除了类型检查之外,还可以为每个 prop 指定默认值或验证函数。这种方式在需要确保组件的 prop 具有正确的类型或默认值时非常有用。

 1props: {
 2  title: {
 3    type: String,
 4    required: true
 5  },
 6  likes: {
 7    type: Number,
 8    default: 0
 9  },
10  isPublished: {
11    type: Boolean,
12    default: false
13  },
14  comments: {
15    type: Array,
16    // 对于对象或数组类型的 prop,必须使用一个函数来返回默认值
17    default: function () {
18      return []
19    }
20  },
21  author: {
22    type: Object,
23    default: function () {
24      return { name: 'Anonymous' }
25    }
26  },
27  callback: {
28    type: Function,
29    // 默认值为一个函数
30    default: function () {
31      return () => {}
32    }
33  }
34}

可以为 props 提供一个自定义验证函数。如果验证失败,则 Vue 会发出警告(仅在开发模式下)。这种方式适用于需要进行更复杂验证的场景。

 1props: {
 2  age: {
 3    type: Number,
 4    validator: function (value) {
 5      // 这个值必须匹配下面的条件
 6      return value > 0 && value < 100;
 7    }
 8  }
 9}

919. [Vue] 子组件是否能使用 未定义的 props 【热度: 266】【web 框架】【出题公司: TOP100 互联网】

关键词:组件定义 props

在 Vue 中,子组件默认情况下不能使用未在 props 选项中明确定义的属性。Vue 的组件系统旨在明确组件之间的接口,其中 props 作为组件公开的属性,必须被明确声明。这样做的目的是为了增强代码的可读性和可维护性,确保组件之间的通信清晰和有序。

尽管子组件不能直接使用未声明的 props,但它可以通过继承未声明的属性来接收来自父组件的非 props 属性。Vue 实例的 $attrs 对象包含了传递给一个组件,但是未在 props 配置中声明的属性。这些属性包括 classstyle,以及绑定的事件监听器(如果 inheritAttrs 配置项设置为 false)。

 1<!-- 子组件 -->
 2<template>
 3  <div>{{ $attrs.someProp }}</div>
 4</template>
 5
 6<script>
 7  export default {
 8    // 如果你不希望组件的根元素继承属性,可以设置 inheritAttrs: false
 9    inheritAttrs: false,
10  };
11</script>

虽然不推荐这种做法,但理论上,如果你通过动态的方式绑定父组件的属性到子组件上,并在子组件内部使用 this.$props 来访问这些属性,Vue 会警告未找到对应的 prop 定义,但这并不会阻止你在组件内部获取这些属性的值。

 1<!-- 子组件 -->
 2<template>
 3  <div>{{ $props.someUndeclaredProp }}</div>
 4</template>

这种方式不利于保持组件接口的清晰,很容易导致难以跟踪和理解的代码,因此并不推荐使用。

最佳实践是始终在子组件中明确声明你打算使用的所有 props。这有助于保持接口清晰,并使得组件之间的通信更加可靠和可维护。使用 $attrs 是处理未声明属性的推荐方式,尤其是当你需要构建高度复用的组件库时,它能提供额外的灵活性,而且可以保持组件接口的整洁和明确。

920. [Vue] 介绍一下 defineModel【热度: 433】【web 框架】【出题公司: TOP100 互联网】

关键词:vue3 双向绑定 defineModel

在 Vue 3 中,defineModel是一个用于简化双向绑定的函数,通常与组合式函数(composition function)一起使用。

一、主要作用

  1. 自动解包响应式对象
    • 当在组合式函数中使用响应式对象时,使用defineModel可以自动解包响应式对象的属性,使得这些属性可以在模板中直接使用,无需通过.value来访问。
    • 例如,如果有一个响应式对象state,其中包含属性count,在不使用defineModel时,在模板中需要使用state.count.value来访问count的值。但使用defineModel后,可以直接在模板中使用count
  2. 实现双向绑定
    • 配合v-model指令使用时,defineModel可以轻松实现双向绑定。它会自动处理输入事件,并将新的值更新到响应式对象中。
    • 例如,在一个自定义组件中,使用defineModel可以让组件的props中的一个值与组件内部的状态实现双向绑定,使得父组件和子组件之间的数据传递更加方便。

二、使用方法

  1. 导入defineModel

    • 在组合式函数中,首先需要从'vue'模块中导入defineModel函数。
     1import { defineModel } from "vue";
  2. 使用defineModel

    • 在组合式函数内部,将需要双向绑定的响应式对象作为参数传递给defineModel
     1import { reactive } from "vue";
     2
     3export default function useCounter() {
     4  const state = reactive({
     5    count: 0,
     6  });
     7
     8  return defineModel(() => ({
     9    count: state.count,
    10  }));
    11}
    • 在上面的例子中,state.count是一个响应式属性,通过defineModel函数返回后,可以在模板中直接使用count进行双向绑定。
  3. 在模板中使用

    • 在组件的模板中,可以使用v-model指令来绑定使用了defineModel的属性。
     1<template>
     2  <div>
     3    <input v-model="count" />
     4  </div>
     5</template>
     6
     7<script setup>
     8  import useCounter from "./useCounter";
     9  const { count } = useCounter();
    10</script>
    • 在这个例子中,input元素的v-model绑定了count属性,当用户在输入框中输入内容时,count的值会自动更新,实现了双向绑定。

三、优势和适用场景

  1. 优势
    • 简化代码:减少了在模板中访问响应式属性时需要添加.value的繁琐操作,使代码更加简洁易读。
    • 方便双向绑定:特别是在自定义组件中,使用defineModel可以快速实现双向绑定,提高开发效率。
  2. 适用场景
    • 自定义组件开发:当开发自定义组件时,如果需要实现双向绑定的属性,使用defineModel可以简化代码,提高组件的易用性。
    • 复杂业务逻辑处理:在组合式函数中处理复杂的业务逻辑时,defineModel可以帮助更好地管理响应式数据,实现数据的双向绑定。

922. [Vue] 介绍一下 defineEmits【热度: 346】【web 框架】

关键词:介绍一下 defineEmits

在 Vue 3 中,defineEmits是一个用于定义组件触发的自定义事件的函数。

一、作用与目的

在 Vue 3 的组合式 API 中,使用defineEmits可以明确地声明组件向外触发的事件类型,这有助于提高代码的可读性和可维护性。通过定义触发的事件,其他使用该组件的地方可以清楚地知道组件可能会触发哪些事件,以便进行相应的处理。

二、使用方法

  1. 基本用法:
 1<script setup>
 2import { defineEmits } from "vue";
 3
 4const emits = defineEmits(["customEvent1", "customEvent2"]);
 5
 6// 在某个逻辑中触发自定义事件
 7emits("customEvent1", arg1, arg2);
 8</script>

在这个例子中,定义了一个组件,该组件可以触发名为customEvent1customEvent2的两个自定义事件。

  1. 带参数的事件:

可以定义带参数的事件,在触发事件时传递相应的参数。例如:

 1<script setup>
 2import { defineEmits } from "vue";
 3
 4const emits = defineEmits(["eventWithArgs", "eventWithoutArgs"]);
 5
 6function someFunction() {
 7  const argValue = "some value";
 8  emits("eventWithArgs", argValue);
 9}
10</script>

这里定义了一个带参数的事件eventWithArgs,在someFunction函数中触发该事件并传递了一个参数。

三、优势

  1. 类型安全:明确了事件的名称和参数类型,减少了因事件名称错误或参数传递错误导致的问题。
  2. 清晰的组件接口:让使用者更容易理解组件的行为和交互方式。
  3. 更好的维护性:在代码重构或团队协作时,更容易找到和处理与事件相关的逻辑。

925. [Vue] 介绍一下 Provide【热度: 633】【web 框架】

关键词:vue3 Provide

Vue 3 中的 provideinject 功能提供了一种方法,允许祖先组件将数据“提供”给它的所有后代组件,无论后代组件位于组件树的何处,而不必通过所有的组件层层传递属性(props)。这对于深层嵌套的组件或跨多个组件共享状态特别有用。

你可以在任何组件中使用 provide 选项来提供数据。provide 选项应该是一个对象或返回对象的函数,其中的每个属性都可以被子组件注入。从 Vue 3 开始,provideinject 绑定现在是响应式的。

在 Vue 3 中,建议在 setup() 函数中使用 provide 函数,因为 setup 是组合式 API 的入口点。

 1import { provide } from "vue";
 2
 3export default {
 4  setup() {
 5    // 提供 'theme' 数据
 6    provide("theme", "dark");
 7  },
 8};

后代组件可以使用 inject 选项来接收数据。inject 选项应该是一个字符串数组,列出需要注入的属性名。

 1import { inject } from "vue";
 2
 3export default {
 4  setup() {
 5    const theme = inject("theme");
 6    return { theme };
 7  },
 8};

假设你正在开发一个应用,该应用有一个主题切换功能,你可以在顶层组件中提供当前主题,而所有子组件都可以注入这个主题信息,而不必通过层层传递。

如果要提供的数据是响应式的,并且希望后代组件能够响应数据的变化,你需要使用 Vue 的响应式系统函数,例如 reactiveref

 1import { provide, reactive } from "vue";
 2
 3export default {
 4  setup() {
 5    const theme = reactive({ color: "dark" });
 6    provide("theme", theme);
 7  },
 8};

后代组件同样可以如上所示通过 inject 获取这个响应式的数据。

  • provideinject 提供的依赖关系不是可靠的,并且不应该在业务逻辑中频繁使用,以避免复杂的跨组件通讯导致应用难以维护。它通常被用于开发可复用的插件或高阶组件。
  • 使用这两个选项时,注入的数据在后代组件中并不是响应式的,除非使用了 Vue 的响应式系统(如 reactiveref)来提供这些数据。
  • 如果 inject 未找到提供的键,则它默认返回 undefined。你可以通过提供第二个参数作为默认值来改变这一行为。

总的来说,provideinject 是 Vue 3 中解决跨多个组件共享状态问题的一个非常有用的功能,尤其适用于开发高阶组件或插件时使用。

928. [Vue] 如何自定义指令【热度: 159】【web 框架】

关键词:vue 自定义指令

在 Vue 中,可以通过以下步骤来自定义指令:

一、全局自定义指令

  1. 使用Vue.directive()方法定义全局指令:

     1Vue.directive("my-directive", {
     2  // 指令的定义对象
     3  bind(el, binding, vnode) {
     4    // 在元素绑定指令时调用
     5    // el 是指令所绑定的元素
     6    // binding 包含指令的信息,如 value、arg、modifiers 等
     7    // vnode 是虚拟节点
     8  },
     9  inserted(el, binding, vnode) {
    10    // 被绑定元素插入父节点时调用
    11  },
    12  update(el, binding, vnode, oldVnode) {
    13    // 当组件更新时调用,包括数据更新和组件本身的更新
    14  },
    15  componentUpdated(el, binding, vnode, oldVnode) {
    16    // 组件及其子组件的 VNode 更新后调用
    17  },
    18  unbind(el, binding, vnode) {
    19    // 指令与元素解绑时调用
    20  },
    21});
  2. 在模板中使用自定义指令:

     1<div v-my-directive="someValue"></div>

二、局部自定义指令

  1. 在组件中定义局部指令:

     1export default {
     2  directives: {
     3    "my-directive": {
     4      bind(el, binding, vnode) {
     5        // 指令定义
     6      },
     7    },
     8  },
     9};
  2. 在组件的模板中使用局部自定义指令:

     1<template>
     2  <div v-my-directive="someValue"></div>
     3</template>

三、指令定义对象的参数说明

  1. el:指令所绑定的元素,可以通过这个参数来操作元素的属性、样式等。
  2. binding:一个对象,包含以下属性:
    • value:指令的绑定值,例如在v-my-directive="someValue"中,value就是someValue的值。
    • arg:指令的参数,如果指令是v-my-directive:argName,那么arg就是argName
    • modifiers:一个对象,包含指令的修饰符。
  3. vnode:虚拟节点,代表指令所绑定的元素的虚拟节点。
  4. oldVnode:上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。

四、自定义指令的应用场景

  1. 操作 DOM 元素:例如,在特定条件下为元素添加或移除类名、设置样式、监听元素的事件等。
  2. 实现复杂的交互效果:比如拖拽、缩放、滚动监听等。
  3. 数据格式化:在将数据绑定到元素之前对数据进行格式化处理。

930. [Vue] 插件是什么概念,有什么作用,该怎么用【热度: 550】【web 框架】

关键词:vue 插件

在 Vue 中,插件是一种用于增强 Vue 功能的工具。

一、概念

Vue 插件是一个包含install方法的对象,或者是一个函数,这个函数接收 Vue 的构造函数作为参数。插件可以为 Vue 添加全局的功能,如全局组件、全局指令、全局过滤器、全局混入(mixin)等,也可以扩展 Vue 的实例方法或原型属性。

二、作用

  1. 添加全局功能
    • 全局组件:可以通过插件注册全局组件,使得在整个项目的任何组件中都可以直接使用这个组件,无需在每个组件中单独引入。例如,一个弹窗组件可以作为插件注册为全局组件,方便在项目中的各个地方弹出统一风格的弹窗。
    • 全局指令:插件可以添加全局指令,用于在模板中对元素进行特定的操作。比如,一个v-focus指令可以在元素挂载时自动聚焦该元素,提高用户体验。
    • 全局过滤器:用于对数据进行格式化处理。例如,一个全局过滤器可以将日期格式化为特定的字符串格式,方便在模板中显示日期数据。
    • 全局混入:可以在多个组件之间共享一些通用的选项或方法。例如,一个全局混入可以为多个组件添加相同的生命周期钩子函数或方法,减少重复代码。
  2. 扩展 Vue 实例
    • 插件可以向 Vue 实例添加新的方法或属性,使得在项目中的任何地方都可以通过this访问这些方法或属性。例如,一个插件可以添加一个$http方法,用于发送 HTTP 请求,方便在组件中进行数据获取。
  3. 集成第三方库
    • 可以将第三方库包装成 Vue 插件,使其与 Vue 更好地集成。例如,将 Vue Router(路由库)和 Vuex(状态管理库)作为插件使用,方便在 Vue 项目中进行路由管理和状态管理。

三、使用方法

  1. 创建插件

    • 插件可以是一个对象,包含install方法:
     1const myPlugin = {
     2  install(Vue) {
     3    // 在这里添加全局功能或扩展 Vue 实例
     4    Vue.prototype.$myMethod = function () {
     5      console.log("This is a custom method added by the plugin.");
     6    };
     7  },
     8};
    • 也可以是一个函数,接收 Vue 构造函数作为参数:
     1function myPlugin(Vue) {
     2  Vue.prototype.$myMethod = function () {
     3    console.log("This is a custom method added by the plugin.");
     4  };
     5}
  2. 使用插件

    • 在 Vue 项目中,可以通过Vue.use()方法来使用插件。通常在项目的入口文件(如main.js)中进行插件的安装。
     1import Vue from "vue";
     2import App from "./App.vue";
     3// 引入插件
     4import myPlugin from "./myPlugin";
     5
     6Vue.use(myPlugin);
     7
     8new Vue({
     9  render: (h) => h(App),
    10}).$mount("#app");
  3. 在组件中使用插件提供的功能

    • 在组件的方法、生命周期钩子函数或模板中,可以通过this.$myMethod()来调用插件添加的方法。
     1<template>
     2  <div @click="callPluginMethod">Click me</div>
     3</template>
     4<script>
     5  export default {
     6    methods: {
     7      callPluginMethod() {
     8        this.$myMethod();
     9      },
    10    },
    11  };
    12</script>

通过使用插件,可以将一些通用的功能封装起来,提高代码的可维护性和可复用性,同时也方便在项目中进行功能的扩展和集成第三方库。

932. [Vue] 有哪些内置组件【热度: 355】【web 框架】

关键词:vue 内置组件

在 Vue 中,有一些内置组件,主要包括以下几个:

一、<component>动态组件

  1. 作用:用于根据条件动态地渲染不同的组件。

  2. 使用方法:

     1<template>
     2  <div>
     3    <component :is="currentComponent"></component>
     4    <button @click="toggleComponent">Toggle Component</button>
     5  </div>
     6</template>
     7
     8<script setup>
     9import ComponentA from "./ComponentA.vue";
    10import ComponentB from "./ComponentB.vue";
    11
    12let currentComponent = ComponentA;
    13
    14const toggleComponent = () => {
    15  currentComponent = currentComponent === ComponentA ? ComponentB : ComponentA;
    16};
    17</script>

二、<transition>过渡组件

  1. 作用:为元素或组件的插入、更新和移除添加过渡效果。

  2. 使用方法:

     1<template>
     2  <div>
     3    <transition name="fade">
     4      <p v-if="show">Hello World</p>
     5    </transition>
     6    <button @click="toggleShow">Toggle</button>
     7  </div>
     8</template>
     9
    10<script setup>
    11import { ref } from "vue";
    12
    13const show = ref(true);
    14const toggleShow = () => {
    15  show.value = !show.value;
    16};
    17</script>
    18
    19<style>
    20.fade-enter-active,
    21.fade-leave-active {
    22  transition: opacity 0.5s;
    23}
    24.fade-enter-from,
    25.fade-leave-to {
    26  opacity: 0;
    27}
    28</style>

三、<teleport>传送门组件

  1. 作用:将一个组件的模板内容渲染到指定的 DOM 节点位置,而不是在组件自身的位置。

  2. 使用方法:

     1<template>
     2  <div>
     3    <teleport to="body">
     4      <div class="modal">This is a modal content.</div>
     5    </teleport>
     6  </div>
     7</template>
     8
     9<style>
    10.modal {
    11  position: fixed;
    12  top: 50%;
    13  left: 50%;
    14  transform: translate(-50%, -50%);
    15  background-color: white;
    16  padding: 20px;
    17  border: 1px solid #ccc;
    18}
    19</style>

四、<keep-alive>缓存组件

  1. 作用:在组件切换时缓存不活动的组件实例,避免重复渲染,提高性能。

  2. 使用方法:

     1<template>
     2  <div>
     3    <keep-alive>
     4      <component :is="currentComponent"></component>
     5    </keep-alive>
     6    <button @click="toggleComponent">Toggle Component</button>
     7  </div>
     8</template>
     9
    10<script setup>
    11import ComponentA from "./ComponentA.vue";
    12import ComponentB from "./ComponentB.vue";
    13
    14let currentComponent = ComponentA;
    15
    16const toggleComponent = () => {
    17  currentComponent = currentComponent === ComponentA ? ComponentB : ComponentA;
    18};
    19</script>

935. [Vue] 介绍一下 vue 工具链【热度: 53】【web 框架】

关键词:vue 工具链

作者备注

这个其实没有啥好说的, 官网上面都有。 直接看官网即可 https://cn.vuejs.org/guide/scaling-up/tooling

以下是 Vue 的相关工具链介绍:

一、项目脚手架

  1. Vue CLI
    • 功能:Vue CLI 是一个官方的 Vue.js 项目脚手架工具。它提供了快速搭建 Vue 项目的模板和配置选项,可以轻松生成项目结构、配置开发服务器、集成各种构建工具和插件等。
    • 特点:支持多种项目模板,如默认模板、移动端模板、PWA(Progressive Web App)模板等。可以方便地进行项目配置和扩展,如添加路由、状态管理、单元测试等功能模块。

二、IDE 支持

  1. Visual Studio Code

    • 功能:一款非常流行的轻量级代码编辑器,对 Vue 有很好的支持。通过安装 Vue 相关的扩展插件,可以实现语法高亮、智能提示、代码片段、调试等功能。
    • 特点:拥有丰富的扩展生态系统,如 Vetur 插件提供了全面的 Vue 开发支持,包括单文件组件(SFC)的语法高亮、模板智能提示、组件自动补全等功能。同时,VS Code 的调试功能也非常强大,可以方便地对 Vue 项目进行调试。
  2. WebStorm

    • 功能:一款功能强大的专业 IDE,对 Vue 也有很好的支持。提供了全面的开发功能,包括语法高亮、智能提示、代码重构、调试、版本控制等。
    • 特点:具有强大的代码分析和错误检测功能,可以帮助开发者快速发现和修复代码中的问题。同时,WebStorm 还支持多种前端技术栈,方便开发者在一个 IDE 中进行多种技术的开发。

三、Chrome 开发插件

  1. Vue Devtools
    • 功能:这是 Vue.js 官方推出的 Chrome 浏览器插件。它可以帮助开发者在浏览器中调试 Vue 应用程序,提供了组件层次结构查看、状态检查、事件监听、性能分析等功能。
    • 特点:能够实时查看 Vue 应用的组件结构和状态,方便开发者进行调试和优化。可以在开发过程中快速定位问题,提高开发效率。

四、TS 支持

  1. Vue + TypeScript
    • 功能:Vue 本身支持 TypeScript,可以使用 TypeScript 来编写 Vue 应用程序。通过使用 TypeScript,可以获得静态类型检查、更好的代码提示和自动补全等功能,提高代码的可维护性和可扩展性。
    • 特点:Vue 提供了专门的类型定义文件,可以让 TypeScript 正确地识别 Vue 的语法和 API。同时,Vue 的官方文档也提供了详细的 TypeScript 支持指南,帮助开发者快速上手。

五、测试

  1. Jest

    • 功能:一个流行的 JavaScript 测试框架,也适用于 Vue 项目。可以用于单元测试、集成测试和快照测试等。提供了丰富的断言库和测试工具,方便开发者编写和运行测试用例。
    • 特点:具有自动模拟、并行测试、代码覆盖率报告等功能。可以与 Vue CLI 集成,方便地进行项目的测试配置和运行。
  2. Vue Test Utils

    • 功能:这是 Vue.js 官方提供的测试工具库,用于编写 Vue 组件的单元测试。提供了一系列的 API,可以方便地获取组件实例、模拟用户交互、检查组件状态等。
    • 特点:与 Jest 等测试框架配合使用,可以方便地对 Vue 组件进行测试。支持 Vue 的各种特性,如响应式数据、计算属性、生命周期钩子等。

六、代码规范

  1. ESLint

    • 功能:一个强大的 JavaScript 代码检查工具,可以用于检查 Vue 项目中的代码规范问题。可以配置各种规则和插件,对代码的格式、语法、风格等进行检查和规范。
    • 特点:拥有丰富的规则集和插件生态系统,可以根据项目的需求进行定制化配置。可以与各种开发工具集成,如 VS Code、WebStorm 等,在开发过程中实时检查代码规范问题。
  2. Prettier

    • 功能:一个代码格式化工具,可以自动格式化 Vue 项目中的代码,使其符合统一的代码风格。支持多种前端技术栈,包括 JavaScript、Vue、CSS 等。
    • 特点:具有简洁的配置和快速的格式化速度。可以与各种开发工具集成,实现自动格式化功能,提高代码的可读性和可维护性。

七、格式化

  1. Prettier
    • 如上述代码规范中提到,Prettier 主要用于代码格式化,确保代码风格的一致性。它可以自动格式化 Vue 的单文件组件、JavaScript、CSS 等代码,使代码更加易读和易于维护。

八、单文件组件自定义块集成

  1. Vue Loader
    • 功能:这是 Webpack 或 Vue CLI 中用于处理 Vue 单文件组件的加载器。它可以解析 Vue 的单文件组件,将其拆分为模板、脚本和样式三个部分,并进行相应的处理和编译。
    • 特点:支持自定义块的处理,可以通过在单文件组件中添加自定义的块标签,如<docs><config>等,来扩展组件的功能和文档。可以与各种构建工具和插件集成,实现更强大的功能。

九、底层库

  1. Vue Router

    • 功能:Vue 的官方路由库,用于实现单页应用的路由功能。可以定义不同的路由路径,对应不同的组件显示,实现页面之间的导航和切换。
    • 特点:支持动态路由、嵌套路由、路由守卫等功能。可以与 Vue 的响应式系统深度集成,实现流畅的页面切换和导航体验。
  2. Vuex

    • 功能:Vue 的官方状态管理库,用于集中管理 Vue 应用的状态。可以将应用中的数据存储在一个集中的状态容器中,通过 mutations 和 actions 来修改状态,实现数据的共享和管理。
    • 特点:支持模块化、严格模式、插件扩展等功能。可以与 Vue 的组件系统深度集成,实现高效的数据管理和响应式更新。

916. [Vue] vue3 里面 <script setup> 作用是啥【热度: 210】【web 框架】

关键词<script setup> 作用

在 Vue 3 中,<script setup> 是一种新的组件编写方式,旨在使组件的编写更为简洁明了。它是 Composition API 的一个语法糖,提供了一种更为简洁和易用的方式来定义组件。使用 <script setup> 可以带来几个主要好处:

通过 <script setup>,你可以直接在 <script> 标签内使用 Composition API(如 ref, reactive, computed, watch, 等),而无需明确地定义 setup() 函数。这减少了引导性的样板代码,使得组件的逻辑更加紧凑和易读。

对于使用 TypeScript 的项目,<script setup> 提供了更好的类型推断支持。在 <script setup> 中声明的变量和函数会自动被视为组件的一部分,使得类型推断更为直接和准确。

3. 易于使用 Composition API 特性

使用 <script setup>,所有顶级的绑定(如变量、函数等)都自动认为是组件的一部分,并且可以在模板中直接使用,无需返回对象。

<script setup> 提供了特殊的编译时 definePropsdefineEmits 函数,允许你以更声明式的方式定义组件的 props 和 emits,同时也提供了类型推断的好处。

为了展示 <script setup> 如何使 Vue 3 组件代码更加简洁,让我们对比传统的 Composition API 用法和使用 <script setup> 语法的用法。

使用传统 Composition API 的组件

 1<template>
 2  <button @click="increment">{{ count }}</button>
 3</template>
 4
 5<script>
 6  import { ref, defineComponent } from "vue";
 7
 8  export default defineComponent({
 9    setup() {
10      const count = ref(0);
11
12      function increment() {
13        count.value++;
14      }
15
16      return { count, increment };
17    },
18  });
19</script>

在这个例子中,我们首先需要从 vue 导入 refdefineComponent。然后,我们通过 defineComponent 函数定义组件,并在 setup 函数中定义响应式状态和函数,最后返回这些响应式状态和函数以在模板中使用它们。

使用 <script setup> 的组件

 1<template>
 2  <button @click="increment">{{ count }}</button>
 3</template>
 4
 5<script setup>
 6  import { ref } from "vue";
 7
 8  const count = ref(0);
 9
10  function increment() {
11    count.value++;
12  }
13</script>

当使用 <script setup> 时,我们不需要使用 defineComponent 来定义组件或在 setup 函数中返回响应式状态和方法。相反,我们可以直接定义响应式状态和函数,这些都会自动被视为组件的一部分,并且可以在模板中直接使用。

921. [Vue] 都是支持响应式, defineModel 和 reactive 有何不同【热度: 344】【web 框架】【出题公司: TOP100 互联网】

关键词:defineModel 和 reactive 异同

在 Vue 3 中,defineModelreactive虽然都与响应式相关,但它们有以下不同之处:

  1. reactive

    • 主要用于创建响应式对象。它接收一个普通的 JavaScript 对象,并将其转换为响应式对象,使得对这个对象的属性进行修改时,可以触发依赖这个对象的组件重新渲染。
    • 例如:
     1import { reactive } from "vue";
     2const state = reactive({
     3  count: 0,
     4});
     5state.count++; // 修改响应式对象的属性,会触发相关组件重新渲染
  2. defineModel

    • 主要用于在组合式函数中简化双向绑定的实现。它通常与reactive等响应式函数一起使用,自动解包响应式对象的属性,使得这些属性可以在模板中直接使用,无需通过.value来访问,并且方便与v-model指令配合实现双向绑定。
    • 例如:
     1import { reactive, defineModel } from "vue";
     2export default function useCounter() {
     3  const state = reactive({
     4    count: 0,
     5  });
     6  return defineModel(() => ({
     7    count: state.count,
     8  }));
     9}
  3. reactive

    • 直接接收一个普通对象作为参数,返回一个响应式对象。这个响应式对象的属性可以在组件的逻辑部分(如setup函数、方法等)中被修改,从而触发视图更新。
    • 例如在组件中使用:
     1<template>
     2  <div>{{ state.count }}</div>
     3</template>
     4<script setup>
     5  import { reactive } from "vue";
     6  const state = reactive({
     7    count: 0,
     8  });
     9  setTimeout(() => {
    10    state.count++;
    11  }, 1000);
    12</script>
  4. defineModel

    • 在组合式函数中使用,通常返回一个对象,其中包含需要进行双向绑定的属性。这个对象中的属性可以在模板中直接使用v-model指令进行双向绑定。
    • 例如:
     1<template>
     2  <div>
     3    <input v-model="count" />
     4  </div>
     5</template>
     6<script setup>
     7  import useCounter from "./useCounter";
     8  const { count } = useCounter();
     9</script>
  5. reactive

    • 创建的响应式对象可以在整个组件中使用,包括模板、setup函数、方法等。它主要用于管理组件的状态数据,使得这些数据的变化能够反映到视图中。
  6. defineModel

    • 主要作用于组合式函数中,用于处理特定的逻辑并返回可以在模板中进行双向绑定的属性。它的作用范围相对较窄,主要是为了方便实现双向绑定的场景。
  7. reactive

    • 如果要在自定义组件中使用reactive创建的响应式对象与父组件进行双向绑定,需要手动处理v-model绑定的值的传递和更新。通常需要在组件的props中接收一个值,并在组件内部通过事件触发将更新后的值传递回父组件。
    • 例如:
     1<template>
     2  <div>
     3    <input :value="inputValue" @input="$emit('update:inputValue', $event.target.value)" />
     4  </div>
     5</template>
     6<script setup>
     7  defineProps(["inputValue"]);
     8</script>
  8. defineModel

    • v-model配合更加方便,使用defineModel返回的属性可以直接在模板中使用v-model进行双向绑定,无需手动处理事件的触发和值的传递。它自动处理了输入事件,并将新的值更新到响应式对象中。

923. [Vue] 介绍一下条件插槽【热度: 100】【web 框架】

关键词:vue3 条件插槽

在 Vue 3 中,条件插槽(Conditional Slots)允许根据特定条件来渲染不同的内容到插槽中,为组件的灵活性和可扩展性提供了强大的支持。

插槽(Slots)是 Vue 中一种用于在组件中传递内容的机制。而条件插槽则在此基础上,通过在父组件中使用条件判断来决定向子组件的插槽中传递哪些内容。

  1. 在子组件中定义插槽:

     1<template>
     2  <div>
     3    <slot v-if="condition" name="conditionalSlot"></slot>
     4    <slot v-else name="defaultSlot"></slot>
     5  </div>
     6</template>

    在这个子组件中,根据条件condition来决定渲染名为conditionalSlot的插槽还是名为defaultSlot的插槽。

  2. 在父组件中使用条件插槽:

     1<template>
     2  <ChildComponent>
     3    <template v-if="someCondition" #conditionalSlot>
     4      <!-- 条件成立时要渲染的内容 -->
     5      <p>Conditional content</p>
     6    </template>
     7    <template v-else #defaultSlot>
     8      <!-- 条件不成立时要渲染的内容 -->
     9      <p>Default content</p>
    10    </template>
    11  </ChildComponent>
    12</template>

    在父组件中,根据someCondition的值来决定向子组件的插槽中传递不同的内容。

  3. 动态性:可以根据不同的条件动态地渲染不同的内容,使组件更加灵活适应各种场景。

  4. 可维护性:将不同情况下的内容分别组织在不同的模板中,使得代码更加清晰易读,便于维护。

  5. 复用性:通过条件插槽,可以在不同的场景下复用同一个子组件,只需要在父组件中根据不同的条件传递不同的内容即可。

924. [Vue] 介绍一下动态插槽名【web 框架】

关键词:vue3 动态插槽名

在 Vue 3 中,动态插槽名允许在运行时根据特定的条件动态地确定插槽的名称,从而为组件的渲染提供了更大的灵活性。

通常情况下,插槽名在组件定义时是固定的。但在某些场景中,可能需要根据不同的情况动态地选择要渲染的插槽。Vue 3 引入了动态插槽名的特性,使得可以在运行时动态地确定插槽的名称。

  1. 在子组件中接收动态插槽:

     1<template>
     2  <div>
     3    <slot :name="dynamicSlotName"></slot>
     4  </div>
     5</template>
     6
     7<script setup>
     8import { ref } from "vue";
     9const dynamicSlotName = ref("defaultSlot");
    10</script>

    在这个子组件中,通过ref定义了一个名为dynamicSlotName的响应式变量,用于动态确定插槽的名称。

  2. 在父组件中使用动态插槽名:

     1<template>
     2  <ChildComponent>
     3    <template v-for="slotName in slotNames" :key="slotName" #[slotName]>
     4      <!-- 根据不同的插槽名渲染不同的内容 -->
     5      <p v-if="slotName === 'slot1'">Content for slot1</p>
     6      <p v-else-if="slotName === 'slot2'">Content for slot2</p>
     7    </template>
     8  </ChildComponent>
     9</template>
    10
    11<script setup>
    12import { ref } from "vue";
    13const slotNames = ref(["slot1", "slot2"]);
    14</script>

    在父组件中,使用v-for循环遍历一个包含插槽名的数组,并根据不同的插槽名渲染不同的内容。通过这种方式,可以动态地将内容传递给子组件的不同插槽。

  3. 灵活性:可以根据不同的条件动态地选择要渲染的插槽,使得组件能够适应各种复杂的场景。

  4. 可扩展性:在需要根据不同的情况展示不同的内容时,动态插槽名提供了一种简洁而强大的方式,无需为每个可能的情况创建单独的组件。

  5. 代码复用:通过动态插槽名,可以在不同的组件中复用相同的逻辑,只需要在父组件中根据不同的需求传递不同的插槽名即可。

926. [Vue] 如何提升复用逻辑【热度: 671】【web 框架】

关键词:vue3 复用逻辑

在 Vue 3 中,可以通过以下几种方式提升复用逻辑:

一、组合式函数(Composables)

  1. 定义与使用:

    • 组合式函数是一个封装了可复用逻辑的函数,可以接收参数并返回响应式数据和方法。例如:

       1import { ref } from "vue";
       2
       3export function useCounter(initialValue = 0) {
       4  const count = ref(initialValue);
       5  const increment = () => count.value++;
       6  const decrement = () => count.value--;
       7
       8  return { count, increment, decrement };
       9}
    • 在组件中使用组合式函数:

       1<script setup>
       2import { useCounter } from "./path/to/composable";
       3
       4const { count, increment, decrement } = useCounter();
       5</script>
       6
       7<template>
       8  <div>
       9    Count: {{ count }}
      10    <button @click="increment">Increment</button>
      11    <button @click="decrement">Decrement</button>
      12  </div>
      13</template>
  2. 优势:

    • 可维护性高:将可复用的逻辑封装在独立的函数中,使得代码更易于理解和维护。
    • 可测试性强:可以单独对组合式函数进行测试,而不需要依赖于整个组件。
    • 易于复用:可以在多个组件中导入和使用相同的组合式函数。

二、自定义指令

  1. 定义与使用:

    • 自定义指令可以在元素上应用特定的行为。例如:

       1const focusDirective = {
       2  mounted(el) {
       3    el.focus();
       4  },
       5};
       6
       7export default focusDirective;
    • 在组件中使用自定义指令:

       1<script setup>
       2import focusDirective from "./path/to/directive";
       3</script>
       4
       5<template>
       6  <input v-focus />
       7</template>
  2. 优势:

    • 特定行为复用:对于一些需要在多个元素上重复应用的特定行为,可以通过自定义指令进行复用。
    • 解耦逻辑:将特定的行为从组件的逻辑中分离出来,使得组件更加专注于业务逻辑。

三、混入(Mixins)

  1. 定义与使用:

    • 混入是一种可以将多个组件的可复用选项合并到一个对象中的方式。例如:

       1const myMixin = {
       2  data() {
       3    return {
       4      commonData: "This is common data",
       5    };
       6  },
       7  methods: {
       8    commonMethod() {
       9      console.log("This is a common method");
      10    },
      11  },
      12};
      13
      14export default myMixin;
    • 在组件中使用混入:

       1<script setup>
       2import myMixin from "./path/to/mixin";
       3
       4export default {
       5  mixins: [myMixin],
       6};
       7</script>
       8
       9<template>
      10  <div>
      11    {{ commonData }}
      12    <button @click="commonMethod">Call common method</button>
      13  </div>
      14</template>
  2. 优势:

    • 代码复用:可以将一些通用的属性、方法或生命周期钩子合并到多个组件中。
    • 减少重复代码:避免在多个组件中重复编写相同的逻辑。

四、函数式组件

  1. 定义与使用:

    • 函数式组件是一个无状态、无实例的组件,它接收 props 并返回一个 VNode。例如:

       1<script setup>
       2import { h } from "vue";
       3
       4const MyFunctionalComponent = (props) => {
       5  return h("div", {}, props.message);
       6};
       7
       8export default MyFunctionalComponent;
       9</script>
    • 在其他组件中使用函数式组件:

       1<script setup>
       2import MyFunctionalComponent from "./path/to/functionalComponent";
       3</script>
       4
       5<template>
       6  <MyFunctionalComponent message="Hello from functional component" />
       7</template>
  2. 优势:

    • 轻量级:函数式组件没有实例化的开销,性能更高。
    • 简洁性:对于一些简单的展示性组件,可以使用函数式组件来简化代码。

927. [Vue] 组合式函数 和 vue2 mixins 对比, 有何优劣【热度: 311】【web 框架】

关键词:组合式函数 对比 mixins

在 Vue 3 中,组合式函数(Composables)与 Vue 2 中的混入(Mixins)相比,有以下优劣:

一、组合式函数的优势

  1. 更好的可读性和可维护性:

    • 组合式函数通常是一个独立的函数,其逻辑更加清晰,容易理解和调试。每个组合式函数专注于特定的功能,使得代码结构更加模块化。
    • 相比之下,混入可能会导致命名冲突和难以追踪的代码来源,尤其是当多个混入被应用到一个组件时。
  2. 灵活的组合和参数化:

    • 可以根据需要选择和组合不同的组合式函数,并且可以传递参数来定制它们的行为。这使得代码更加灵活,可以适应不同的场景。
    • 混入的组合相对固定,难以进行灵活的参数化。
  3. 更好的类型支持:

    • 在使用 TypeScript 时,组合式函数可以更好地利用类型系统,提供更准确的类型提示和错误检查。
    • 混入在类型支持方面相对较弱,可能会导致类型不明确的问题。
  4. 避免命名冲突:

    • 组合式函数通过命名空间或函数名来避免命名冲突,而混入可能会因为相同的属性或方法名而产生冲突。

二、混入的优势

  1. 历史兼容性:

    • 如果是从 Vue 2 迁移过来的项目,已经使用了混入,那么在一定程度上可以继续使用它们,减少迁移成本。
  2. 简单的使用方式:

    • 对于一些简单的复用场景,混入可以快速地将一些通用的属性和方法添加到组件中,使用起来相对简单。

三、组合式函数的劣势

  1. 学习曲线:

    • 对于习惯了 Vue 2 混入的开发者来说,学习和适应组合式函数可能需要一定的时间。
  2. 代码组织要求高:

    • 由于组合式函数需要更加细致的代码组织,对于一些小型项目或快速开发场景,可能会觉得相对繁琐。

四、混入的劣势

  1. 不明确的来源:

    • 当多个混入被应用到一个组件时,很难确定某个属性或方法的具体来源,这会增加代码的理解难度。
  2. 潜在的命名冲突:

    • 如前所述,混入容易产生命名冲突,尤其是在大型项目中,可能会导致难以调试的问题。
  3. 可维护性问题:

    • 随着项目的发展,混入可能会变得复杂和难以维护,特别是当需要修改或扩展它们的功能时。

929. [Vue] vue 如何配置全局使用的定义或者常量【热度: 337】【web 框架】

关键词:vue 全局配置

在 Vue 中,可以通过以下几种方式配置全局使用的定义或常量:

一、使用 Vue 原型(不推荐在 Vue 3 中使用)

在 Vue 2 中,可以通过在main.js文件中向 Vue 的原型上添加属性来实现全局定义或常量的访问。但在 Vue 3 中不推荐这种方式,因为它可能会导致一些潜在的问题。

 1// Vue 2 示例
 2Vue.prototype.$globalConstant = "This is a global constant";

二、使用 provide/inject(推荐)

  1. 在根组件中提供全局定义或常量:

     1import { createApp } from "vue";
     2
     3const app = createApp({
     4  setup() {
     5    return {
     6      globalValue: "Global value",
     7    };
     8  },
     9  provide() {
    10    return {
    11      global: this.globalValue,
    12    };
    13  },
    14});
    15
    16app.mount("#app");
  2. 在子组件中注入并使用:

     1<script setup>
     2import { inject } from "vue";
     3
     4const global = inject("global");
     5</script>
     6
     7<template>
     8  <div>{{ global }}</div>
     9</template>

三、创建全局变量文件并导入

  1. 创建一个专门的文件用于存储全局定义或常量,例如globals.js

     1export const globalConstant = "This is a global constant";
  2. 在需要使用的地方导入:

     1import { globalConstant } from "./globals.js";

四、使用 Vuex(状态管理)

如果你的全局定义或常量需要在多个组件之间共享并且可能会发生变化,可以考虑使用 Vuex 进行状态管理。

  1. 安装和设置 Vuex:

    创建一个store.js文件:

     1import { createStore } from "vuex";
     2
     3const store = createStore({
     4  state: {
     5    globalValue: "Global value from Vuex",
     6  },
     7  mutations: {},
     8  actions: {},
     9  modules: {},
    10});
    11
    12export default store;
  2. main.js中引入并挂载 Vuex:

     1import { createApp } from "vue";
     2import App from "./App.vue";
     3import store from "./store";
     4
     5const app = createApp(App);
     6app.use(store);
     7app.mount("#app");
  3. 在组件中使用:

     1<script setup>
     2import { useStore } from "vuex";
     3
     4const store = useStore();
     5</script>
     6
     7<template>
     8  <div>{{ store.state.globalValue }}</div>
     9</template>

931. [Vue] 实现一个简单的 i18n (国际化 (Internationalization) 的缩写) 插件【热度: 166】【web 框架】

关键词:vue i18n 插件实现

作者备注

这个是一个简单的官方案例, 如果阅读过官方文档, 就没有任何难点。 所以暂定为「中级」

实现下面的这样的一个插件 <h1>{{ $translate('greetings.hello') }}</h1>

以下是一个简单的 Vue 3 的国际化插件实现:

  1. 创建一个名为i18nPlugin.js的文件:
 1const i18nPlugin = {
 2  install(app, options) {
 3    const translations = options.translations;
 4    app.config.globalProperties.$translate = (key) => {
 5      const parts = key.split(".");
 6      let value = translations[parts[0]];
 7      for (let i = 1; i < parts.length && value; i++) {
 8        value = value[parts[i]];
 9      }
10      return value || key;
11    };
12  },
13};
14
15export default i18nPlugin;
  1. 在你的 Vue 3 项目中使用这个插件:

假设你有以下的语言翻译对象:

 1// en.js
 2const enTranslations = {
 3  greetings: {
 4    hello: 'Hello!',
 5  },
 6};
 7
 8export default enTranslations;
 9
10// zh.js
11const zhTranslations = {
12  greetings: {
13    hello: '你好!',
14  },
15};
16
17export default zhTranslations;

在项目的入口文件(通常是main.jsmain.ts)中:

 1import { createApp } from "vue";
 2import App from "./App.vue";
 3import enTranslations from "./locales/en";
 4import i18nPlugin from "./i18nPlugin";
 5
 6const app = createApp(App);
 7
 8app.use(i18nPlugin, { translations: enTranslations });
 9
10app.mount("#app");

这样,在你的组件中就可以使用{{ $translate('greetings.hello') }}来获取翻译后的文本,并且可以通过修改传入插件的翻译对象来切换不同的语言。

933. [Vue] 详细介绍一下 teleport 内置组件【热度: 100】【web 框架】

关键词:teleport 内置组件

在 Vue 中,<teleport>是一个内置组件,它提供了一种将组件的模板内容渲染到指定 DOM 节点位置的方式,而不是在组件自身的位置渲染。

一、作用与优势

  1. 灵活布局:允许你将特定的组件内容放置在页面的任何位置,而不受组件层次结构的限制。这对于创建模态框、通知、工具提示等需要在特定位置显示的元素非常有用。
  2. 分离关注点:可以将与特定功能相关的模板内容从组件的逻辑中分离出来,并将其渲染到合适的位置。这样可以使组件的代码更加清晰和易于维护。
  3. 性能优化:在某些情况下,将某些内容渲染到远离其他组件的位置可以减少不必要的重绘和回流,提高性能。

二、使用方法

  1. 基本用法:

     1<template>
     2  <div>
     3    <teleport to="body">
     4      <div class="modal">This is a modal content.</div>
     5    </teleport>
     6  </div>
     7</template>
     8
     9<style>
    10.modal {
    11  position: fixed;
    12  top: 50%;
    13  left: 50%;
    14  transform: translate(-50%, -50%);
    15  background-color: white;
    16  padding: 20px;
    17  border: 1px solid #ccc;
    18}
    19</style>

    在这个例子中,<teleport>组件将包含模态框内容的<div>渲染到了<body>元素中,使其在页面上居中显示。

  2. 指定目标选择器: 可以使用任何有效的 CSS 选择器作为to属性的值来指定目标位置。例如:

     1<template>
     2  <div>
     3    <teleport to="#my-target-element">
     4      <div class="notification">This is a notification.</div>
     5    </teleport>
     6  </div>
     7</template>

    这里将通知内容渲染到具有idmy-target-element的元素中。

  3. 动态目标: 可以使用响应式数据来动态地确定<teleport>的目标位置。例如:

     1<template>
     2  <div>
     3    <input v-model="targetElementId" />
     4    <teleport :to="targetElementId">
     5      <div class="dynamic-content">This content will be teleported to the specified element.</div>
     6    </teleport>
     7  </div>
     8</template>
     9
    10<script setup>
    11import { ref } from "vue";
    12
    13const targetElementId = ref("body");
    14</script>

    在这个例子中,用户可以通过输入框输入目标元素的id,从而动态地确定<teleport>的目标位置。

三、注意事项

  1. 事件冒泡:当在<teleport>内部的元素上触发事件时,事件会按照正常的 DOM 事件冒泡机制传播到目标位置的父元素中。如果需要处理这些事件,确保在目标位置的父元素中正确地监听和处理这些事件。
  2. 样式隔离:如果<teleport>内部的内容需要特定的样式,确保这些样式不会影响到目标位置的其他元素。可以使用 CSS 模块化、命名空间或特定的选择器来确保样式的隔离。
  3. 响应式数据:如果在<teleport>内部使用了响应式数据,确保这些数据在目标位置的上下文中也能正确地更新。可以使用 Vue 的响应式系统来确保数据的一致性。

934. [Vue] 介绍一下 component 动态组件【热度: 184】【web 框架】

关键词:component 动态组件

在 Vue 中,动态组件是一种强大的特性,可以根据不同的条件在运行时动态地切换组件的显示。

一、基本概念

动态组件使用特殊的<component>标签结合is属性来实现。is属性可以接受一个字符串或变量,用于指定要渲染的组件名称或组件选项对象。Vue 会根据is属性的值来动态地加载和渲染相应的组件。

二、使用方法

  1. 使用字符串指定组件名称

    • 可以直接在is属性中使用字符串来指定组件的名称。例如:
     1<template>
     2  <div>
     3    <component :is="currentComponent"></component>
     4  </div>
     5</template>
     6<script setup>
     7  import ComponentA from "./ComponentA.vue";
     8  import ComponentB from "./ComponentB.vue";
     9  let currentComponent = "ComponentA";
    10</script>
    • 在这个例子中,根据currentComponent变量的值,<component>标签会动态地渲染ComponentAComponentB组件。
  2. 使用变量指定组件选项对象

    • 也可以使用变量来指定一个组件选项对象。例如:
     1<template>
     2  <div>
     3    <component :is="currentComponent"></component>
     4  </div>
     5</template>
     6<script setup>
     7  import ComponentA from "./ComponentA.vue";
     8  import ComponentB from "./ComponentB.vue";
     9  let currentComponent = ComponentA;
    10</script>
    • 这里,currentComponent变量可以在运行时被赋值为ComponentAComponentB的组件选项对象,从而实现动态切换组件。
  3. 结合v-ifv-show控制组件显示

    • 可以结合v-ifv-show指令来控制动态组件的显示条件。例如:
     1<template>
     2  <div>
     3    <component :is="currentComponent" v-if="showComponent"></component>
     4  </div>
     5</template>
     6<script setup>
     7  import ComponentA from "./ComponentA.vue";
     8  import ComponentB from "./ComponentB.vue";
     9  let currentComponent = "ComponentA";
    10  let showComponent = true;
    11</script>
    • 在这个例子中,只有当showComponenttrue时,动态组件才会被渲染。

三、优势和应用场景

  1. 优势

    • 灵活性:可以根据不同的业务逻辑和用户交互动态地切换组件,提高应用的灵活性和可维护性。
    • 代码复用:可以在多个地方使用相同的动态组件机制,减少重复代码。
    • 性能优化:只在需要的时候加载和渲染特定的组件,可以提高应用的性能。
  2. 应用场景

    • 页面布局切换:根据用户的操作或应用的状态,动态地切换不同的页面布局组件。例如,在一个管理系统中,根据用户的角色显示不同的菜单栏和功能区域。
    • 内容展示切换:根据数据的类型或状态,动态地展示不同的内容组件。例如,在一个新闻应用中,根据新闻的类型显示不同的新闻详情组件。
    • 步骤向导:在一个多步骤的向导流程中,使用动态组件来逐步展示不同的步骤组件。用户可以根据向导的进度动态地切换到不同的步骤,提高用户体验。
个人笔记记录 2021 ~ 2025