当前位置: 首页 > article >正文

Vue进阶面试题目(四)

1. 什么是双向绑定? Vue 双向绑定的原理是什么?

双向绑定是一种数据绑定机制,指的是视图和数据之间可以相互同步。即,当模型数据(Model)发生变化时,视图(View)会自动更新;反之,视图变化时,模型数据也会更新。

Vue 双向绑定的原理依赖于 Object.defineProperty(Vue2)或 Proxy(Vue3)的响应式原理:

  • Vue2:通过 Object.defineProperty 监听对象属性的 getter 和 setter,实现数据劫持,并结合模板编译更新视图。
  • Vue3:通过 Proxy 创建响应式代理,监听整个对象的操作(如属性读取、设置、新增、删除),从而更灵活高效地更新视图。

2. 如何使用 Vue 开发多语言项目?

使用 Vue 开发多语言项目时,可以借助 vue-i18n 插件。主要步骤如下:

  1. 安装依赖:
    npm install vue-i18n
    
  2. 配置多语言文件,例如 en.jsonzh.json
  3. 初始化 i18n 实例并挂载:
    import { createApp } from 'vue';
    import { createI18n } from 'vue-i18n';
    import App from './App.vue';
    
    const messages = {
      en: { hello: 'Hello' },
      zh: { hello: '你好' },
    };
    
    const i18n = createI18n({
      locale: 'en', // 默认语言
      messages,
    });
    
    const app = createApp(App);
    app.use(i18n);
    app.mount('#app');
    
  4. 在模板中使用 $t 来实现多语言:
    <template>
      <p>{{ $t('hello') }}</p>
    </template>
    

3. Vue 中什么是递归组件? 请举例说明

递归组件是指组件自身调用自身,常用于处理嵌套结构(如树形菜单、文件夹结构)。

示例:文件夹结构

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
      <folder v-if="item.children" :items="item.children" />
    </li>
  </ul>
</template>

<script>
export default {
  name: 'Folder',
  props: ['items'],
};
</script>

4. Vue 的 data 中如果有数组,如何检测数组的变化?

在 Vue2 中,数组的响应式存在一些限制。Vue2 修改数组时需要使用以下方法触发视图更新:

  • push(), pop(), shift(), unshift(), splice(), sort(), reverse() 等。

注意:直接通过索引修改数组或使用 length 属性时,不会自动触发更新:

this.arr[0] = 'newValue'; // 不会触发更新
this.arr.length = 2; // 不会触发更新

解决方法:

  • 使用 Vue.set()
    Vue.set(this.arr, 0, 'newValue');
    

在 Vue3 中,通过 Proxy 的响应式机制,数组的索引和长度变化都能被正确检测。

5. Vue3 中的 Suspense 组件有什么作用? 如何使用它来处理异步组件?

Suspense 是 Vue3 提供的一个内置组件,用于处理异步组件加载,并显示加载状态或备用内容。

使用示例

<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <p>Loading...</p>
    </template>
  </Suspense>
</template>

<script>
import { defineAsyncComponent } from 'vue';

const AsyncComponent = defineAsyncComponent(() =>
  import('./AsyncComponent.vue')
);

export default {
  components: { AsyncComponent },
};
</script>

作用

  • 显示异步组件加载时的备用内容(fallback 插槽)。
  • 等待异步组件加载完成后再渲染。

6. Vue 3 中的 Vue Composition API 是什么?

Composition API 是 Vue3 提供的一种新的代码组织方式,增强了逻辑复用和代码清晰度。核心方法包括 setuprefreactive 等。

示例

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

<script>
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);

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

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

7. Vue 中子组件可以直接修改父组件的数据吗?

不可以。子组件不能直接修改父组件的数据,应该通过 事件传递props + emit 机制实现:

  • 父组件通过 props 将数据传递给子组件。
  • 子组件通过 $emit 触发事件通知父组件更新数据。

8. Vue 中 style 的 scoped 属性有什么用? 它的实现原理是什么?

scoped 属性用于使样式只作用于当前组件,避免污染全局样式。

