本文深入讲解了Vue3的核心概念和特性,包括响应式系统、模板语法、指令和事件处理等。此外,文章还提供了Vue3大厂面试真题的解析和实战演练,帮助读者更好地理解和掌握Vue3的高级用法。
Vue.js 是一个渐进式的 JavaScript 框架,它可以帮助我们构建高效、可维护的前端应用。Vue3 是 Vue.js 的最新版本,引入了许多新的特性和改进。以下是 Vue3 中的一些核心概念。
Vue3 的响应式系统通过 Proxy 对象实现,相比 Vue2 中的 Object.defineProperty 方式,具有更好的性能和更强大的功能。
在 Vue3 中,我们可以使用 ref
或 reactive
来声明响应式数据。
import { ref } from 'vue'; const count = ref(0); console.log(count.value); // 0 count.value++; console.log(count.value); // 1 import { reactive } from 'vue'; const state = reactive({ message: 'Hello, Vue3!', count: 0 }); console.log(state.count); // 0 state.count++; console.log(state.count); // 1
Vue3 支持基于 HTML 的模板语法,可以让你以声明式的方式将 DOM 绑定到 Vue 实例的数据。这对于快速构建用户界面非常有用。
<template> <div> <h1>{{ message }}</h1> <p>{{ count }}</p> </div> </template> <script> import { ref, reactive } from 'vue'; export default { setup() { const message = ref('Hello, Vue3!'); const state = reactive({ count: 0 }); return { message, state }; } } </script>
Vue 指令是带有 v-
前缀的特殊属性,它们用于定义 DOM 的行为。
<template> <div> <p v-if="show">Welcome!</p> <p v-else>Goodbye!</p> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const show = ref(true); return { show }; } } </script>
Vue3 中的事件处理使用 v-on
指令来绑定事件处理函数。
<template> <button v-on: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>
插值可以用于在模板中显示数据。计算属性则用于处理需要复杂逻辑的数据。
<template> <div> <p>原始数据: {{ rawMessage }}</p> <p>反转后的数据: {{ reversedMessage }}</p> </div> </template> <script> import { ref, computed } from 'vue'; export default { setup() { const rawMessage = ref('Hello Vue3'); const reversedMessage = computed(() => { return rawMessage.value.split('').reverse().join(''); }); return { rawMessage, reversedMessage }; } } </script>
Vue3 引入了许多新特性和改进,以下是其中的一些:
Composition API 是 Vue3 中引入的一个新 API,它为逻辑复用和代码组织提供了一种更强大的方法。
import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++; }; const doubleCount = computed(() => { return count.value * 2; }); return { count, increment, doubleCount }; } }
Teleport 是一个 Vue3 的内置组件,它允许你在 DOM 中将一个节点移动到另一个位置。
<template> <teleport to="body"> <div>这是一个被移动的元素</div> </teleport> </template>
Vue3 支持 Fragments,即一个组件可以返回多个根节点。
<template> <div> <p>我是第一个段落</p> <p>我是第二个段落</p> </div> </template>
Vue3 还引入了其他特性,如更好的 TypeScript 支持、更好的性能、更小的包体积等。这些特性使得 Vue3 成为了构建现代 Web 应用的理想选择。
Vue3 中的组件可以使用 Composition API 或 Options API 创建。这里我们主要介绍 Composition API 和 Options API 的使用。
<template> <div> <h1>欢迎来到我的应用</h1> <p>{{ message }}</p> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const message = ref('这是一个 Vue3 组件'); return { message }; } } </script>
<template> <div> <h1>欢迎来到我的应用</h1> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: '这是一个 Vue3 组件' }; } } </script>
<template> <app-welcome /> </template> <script> import AppWelcome from './components/AppWelcome.vue'; export default { components: { AppWelcome } } </script>
在 Vue3 中,可以使用插槽(slot)来实现内容分发和通信。
<template> <base-layout> <h1 slot="header">我的应用</h1> <p slot="content">这是一个插槽插值</p> </base-layout> </template> <script> import BaseLayout from './components/BaseLayout.vue'; export default { components: { BaseLayout } } </script>
<template> <div> <header> <slot name="header"></slot> </header> <main> <slot name="content"></slot> </main> </div> </template>
作用域插槽允许父组件传递数据到子组件的插槽。
<template> <base-layout> <template v-slot:item="{ item }"> <h2>{{ item.title }}</h2> <p>{{ item.content }}</p> </template> </base-layout> </template> <script> import BaseLayout from './components/BaseLayout.vue'; export default { components: { BaseLayout } } </script>
<template> <div> <header> <slot name="header"></slot> </header> <main> <slot name="content" :items="items"></slot> </main> </div> </template> <script> export default { data() { return { items: [ { title: '标题1', content: '内容1' }, { title: '标题2', content: '内容2' } ] }; } } </script>
在 Vue3 中,可以使用 ref
或 reactive
来声明响应式数据。
import { ref, reactive } from 'vue'; const count = ref(0); const state = reactive({ message: 'Hello Vue3', count: 0 });
v-model
是一个在表单输入元素上创建双向数据绑定的指令。
<template> <input v-model="message" placeholder="输入你的名字"> <p>{{ message }}</p> </template> <script> import { ref } from 'vue'; export default { setup() { const message = ref(''); return { message }; } } </script>
Vue3 的生命周期钩子与 Vue2 类似,但有一些细微的变化。
import { onMounted, onUnmounted } from 'vue'; export default { setup() { onMounted(() => { console.log('组件已挂载'); }); onUnmounted(() => { console.log('组件已卸载'); }); return {}; } }
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeUnmount
unmounted
这些钩子函数可以让你在组件的不同生命周期阶段执行相应的操作。
组件通信可以通过 props、事件、提供/使用(provide/inject)等方式实现。
<template> <child-component :message="parentMessage" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, setup() { const parentMessage = ref('这是父组件传递给子组件的数据'); return { parentMessage }; } } </script>
<template> <child-component @child-event="handleChildEvent" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, setup() { const handleChildEvent = (data) => { console.log('子组件触发了事件:', data); }; return { handleChildEvent }; } } </script>
<template> <child-component /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, setup() { const sharedData = ref('这是共享的数据'); provide('sharedData', sharedData); return {}; } } </script>
<script> import { inject } from 'vue'; export default { setup() { const sharedData = inject('sharedData'); return { sharedData }; } } </script>
Vue Router 是 Vue.js 的官方路由库,可以让你管理单页面应用的不同视图。
import { createRouter, createWebHistory } from 'vue-router'; import Home from './views/Home.vue'; import About from './views/About.vue'; const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
<template> <router-view></router-view> </template>
Vuex 是一个用于 Vue.js 应用的状态管理库,它可以集中管理应用的状态。
import { createStore } from 'vuex'; export default createStore({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { increment({ commit }) { commit('increment'); } }, getters: { count: state => state.count } });
<template> <div> <p>{{ count }}</p> <button @click="increment">Increment</button> </div> </template> <script> import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = computed(() => store.getters.count); const increment = () => { store.dispatch('increment'); }; return { count, increment }; } } </script>
import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; const app = createApp(App); app.use(router); app.use(store); app.mount('#app');
<template> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> <router-view></router-view> </template>
<template> <div> <h1>Home</h1> <p>{{ count }}</p> <button @click="increment">Increment</button> </div> </template> <script> import { computed } from 'vue'; import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = computed(() => store.getters.count); const increment = () => { store.dispatch('increment'); }; return { count, increment }; } } </script>
<template> <div> <h1>About</h1> <p>{{ count }}</p> <button @click="increment">Increment</button> </div> </template> <script> import { computed } from 'vue'; import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = computed(() => store.getters.count); const increment = () => { store.dispatch('increment'); }; return { count, increment }; } } </script>
可以通过减少不必要的数据变动和优化计算属性来提高性能。
import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubleCount = computed(() => { return count.value * 2; }); const increment = () => { count.value++; }; return { count, doubleCount, increment }; } }
对于大型应用,可以使用懒加载来按需加载组件,减少初始加载时间。
import { lazy } from 'vue'; const LazyComponent = lazy(() => import('./LazyComponent.vue')); <template> <lazy-component /> </template>
Vue Devtools 是一个强大的工具,可以帮助你调试 Vue 应用。
import { ref, watch } from 'vue'; export default { setup() { const count = ref(0); watch(count, (newVal, oldVal) => { console.log(`count 从 ${oldVal} 变为了 ${newVal}`); }); const increment = () => { count.value++; }; return { count, increment }; } }
import { onErrorCaptured } from 'vue'; export default { setup() { onErrorCaptured((error) => { console.error('捕获到一个错误:', error); return true; // 继续传播错误 }); const throwError = () => { throw new Error('这是一个错误'); }; return { throwError }; } }
my-vue3-app/ ├── public/ │ ├── index.html ├── src/ │ ├── main.js │ ├── App.vue │ ├── components/ │ │ ├── HelloWorld.vue │ ├── router/ │ │ ├── index.js │ ├── store/ │ │ ├── index.js
import { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; import About from '../views/About.vue'; const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
import { createStore } from 'vuex'; export default createStore({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { increment({ commit }) { commit('increment'); } }, getters: { count: state => state.count } });
import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; const app = createApp(App); app.use(router); app.use(store); app.mount('#app');
<template> <router-view></router-view> </template> <script> import { computed } from 'vue'; import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = computed(() => store.getters.count); const increment = () => { store.dispatch('increment'); }; return { count, increment }; } } </script>
可以使用 props、事件、provide/inject 等方式实现组件间的通信。
<template> <child-component :message="parentMessage" @child-event="handleChildEvent" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, setup() { const parentMessage = ref('这是父组件传递给子组件的数据'); const handleChildEvent = (data) => { console.log('子组件触发了事件:', data); }; return { parentMessage, handleChildEvent }; } } </script> <script> import { inject } from 'vue'; export default { setup() { const sharedData = inject('sharedData'); return { sharedData }; } } </script>
Vue Router 和 Vuex 分别是 Vue.js 的路由库和状态管理库,可以用来管理和优化导航和应用状态。
import { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; import About from '../views/About.vue'; const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
import { createStore } from 'vuex'; export default createStore({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { increment({ commit }) { commit('increment'); } }, getters: { count: state => state.count } });
可以通过减少不必要的渲染、使用懒加载和优化计算属性来优化 Vue3 应用的性能。
import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubleCount = computed(() => { return count.value * 2; }); const increment = () => { count.value++; }; return { count, doubleCount, increment }; } }
可以使用 Vue Devtools、跟踪状态变化和异常处理来调试 Vue3 应用。
import { watch } from 'vue'; export default { setup() { const count = ref(0); watch(count, (newVal, oldVal) => { console.log(`count 从 ${oldVal} 变为了 ${newVal}`); }); const increment = () => { count.value++; }; return { count, increment }; } }
通过以上实战演练,你可以更好地掌握 Vue3 的核心概念和实战技巧,从而在面试中表现出色。