Vue 3 是 Vue.js 的最新主要版本,带来了许多改进和新特性,包括更好的性能、更小的体积、更强大的 TypeScript 支持以及 Composition API 等。以下是一个基础教程,帮助你开始使用 Vue 3。
Vite 是一个非常快速的构建工具,非常适合用于创建 Vue 3 项目。
bashnpm init vite@latest my-vue-app --template vue
cd my-vue-app
npm install
npm run dev
如果你已经有自己的项目结构,可以通过 npm 或 yarn 手动安装 Vue 3:
bashnpm install vue@next
# 或者
yarn add vue@next
在 main.js
中设置你的 Vue 应用:
javascriptimport { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
然后,在 App.vue
中定义你的组件:
html<template>
<div id="app">
<h1>{{ message }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue 3!'
}
}
}
</script>
Vue 3 引入了组合式 API,它提供了一种更加灵活的方式来组织代码逻辑。
javascript<template>
<div>{{ count }} {{ text }}</div>
<button @click="increment">Increment</button>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const text = computed(() => count.value > 5 ? 'Greater than 5' : 'Less than 5');
function increment() {
count.value++;
}
return { count, text, increment };
}
}
</script>
在 Vue 3 中,生命周期钩子与 Vue 2 类似,但它们现在也可以在 setup()
函数中使用。
javascriptimport { onMounted, onUnmounted } from 'vue';
export default {
setup() {
onMounted(() => {
console.log('Component is mounted!');
});
onUnmounted(() => {
console.log('Component will unmount.');
});
}
};
Vue 3 提供了多个函数来创建响应式数据:ref
, reactive
和 computed
。
ref
创建单一值的响应式引用。reactive
创建对象类型的响应式引用。computed
创建计算属性。javascriptimport { ref, reactive, computed } from 'vue';
export default {
setup() {
// 单一值响应式引用
let age = ref(20);
// 对象类型响应式引用
let state = reactive({
name: 'Vue'
});
// 计算属性
let fullName = computed(() => `${state.name} 3`);
return { age, state, fullName };
}
};
Teleport 提供了一种跨层级组件边界管理 DOM 节点的方式。
html<teleport to="body">
<div v-if="showModal" class="modal">
<p>This is a modal dialog!</p>
<button @click="showModal = false">Close</button>
</div>
</teleport>
javascriptexport default {
data() {
return {
showModal: true
}
}
};
在 Vue 3 中,组件可以返回多个根节点(Fragments)。
html<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>
Suspense 允许你在等待异步依赖时显示一个加载状态。
html<template>
<suspense>
<template #default>
<async-component />
</template>
<template #fallback>
Loading...
</template>
</suspense>
</template>
自定义指令的定义方式在 Vue 3 中有所变化,使用 app.directive
来注册全局指令或局部指令。
javascript// 注册全局指令
app.directive('focus', {
mounted(el) {
el.focus();
}
});
或者在组件内部定义局部指令:
javascriptexport default {
directives: {
focus: {
mounted(el) {
el.focus();
}
}
}
};
插槽机制在 Vue 3 中保持不变,但是使用上更加直观。
html<!-- 子组件 -->
<template>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</template>
<!-- 父组件 -->
<child-component>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</child-component>
Composition API 提供了更灵活的方式来组织和重用逻辑代码。这对于处理复杂的组件状态管理非常有用。
ref
和 reactive
组合逻辑javascriptimport { ref, reactive, computed } from 'vue';
export default {
setup() {
// 使用 ref 创建单一值的响应式引用
const count = ref(0);
// 使用 reactive 创建对象类型的响应式引用
const state = reactive({
name: 'Vue 3',
age: 3
});
// 计算属性
const fullName = computed(() => `${state.name} ${state.age}`);
function increment() {
count.value++;
}
return { count, state, fullName, increment };
}
};
provide
和 inject
提供了一种在父组件与任意深度嵌套的子组件之间传递数据的方式,而不需要通过 props 手动逐层传递。
javascriptimport { provide, ref } from 'vue';
export default {
setup() {
const user = ref('John Doe');
provide('user', user);
}
};
javascriptimport { inject } from 'vue';
export default {
setup() {
const user = inject('user');
return { user };
}
};
<script setup>
<script setup>
是 Vue 3 中的一个语法糖,它使得编写组合式 API 更加简洁直观。
vue<script setup> import { ref } from 'vue'; const count = ref(0); function increment() { count.value++; } </script> <template> <button @click="increment">Count is: {{ count }}</button> </template>
Vue 3 对 TypeScript 支持更好,尤其是在使用 Composition API 时。
typescript<script setup lang="ts">
import { ref } from 'vue';
const count = ref<number>(0);
function increment(): void {
count.value++;
}
</script>
Vue Router 4.x 与 Vue 3 兼容,并引入了一些新的特性。
bashnpm install vue-router@4
javascriptimport { createRouter, createWebHistory } from 'vue-router';
import Home from './components/Home.vue';
import About from './components/About.vue';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
javascriptimport { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App).use(router).mount('#app');
Vuex 4.x 与 Vue 3 兼容,提供了状态管理功能。
bashnpm install vuex@next
javascriptimport { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit('increment');
}
}
});
javascriptimport { createApp } from 'vue';
import App from './App.vue';
import store from './store';
createApp(App).use(store).mount('#app');
Vue 3 提供了 <transition>
和 <transition-group>
组件来实现动画效果。
html<transition name="fade">
<p v-if="show">Hello, Vue 3!</p>
</transition>
CSS 样式:
css.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
opacity: 0;
}
Vue Test Utils 为 Vue 3 提供了单元测试支持。
bashnpm install --save-dev @vue/test-utils vitest
javascriptimport { mount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';
describe('MyComponent.vue', () => {
it('renders correctly', () => {
const wrapper = mount(MyComponent, {
props: { msg: 'hello!' }
});
expect(wrapper.text()).toContain('hello!');
});
});
Vue I18n 为 Vue 3 提供了国际化支持。
bashnpm install vue-i18n@next
javascriptimport { createI18n } from 'vue-i18n';
const i18n = createI18n({
locale: 'en',
messages: {
en: { message: { hello: 'hello world' }},
zh: { message: { hello: '你好,世界' }}
}
});
export default i18n;
javascriptimport { createApp } from 'vue';
import App from './App.vue';
import i18n from './i18n';
createApp(App).use(i18n).mount('#app');