实现原理

  • Vue 为 scoped 样式的元素添加一个唯一的属性(如 data-v-xxx)。
  • 编译时,将样式选择器加上该属性,确保样式作用域限定在组件内。

示例

<template>
  <div class="example">Hello</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

9. Vuex 状态管理存在什么缺点?

  • 复杂性增加:项目较小时,引入 Vuex 会显得过于繁重。
  • 调试困难:需要配合工具(如 Vue DevTools)调试。
  • 模块间耦合性:模块较多时,可能导致数据和逻辑交叉。

10. 你在 Vue 项目中如何发送请求? ajax、fetch、axios 之间有什么区别?

发送请求:常用 axios,因为其功能强大、支持拦截器、兼容性好。

  • ajax:基于 XMLHttpRequest,过于底层,不推荐。
  • fetch:浏览器自带 API,支持 Promise,但不支持拦截器,需手动处理错误和超时。
  • axios:基于 Promise,封装了 XMLHttpRequest,提供了更好的功能和更简洁的 API。

11. Vue 中怎么改变插入模板的分隔符?

通过 delimiters 配置:

const app = new Vue({
  el: '#app',
  delimiters: ['${', '}'],
});

12. Vue 中有哪些边界情况需要注意?

  • 组件销毁时未清除定时器或事件监听器。
  • 动态组件切换导致状态丢失。
  • 大量 DOM 操作导致性能问题。
  • 深层嵌套的响应式数据可能导致性能问题。

13. 虚拟 DOM 和 DIFF 算法的关系,其中 key 的作用是什么?

虚拟 DOM 是一种用 JavaScript 对 DOM 结构进行抽象的表示,便于高效更新视图。
DIFF 算法 用于比较新旧虚拟 DOM 树,计算最小更新操作。

key 的作用

  • 唯一标识节点,帮助 DIFF 算法精准复用和更新 DOM 节点。
  • 避免不必要的 DOM 重建。

14. 什么是事件总线 EventBus? 怎么在 Vue 项目中使用它?

事件总线是一个空的 Vue 实例,用于组件之间的事件通信。

使用方法

  1. 创建 EventBus:
    const EventBus = new Vue();
    export default EventBus;
    
  2. 组件中使用:
    // 子组件 A 触发事件
    EventBus.$emit('eventName', data);
    
    // 子组件 B 监听事件
    EventBus.$on('eventName', (data) => {
      console.log(data);
    });
    

    1. Vue 项目部署到服务器后,报 404 错误的原因是什么?

主要原因是 Vue Router 的 history 模式在部署时没有正确配置服务端。
在 history 模式下,URL 直接指向某个路由路径,而不是实际的文件路径,因此刷新时,服务器会尝试查找对应路径的文件,找不到时返回 404。

解决方法

  • 确保服务端将所有路由都指向 index.html
    • Apache:
      <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
      </IfModule>
      
    • Nginx:
      location / {
        try_files $uri $uri/ /index.html;
      }
      

2. 什么是 Vuex? 为什么需要它? 它有哪些优点和适用场景?

Vuex 是 Vue 的状态管理库,用于集中式管理应用中的共享状态。

为什么需要 Vuex

  • 解决多组件共享状态的问题。
  • 提供单向数据流,便于调试和维护。

优点

  • 状态集中管理,便于追踪和调试。
  • 提供模块化管理,适合大型项目。
  • 支持 Vue DevTools,调试方便。

适用场景

  • 大型复杂项目,组件间状态共享频繁。
  • 需要对状态进行集中管理和严格约束的应用。

3. 如何在组件中重复使用 Vuex 的 mutation?

可以通过 mapMutations 辅助函数绑定 Vuex 的 mutations:

import { mapMutations } from 'vuex';

export default {
  methods: {
    ...mapMutations(['mutationA', 'mutationB']),
    customMethod() {
      this.mutationA('payload');
    },
  },
};

4. 如何解决 SPA 单页应用首屏加载速度慢的问题?

  • 代码分割
    使用 dynamic import 和 Webpack 的 lazy-loading,按需加载组件:

    const AsyncComponent = () => import('./components/Component.vue');
    
  • 服务端渲染(SSR)
    使用 Vue SSR 提供服务端渲染,减少首屏加载时间。

  • 骨架屏
    在加载真实内容前显示骨架屏以优化用户体验。

  • 资源优化

    • 压缩 JS、CSS 和图片资源。
    • 使用 CDN 加速静态资源加载。
    • 开启 HTTP/2。
  • 缓存
    使用浏览器缓存或 Service Worker 缓存静态资源。

5. Vue Router 的导航守卫有哪些? 它们接受哪些参数?

Vue Router 提供三种导航守卫:

  1. 全局守卫

    • beforeEach:在每次导航前触发。
    • beforeResolve:在所有组件内守卫和异步路由完成后触发。
    • afterEach:导航完成后触发。
  2. 路由独享守卫
    定义在路由配置中的 beforeEnter

  3. 组件内守卫

    • beforeRouteEnter:进入路由前触发。
    • beforeRouteUpdate:当前路由改变时触发。
    • beforeRouteLeave:离开当前路由前触发。

参数

  • to:目标路由对象。
  • from:当前路由对象。
  • next:用于控制导航流程的回调函数。

6. 请求数据的逻辑应该写在 Vue 组件的 methods 中还是 Vuex 的 actions 中?

  • 小型项目:请求逻辑可以写在组件的 methods 中。
  • 大型项目:推荐将请求逻辑写在 Vuex 的 actions 中,便于管理和复用。

7. Vuex 和 localStorage 的区别是什么?

  • Vuex:在内存中管理状态,适合频繁更新、跨组件共享的数据。
  • localStorage:持久化存储,数据存储在浏览器本地,不会随页面刷新丢失。

使用场景

  • Vuex:实时更新数据,如用户会话信息。
  • localStorage:持久存储,如用户设置、令牌。

结合使用:可以在 Vuex 的状态中使用 localStorage 持久化部分数据。

8. Vuex 的实现原理是什么?

Vuex 的核心原理是基于 Vue 的响应式机制和发布-订阅模式:

  1. 响应式:通过 Vue 的 reactivedata 实现对状态的响应式绑定。
  2. 发布-订阅
    • 组件订阅 Store 的状态。
    • Actions 或 Mutations 修改状态后,触发订阅的组件更新。

9. Element UI 组件库是怎么做表单验证的? 怎么在循环中对每个 input 进行验证?

验证原理

  • 通过 el-form 组件结合 async-validator 库,定义验证规则。

示例

<el-form :model="form" :rules="rules" ref="formRef">
  <el-form-item label="Name" prop="name">
    <el-input v-model="form.name" />
  </el-form-item>
</el-form>

<script>
export default {
  data() {
    return {
      form: { name: '' },
      rules: { name: [{ required: true, message: 'Name is required', trigger: 'blur' }] },
    };
  },
};
</script>

循环验证
通过 :prop 动态绑定每个字段:

<el-form :model="form" :rules="rules" ref="formRef">
  <el-form-item v-for="(item, index) in form.items" :prop="'items.' + index + '.name'" :key="index">
    <el-input v-model="item.name" />
  </el-form-item>
</el-form>

10. 什么是 Vue 的高阶组件? 请举例说明

高阶组件(HOC)是复用组件逻辑的一种模式,本质是返回一个增强的组件。

示例

function withLogger(WrappedComponent) {
  return {
    mounted() {
      console.log(`${WrappedComponent.name} mounted`);
    },
    render(h) {
      return h(WrappedComponent, { props: this.$props });
    },
  };
}

// 使用 HOC
const EnhancedComponent = withLogger(MyComponent);

11. Vue 中如何实现强制刷新组件?

可以通过修改组件的 key 属性实现:

<template>
  <MyComponent :key="key" />
  <button @click="refresh">Refresh</button>
</template>

<script>
export default {
  data() {
    return { key: 0 };
  },
  methods: {
    refresh() {
      this.key++;
    },
  },
};
</script>

12. Vue Router 的 history 模式为什么刷新时会出现 404 错误?

原因
在 history 模式下,路由的 URL 不包含 #,刷新时,服务器会将 URL 当作文件路径处理,而对应的文件可能并不存在,因此报 404。

解决方法
在服务器端配置所有路径指向 index.html(见问题 1)。

1. Vue、React 和 Angular 有什么区别? 各自的优缺点和使用场景是什么?

Vue.js
  • 特点:轻量级、渐进式框架,关注视图层,易上手。
  • 优点
    • 简单易学,文档完善,适合快速开发。
    • 双向数据绑定,开发效率高。
    • 生态丰富(Vue Router、Vuex)。
  • 缺点
    • 社区主导,相较于 React 的大厂支持,稳定性稍弱。
    • 灵活性高,可能导致项目规范不统一。
  • 使用场景
    • 中小型项目,关注开发效率。
    • 注重用户交互的前端项目。
React
  • 特点:以组件为中心,功能强大,采用虚拟 DOM 和单向数据流。
  • 优点
    • 灵活性高,适用于各种场景。
    • 背靠 Facebook 社区,更新稳定。
    • 丰富的第三方库和生态。
  • 缺点
    • 需要搭配 Redux/MobX 等工具,学习成本高。
    • 灵活性可能带来复杂的代码管理。
  • 使用场景
    • 复杂的 Web 应用(如电商、社交平台)。
    • 高性能要求的项目。
Angular
  • 特点:全功能框架,提供完整的解决方案。
  • 优点
    • 企业级应用支持强大,提供完整的开发工具链。
    • 双向数据绑定,集成性强。
    • 强大的 TypeScript 支持。
  • 缺点
    • 学习曲线陡峭。
    • 项目体积较大。
  • 使用场景
    • 企业级应用,大型项目。
    • 需要长期维护的复杂系统。

2. Element UI 是什么? 你如何在 Vue 项目中集成 Element UI?

Element UI 是基于 Vue 的 UI 组件库,提供了一系列高质量的组件(如表单、表格、对话框)以提高开发效率。

集成步骤

  1. 安装依赖:
    npm install element-ui
    
  2. 全局引入:
    import Vue from 'vue';
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    
    Vue.use(ElementUI);
    
  3. 按需引入(推荐):
    安装 babel-plugin-component,优化打包大小:
    npm install babel-plugin-component -D
    
    修改 Babel 配置:
    module.exports = {
      plugins: [
        [
          'component',
          {
            libraryName: 'element-ui',
            styleLibraryName: 'theme-chalk',
          },
        ],
      ],
    };
    
    在代码中按需导入:
    import { Button, Select } from 'element-ui';
    Vue.use(Button);
    Vue.use(Select);
    

3. 是否阅读过 Vue Router 的源码? 有哪些优秀的设计?

阅读过 Vue Router 的部分源码,以下是一些优秀设计:

  • 动态路由匹配
    通过路径参数、正则匹配解析路由地址。
  • 导航守卫机制
    利用 Promise 链式调用依次执行 beforeEachbeforeResolve、组件内守卫等。
  • 路由懒加载
    动态加载组件结合 Webpack 的 import(),优化性能。
  • 抽象路由层
    支持多种路由模式(hashhistoryabstract),通过适配器模式实现统一接口。
  • 路由缓存
    结合 Vue 的 keep-alive 提高页面切换性能。

4. Vue 的基本实现原理是什么?

Vue 的核心原理是 数据驱动视图更新响应式机制,主要包括以下部分:

  1. 响应式系统
    • Vue2 使用 Object.defineProperty 劫持对象属性,创建 getter 和 setter。
    • Vue3 使用 Proxy,拦截对象的所有操作。
  2. 模板编译
    • 将模板字符串解析为抽象语法树(AST)。
    • 转化为渲染函数(render)。
  3. 虚拟 DOM
    • 渲染函数生成虚拟 DOM。
    • 比较新旧虚拟 DOM 的差异(Diff 算法),进行最小化更新。
  4. 组件化
    • 通过递归和组合,实现组件嵌套和复用。

5. 你是否阅读过 Vue 组件库(如 Element UI)的源码? 有哪些巧妙的设计?

Element UI 的设计亮点:

  • 动态插槽机制
    利用 Vue 的 slot 动态生成不同内容,提升灵活性。
  • 全局组件注册
    自动注册所有组件,方便全局使用。
  • 指令封装
    使用自定义指令(如 v-loading)实现功能复用。
  • 样式隔离
    通过 BEM 规范和 SCSS 实现组件的样式模块化,避免冲突。
  • 表单验证
    结合 async-validator 库提供灵活的验证机制。

6. 怎么让 Vue 项目支持使用 TypeScript?

  1. 安装依赖:
    vue add typescript
    
  2. 配置项目:
    • 生成 tsconfig.json
    • .js 文件改为 .ts
    • 使用 Vue SFC 的 <script lang="ts">
  3. 使用类型声明:
    • 定义组件 propsstate 类型。
    • 使用 interfacetype 定义数据结构。
    import { defineComponent } from 'vue';
    
    export default defineComponent({
      props: {
        name: String,
      },
      setup(props) {
        const message: string = `Hello, ${props.name}`;
        return { message };
      },
    });
    

7. Vue 模板到渲染的过程是什么?

  1. 模板解析
    • 将模板编译为 AST(抽象语法树)。
  2. 优化
    • 标记静态节点,避免不必要的更新。
  3. 生成渲染函数
    • 将 AST 转化为 render 函数。
  4. 渲染
    • 调用 render 函数生成虚拟 DOM。
  5. Diff
    • 比较新旧虚拟 DOM 的差异,更新真实 DOM。

8. 如何使用 Vue 编写一个 Tab 切换组件? 请介绍设计思路

思路

  1. 数据驱动
    使用父组件传递标签数据,控制选中状态。
  2. 插槽支持
    提供默认插槽,让用户自定义内容。
  3. 事件通信
    子组件通过事件通知父组件切换标签。

示例代码

<!-- TabContainer.vue -->
<template>
  <div>
    <div class="tab-headers">
      <button
        v-for="(tab, index) in tabs"
        :key="index"
        @click="selectTab(index)"
        :class="{ active: index === activeIndex }"
      >
        {{ tab.label }}
      </button>
    </div>
    <div class="tab-content">
      <slot :active-index="activeIndex"></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: ['tabs'],
  data() {
    return { activeIndex: 0 };
  },
  methods: {
    selectTab(index) {
      this.activeIndex = index;
    },
  },
};
</script>

<!-- 使用 -->
<template>
  <TabContainer :tabs="tabList">
    <template v-slot="{ activeIndex }">
      <div v-for="(tab, index) in tabList" :key="index" v-show="index === activeIndex">
        {{ tab.content }}
      </div>
    </template>
  </TabContainer>
</template>

<script>
import TabContainer from './TabContainer.vue';

export default {
  components: { TabContainer },
  data() {
    return {
      tabList: [
        { label: 'Tab 1', content: 'Content 1' },
        { label: 'Tab 2', content: 'Content 2' },
      ],
    };
  },
};
</script>

1. Vue 如何优化网站首页的加载速度?

  1. 代码分割和懒加载
    • 使用动态导入按需加载组件:
      const Home = () => import('./components/Home.vue');
      
  2. 使用骨架屏
    • 在主内容加载前显示骨架屏,提升用户体验。
  3. 预渲染或服务端渲染(SSR)
    • 使用插件如 vue-meta 或框架如 Nuxt.js 进行 SEO 优化和首屏渲染。
  4. 压缩和优化资源
    • 压缩 CSS、JS 文件。
    • 使用现代图片格式(如 WebP)。
  5. 使用 CDN
    • 将静态资源(如 JS 框架、图片)部署到 CDN 上,加快加载速度。
  6. HTTP/2 和缓存
    • 开启 HTTP/2 以并行加载资源。
    • 利用浏览器缓存或 Service Worker 缓存静态文件。

2. 如何修改 Vue 打包后生成文件的路径?

vue.config.js 中配置 publicPathoutputDir

module.exports = {
  publicPath: './', // 设置资源路径相对路径
  outputDir: 'dist', // 修改打包输出文件夹
};

3. 说说你了解哪些 Vue 组件设计原则?

  1. 单一职责
    • 一个组件只负责一项功能,避免过于复杂。
  2. 高内聚低耦合
    • 组件之间通过 props 和事件通信,避免直接依赖。
  3. 数据驱动
    • 用数据驱动 UI,而不是直接操作 DOM。
  4. 插槽设计
    • 使用 slot 提供扩展点,增加组件的灵活性。
  5. 状态管理
    • 只在必要的地方管理状态,避免不必要的状态提升。
  6. 可复用性
    • 提取通用逻辑,利用混入(Vue2)或组合式 API(Vue3)增强复用性。
  7. 性能优化
    • 避免不必要的重渲染,合理使用 v-showkeep-alive 等。

4. 什么是 Vue 的 Object.defineProperty?

Vue2 的响应式系统基于 Object.defineProperty,通过拦截对象属性的 gettersetter 实现响应式。

  • 实现方式

    • 拦截属性读取,收集依赖:
      get: function() {
        // 收集依赖
      }
      
    • 拦截属性更新,通知依赖:
      set: function(newVal) {
        // 通知依赖更新
      }
      
  • 局限性

    • 不能检测对象新增/删除属性。
    • 对数组的 push 等操作无法直接拦截。

5. Vue 中给 data 的对象添加新属性时会发生什么? 如何解决?

问题:Vue 无法监听新添加的属性,因为 Object.defineProperty 在初始化时定义了响应式属性。

解决方法

  1. 使用 Vue.set
    Vue.set(obj, 'newProp', value);
    
  2. 使用 Vue3 的响应式 Proxy(无此问题)。

6. Vue 首页白屏可能是什么问题引起的? 如何解决?

可能原因

  1. 资源路径错误
    • 打包后的文件未正确加载,publicPath 配置错误。
  2. 异步加载失败
    • 异步组件加载时网络延迟或失败。
  3. JS/CSS 压缩问题
    • 压缩不当导致代码不可运行。
  4. 浏览器兼容性问题
    • 低版本浏览器不支持 ES6。

解决方法

  • 确保 publicPath 配置正确。
  • 使用 Polyfill 增强兼容性。
  • 通过骨架屏优化用户体验。
  • 使用浏览器开发工具检查资源加载情况。

7. 如何解决 Vue 动态设置 img 的 src 属性不生效的问题?

原因:某些浏览器或图片资源跨域限制。

解决方法

  1. 确保路径正确。
  2. 使用完整 URL。
  3. 若跨域受限,设置服务端 Access-Control-Allow-Origin

8. 虚拟 DOM 真的比真实 DOM 的性能更好吗?

  • 场景
    • 虚拟 DOM 优势在于批量更新和跨平台能力。
    • 对于小规模静态页面,真实 DOM 性能更优。
  • 虚拟 DOM 的优势
    • 减少直接操作 DOM 的成本。
    • 通过 Diff 算法最小化真实 DOM 更新。
    • 兼容服务端渲染(SSR)。

9. 你使用过哪些 Vue 的 UI 库? 说说它们的优缺点?

  1. Element UI
    • 优点:功能齐全,设计简洁,社区成熟。
    • 缺点:组件体积较大,不适合移动端。
  2. Ant Design Vue
    • 优点:设计优雅,企业应用广泛。
    • 缺点:文档略复杂。
  3. Vuetify
    • 优点:基于 Material Design,适合移动端。
    • 缺点:学习曲线稍高。
  4. iView
    • 优点:轻量级,易用。
    • 缺点:社区支持较少。

10. 如何销毁 Vue 组件中的定时器?

在组件销毁时清除定时器:

export default {
  data() {
    return { timer: null };
  },
  mounted() {
    this.timer = setInterval(() => console.log('Tick'), 1000);
  },
  beforeDestroy() {
    clearInterval(this.timer);
  },
};

11. 如果 Vue 给组件绑定自定义事件无效,如何解决?

原因

  1. 事件未正确绑定。
  2. 组件未通过 $emit 触发事件。

解决方法

  1. 检查父组件是否正确监听:
    <ChildComponent @customEvent="handleEvent" />
    
  2. 检查子组件是否正确触发:
    this.$emit('customEvent', payload);
    

12. 什么是 JSX? Vue 中怎么使用 JSX?

JSX 是 JavaScript 的语法扩展,允许在 JS 中直接写 HTML。

Vue 中使用 JSX

  1. 安装依赖:
    npm install @vitejs/plugin-vue-jsx
    
  2. 配置 Vite:
    import vueJsx from '@vitejs/plugin-vue-jsx';
    
    export default {
      plugins: [vueJsx()],
    };
    
  3. 使用 JSX:
    export default {
      render() {
        return <div>Hello JSX!</div>;
      },
    };
    

13. Vue 中 slot 的实现原理是什么?

  1. 编译阶段

    • slot 会被解析为子组件的插槽。
    • 插槽内容存储为 VNode
  2. 运行时渲染

    • 插槽内容作为子组件的 children 传递。
    • 使用 renderSlot 渲染插槽内容:
      renderSlot(slots, 'slotName', props);
      
  3. 作用域插槽

    • 父组件通过 scopedSlots 提供数据,子组件动态接收。

    1. Vue 组件中,如果使用原生 addEventListener 监听事件,是否需要手动销毁? 为什么?

是的,需要手动销毁

  • 原因
    • Vue 会自动销毁使用 v-on 或 Vue 自身绑定的事件监听,但对于原生 addEventListener 的监听,Vue 无法追踪,需手动移除。
    • 如果不移除,可能导致内存泄漏,因为事件监听器引用了 DOM 节点,即使节点被销毁,监听器仍会占用资源。

解决方法
beforeDestroyunmounted 钩子中移除事件监听:

mounted() {
  this.listener = () => console.log('Event triggered');
  window.addEventListener('resize', this.listener);
},
beforeDestroy() {
  window.removeEventListener('resize', this.listener);
},

2. Vue 中 v-model 是如何实现的?

工作原理

v-model 是 Vue 提供的语法糖,用于实现双向数据绑定。

  1. 绑定值
    • 通过 :value 将数据绑定到表单控件的 value 属性。
  2. 监听事件
    • 添加默认的 @input 事件监听器,当用户输入时更新数据。

等价代码:

<input v-model="message" />
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value" />
自定义组件中的实现

通过 modelValueupdate:modelValue 实现:

<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

<script>
export default {
  props: ['modelValue'],
};
</script>

3. 在 Vue 项目中如何引入第三方前端库? 有哪些方法?

  1. 通过 npm 安装

    • 使用 npm 或 yarn 安装第三方库。
    • 在组件中 import
      npm install lodash
      
      import _ from 'lodash';
      
  2. 通过 CDN 引入

    • public/index.html 中直接添加 <script> 标签。
      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
      
    • 全局可用的库通过 window 对象访问。
  3. 全局引入

    • main.js 中导入:
      import axios from 'axios';
      Vue.prototype.$axios = axios; // 全局绑定
      
  4. 插件形式引入

    • 若库支持 Vue 插件模式,使用 Vue.use 注册:
      import VueToast from 'vue-toast-notification';
      Vue.use(VueToast);
      

4. 什么是 Vue 的 render 函数? 它有什么好处?

定义

render 函数是 Vue 提供的底层渲染函数,用于直接创建虚拟 DOM。

语法
render(createElement) {
  return createElement('div', { class: 'box' }, 'Hello, Render');
}
好处
  1. 动态生成模板
    • 适合需要动态构建模板的场景。
  2. 增强灵活性
    • 支持复杂逻辑,超越模板语言的限制。
  3. 用于 JSX 支持
    • 搭配 JSX 提供更清晰的组件语法。

5. 你了解过哪些 Vue 开发规范?

  1. 文件组织

    • 使用单文件组件(SFC),按功能模块划分文件夹。
    • 文件命名使用 PascalCase(组件)或 kebab-case(视图)。
  2. 组件设计

    • 组件名称使用多单词(避免与 HTML 标签冲突)。
    • 遵循单一职责,提取复用组件。
  3. 代码风格

    • 变量命名使用 camelCase。
    • 模板逻辑保持简单,复杂逻辑移至脚本部分。
  4. Props 和事件

    • props 必须声明类型和默认值。
    • 事件命名使用 kebab-case。
  5. 数据管理

    • 使用 Vuex 管理全局状态。
    • 本地数据使用 data 定义。
  6. 性能优化

    • 合理使用 v-showv-if
    • 避免深度递归绑定。

6. Vue 怎么与原生 App 进行交互? 有哪些方法?

  1. 通过 WebView 与 App 通信

    • App 调用 Vue 方法
      在 WebView 中注入 JavaScript 方法:
      window.nativeCall = function(data) {
        console.log('App called with data:', data);
      };
      
    • Vue 调用 App 方法
      使用 window.location 调用特定协议:
      window.location.href = 'myapp://openCamera';
      
  2. 使用 JSBridge

    • 建立 Vue 和原生代码之间的桥梁。
    • 示例:
      window.JSBridge.callHandler('methodName', params, (response) => {
        console.log(response);
      });
      
  3. 使用 PostMessage

    • Vue 中向 App 发送消息:
      window.postMessage({ type: 'openCamera' });
      
    • App 接收并返回数据。
  4. NativeScript-Vue

    • 使用 NativeScript 框架直接构建原生应用。

7. Vue Router 完整的导航解析过程是怎样的?

  1. 导航触发

    • 用户点击链接或调用 router.push
  2. 解析路由配置

    • 匹配目标路由及其嵌套结构。
  3. 触发全局守卫

    • 调用 beforeEach
      router.beforeEach((to, from, next) => {
        // 全局逻辑
        next();
      });
      
  4. 解析组件内守卫

    • 调用目标组件的 beforeRouteEnterbeforeRouteUpdate
  5. 触发全局后置守卫

    • 调用 afterEach,但不阻塞导航。
  6. 渲染视图

    • 根据路由匹配结果加载对应组件,更新页面。

简要示例

router.beforeEach((to, from, next) => {
  // 验证权限
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next('/login');
  } else {
    next();
  }
});

http://www.kler.cn/a/411546.html

相关文章:

  • 数据结构 (6)栈的应用举例
  • 自动化的内存管理技术之垃圾回收机制-JavaScript引用数据内存回收机制
  • Android 11 三方应用监听关机广播ACTION_SHUTDOWN
  • GCP Dataproc有什么特点,有什么最佳实践
  • jmeter基础06_(练习)常见的http请求
  • OEM sql monitoring 类似SQL
  • 【设计模式】【创建型模式(Creational Patterns)】之原型模式(Prototype Pattern)
  • 25A物联网微型断路器 智慧空开1P 2P 3P 4P-安科瑞黄安南
  • C# 泛型 学习理解记录
  • vue3+ts 我写了一个跟swagger.yml生成请求和响应实体(接口)
  • 电商平台数据获取:解锁商业洞察的多元渠道
  • #Verilog HDL# Verilog中的UDP原语
  • 2024算法基础公选课练习五(DFS2)
  • 前端---CSS(部分用法)
  • C++的中的继承
  • 计算机操作系统——进程控制(Linux)
  • 第八篇:CamX RawHdr Feature Enable
  • org.apache.log4j的日志记录级别和基础使用Demo
  • 【kafka01】消息队列与微服务之Kafka详解
  • 数据库(总结自小林coding)|索引失效的场景、慢查询、原因及如何优化?undo log、redo log、binlog 作用、MySQL和Redis的区别
  • 阿里云私服地址
  • SpringBoot(四十)SpringBoot集成RabbitMQ使用过期时间+死信队列实现延迟队列
  • 林业产品推荐系统:Spring Boot架构设计
  • K8s的水平自动扩容和缩容HPA
  • C#中面试的常见问题006
  • 使用mingw+CMake在Windows平台编译OpenCV