本文全面介绍了Vue3的基础概念,包括Composition API和更好的TypeScript支持,并详细讲解了Vue3与Vue2的区别及环境搭建方法。文章还深入探讨了Vue3组件开发、响应式原理、路由与状态管理,以及通过一个简单的待办事项应用展示了Vue3的实际应用。文中提供了丰富的代码示例和实战技巧,帮助开发者更好地理解和使用Vue3。
Vue3基础概念介绍 什么是Vue3Vue3 是 Vue.js 的最新版本,它在 Vue2 的基础上进行了一系列的改进和优化。Vue3 引入了 Composition API,提供了更灵活的组件逻辑管理和更好的 TypeScript 支持。同时,Vue3 还优化了渲染性能,并引入了新的响应式系统,使得开发效率和应用性能得到显著提升。
Vue3的核心特性Composition API
Composition API 是 Vue3 中引入的一个新的 API,它允许开发者更灵活地组织和复用组件逻辑。通过 setup
函数,开发者可以更清晰地分离和组合组件逻辑。
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
onMounted(() => {
console.log('Component is mounted');
});
return {
count
};
}
};
更好的TypeScript支持
Vue3 对 TypeScript 的支持进行了增强,提供了更强大的类型推断和更丰富的类型定义,使得开发者能够更好地利用 TypeScript 的静态类型检查功能。
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref<number>(0);
onMounted(() => {
console.log('Component is mounted');
});
return {
count
};
}
};
优化的渲染性能
Vue3 对模板解析器进行了重构,使得模板编译速度提高了 20%。同时,通过引入 Proxy
对象作为响应式依赖,Vue3 实现了更高效的依赖收集和更新机制。
Composition API vs Options API
Vue2 使用 Options API,开发者需要在一个对象中定义组件的数据、方法、生命周期钩子等。而在 Vue3 中,Composition API 提供了一种更灵活的方式来组织和复用组件逻辑。
// Vue2 使用 Options API
export default {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
},
mounted() {
console.log('Component is mounted');
}
};
// Vue3 使用 Composition API
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
onMounted(() => {
console.log('Component is mounted');
});
return {
count
};
}
};
语法糖的简化
Vue3 对一些语法糖进行了简化,使得代码更加简洁易读。例如,v-on
简化为 @
,v-bind
简化为 :
。
<!-- Vue2 -->
<template>
<button v-on:click="increment">Click me</button>
</template>
<!-- Vue3 -->
<template>
<button @click="increment">Click me</button>
</template>
Vue3环境搭建
创建Vue3项目
要创建一个新的 Vue3 项目,首先需要确保已经安装了 Node.js 和 npm。然后,可以通过 Vue CLI 或者手动创建项目。
使用 Vue CLI 创建 Vue3 项目:
npm install -g @vue/cli
vue create my-vue3-project
cd my-vue3-project
npm install
手动创建 Vue3 项目:
npm init -y
npm install vue@next
使用Vue CLI快速搭建Vue3项目
Vue CLI 提供了快速搭建 Vue3 项目的功能,可以通过 vue create
命令来创建项目,并选择 Vue3 版本。
vue create my-vue3-project
在创建过程中,可以选择预设的配置或者手动选择特性,例如 Babel、Router、Vuex 等。
安装和配置常用工具(如ESLint、Prettier)安装ESLint
使用 Vue CLI 创建项目时,可以选择安装 ESLint 来进行代码格式检查和错误提示。
vue create my-vue3-project --preset @vue/preset-modules --plugins eslint
手动安装 ESLint:
npm install eslint eslint-plugin-vue eslint-config-prettier eslint-plugin-prettier --save-dev
配置ESLint
在项目根目录下创建 .eslintrc.js
文件,并配置 ESLint 规则。
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'plugin:vue/recommended',
'eslint:recommended',
'prettier'
],
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: 12,
sourceType: 'module'
},
plugins: ['vue'],
rules: {
'vue/multi-word-component-names': 'off',
'prettier/prettier': 'error'
}
};
安装Prettier
Prettier 是一个代码格式化工具,可以自动格式化代码,减少代码风格上的不一致。
npm install prettier --save-dev
配置Prettier
在项目根目录下创建 .prettierrc.js
文件,并配置 Prettier 规则。
module.exports = {
semi: true,
singleQuote: true,
trailingComma: 'all',
printWidth: 80,
tabWidth: 2
};
Vue3组件开发
组件的基本使用
Vue3 中的组件可以通过 export default
导出,然后在其他组件中通过 <component>
标签来使用。
// Button.vue
<template>
<button @click="clickHandler">Click me</button>
</template>
<script setup>
import { ref } from 'vue';
const clickCount = ref(0);
const clickHandler = () => {
clickCount.value++;
};
defineExpose({
clickCount
});
</script>
<!-- App.vue -->
<template>
<HelloWorld />
<Button @click="handleClick" />
</template>
<script setup>
import Button from './components/Button.vue';
const handleClick = () => {
console.log('Button clicked');
};
</script>
通过上述代码,我们定义了一个简单的 Button
组件,并在 App.vue
中使用了它。Button
组件内部定义了一个 clickCount
状态和一个 clickHandler
方法,当按钮被点击时,clickCount
的值会增加。在 App.vue
中,我们通过 @click
事件监听器来处理按钮点击事件。
属性传递
组件可以通过 props
来传递属性,并在组件内部通过 props
来接收这些属性。
// ChildComponent.vue
<template>
<div>{{ name }} is {{ age }} years old</div>
</template>
<script setup>
defineProps({
name: String,
age: Number
});
</script>
<!-- ParentComponent.vue -->
<template>
<ChildComponent name="John" :age="25" />
</template>
<script setup>
import ChildComponent from './components/ChildComponent.vue';
</script>
在上述代码中,ChildComponent
接收两个属性 name
和 age
,并在模板中使用它们。而在 ParentComponent
中,我们通过传递 name
和 age
属性来初始化 ChildComponent
。
事件传递
组件可以通过 emit
来触发事件,并在父组件中通过 @
来监听这些事件。
// ChildComponent.vue
<template>
<button @click="handleClick">Click me</button>
</template>
<script setup>
import { defineEmits } from 'vue';
const emit = defineEmits(['click']);
const handleClick = () => {
emit('click');
};
</script>
<!-- ParentComponent.vue -->
<template>
<ChildComponent @click="handleClick" />
</template>
<script setup>
import ChildComponent from './components/ChildComponent.vue';
const handleClick = () => {
console.log('Child component clicked');
};
</script>
通过上述代码,我们定义了一个触发点击事件的 ChildComponent
,并在 ParentComponent
中通过 @click
监听该事件。当点击 ChildComponent
中的按钮时,会触发 ParentComponent
中的 handleClick
方法。
复用组件
复用组件可以通过将通用的逻辑提取到一个独立的组件中,然后在需要的地方引入和使用。
// Button.vue
<template>
<button @click="handleClick">{{ text }}</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
text: String
});
const emit = defineEmits(['click']);
const handleClick = () => {
emit('click');
};
</script>
<!-- App.vue -->
<template>
<Button text="Click me" @click="handleClick" />
<Button text="Another button" @click="handleAnotherClick" />
</template>
<script setup>
import Button from './components/Button.vue';
const handleClick = () => {
console.log('Button clicked');
};
const handleAnotherClick = () => {
console.log('Another button clicked');
};
</script>
通过这种方式,我们可以在不同的地方复用 Button
组件,并传递不同的文本和事件处理函数。
优化组件
优化组件可以通过减少冗余代码、提高渲染性能等手段来实现。
// 优化前
<template>
<div v-if="show">{{ message }}</div>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(true);
const message = 'Hello, World!';
</script>
<!-- 优化后 -->
<template>
<div v-show="show">{{ message }}</div>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(true);
const message = 'Hello, World!';
</script>
在优化前的代码中,v-if
会完全移除或渲染节点,而优化后的代码使用 v-show
,只是切换节点的显示或隐藏,从而减少了渲染开销。
Vue3 使用 Proxy
对象来实现响应式系统。Proxy
对象可以拦截和转换某些操作,使得当数据发生变化时,Vue3 能够自动更新视图。
import { reactive } from 'vue';
const state = reactive({
message: 'Hello, World!'
});
console.log(state.message); // 输出: 'Hello, World!'
state.message = 'Hello, Vue3';
console.log(state.message); // 输出: 'Hello, Vue3'
通过上述代码,我们定义了一个 state
对象并使用 reactive
函数使其成为响应式的。当 state.message
发生变化时,Vue3 会自动触发视图更新。
Composition API
Composition API 提供了更灵活的方式来组织和复用组件逻辑。通过 setup
函数,开发者可以更清晰地分离和组合组件逻辑。
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
onMounted(() => {
console.log('Component is mounted');
});
return {
count
};
}
};
Options API
Options API 是 Vue2 中使用的 API,开发者需要在一个对象中定义组件的数据、方法、生命周期钩子等。
export default {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
},
mounted() {
console.log('Component is mounted');
}
};
响应式数据的生命周期
Vue3 中响应式数据的生命周期包括创建、更新和销毁。
import { ref, onMounted, onUnmounted } from 'vue';
export default {
setup() {
const count = ref(0);
onMounted(() => {
console.log('Component is mounted');
});
onUnmounted(() => {
console.log('Component is unmounted');
});
return {
count
};
}
};
在上述代码中,我们定义了一个 count
变量,并使用 onMounted
和 onUnmounted
生命周期钩子来处理组件的挂载和卸载。
Vue Router 是 Vue3 中用于实现路由功能的官方库。通过 Vue Router,开发者可以实现单页面应用的导航和路由管理。
安装 Vue Router:
npm install vue-router@next
定义路由配置:
import { 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;
在主应用文件中使用 Vue Router:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
const app = createApp(App);
app.use(router);
app.mount('#app');
定义路由导航:
<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view></router-view>
</template>
通过上述代码,我们定义了两个路由,并在主应用文件中使用 Vue Router 来管理这些路由。路由导航组件允许用户在不同页面之间切换。
Vuex的状态管理Vuex 是一个用于管理应用状态的库。它提供了一种集中式的状态管理方式,使得状态管理变得更加清晰和易于维护。
安装 Vuex:
npm install vuex@next
定义 Vuex store:
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment(context) {
context.commit('increment');
}
},
getters: {
count: state => state.count
}
});
在主应用文件中使用 Vuex:
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');
在组件中使用 Vuex:
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const increment = () => {
store.dispatch('increment');
};
return {
increment
};
}
};
通过上述代码,我们定义了一个 Vuex store,并在主应用文件中使用 Vuex。在组件中,我们通过 useStore
获取 store,并调用 increment
方法来更新状态。
通过结合 Vue Router 和 Vuex,可以实现更复杂的应用状态管理。
定义路由配置:
import { 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;
在组件中使用路由和 Vuex:
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const increment = () => {
store.dispatch('increment');
};
return {
increment
};
}
};
通过上述代码,我们定义了路由配置,并在组件中使用 Vuex 来管理应用状态。当路由切换时,状态管理可以保持一致性。
Vue3实战案例 实现一个简单的待办事项应用创建项目结构
首先,创建一个简单的项目结构,包含 App.vue
、TodoList.vue
和 TodoItem.vue
组件。
vue create todo-app
cd todo-app
定义TodoItem组件
TodoItem.vue
组件用于展示和编辑待办事项。
<template>
<li>
<input type="checkbox" v-model="completed" />
<span :class="{ completed: completed }">{{ text }}</span>
<button @click="remove">Remove</button>
</li>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
text: String,
completed: Boolean
});
const emit = defineEmits(['remove']);
const remove = () => {
emit('remove');
};
</script>
通过上述代码,我们定义了一个 TodoItem
组件,该组件展示一个待办事项,并提供一个复选框(表示已完成)和一个移除按钮。当用户点击移除按钮时,会触发 remove
事件。
定义TodoList组件
TodoList.vue
组件用于管理待办事项列表。
<template>
<div>
<ul>
<TodoItem
v-for="todo in todos"
:key="todo.id"
:text="todo.text"
:completed="todo.completed"
@remove="removeTodo(todo.id)"
/>
</ul>
<form @submit.prevent="addTodo">
<input v-model="newTodoText" placeholder="Add a new todo" />
<button type="submit">Add</button>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import TodoItem from './TodoItem.vue';
const todos = ref([
{ id: 1, text: 'Learn Vue3', completed: false },
{ id: 2, text: 'Build a todo app', completed: false }
]);
const newTodoText = ref('');
const addTodo = () => {
if (newTodoText.value.trim() !== '') {
const todo = {
id: Date.now(),
text: newTodoText.value,
completed: false
};
todos.value.push(todo);
newTodoText.value = '';
}
};
const removeTodo = (id) => {
todos.value = todos.value.filter((todo) => todo.id !== id);
};
</script>
通过上述代码,我们定义了一个 TodoList
组件,该组件管理待办事项列表,并提供一个表单来添加新的待办事项。当用户点击添加按钮时,会执行 addTodo
方法,添加新的待办事项。当用户点击移除按钮时,会执行 removeTodo
方法,移除待办事项。
定义App组件
App.vue
组件用于展示整个应用。
<template>
<TodoList />
</template>
<script setup>
import TodoList from './components/TodoList.vue';
</script>
通过上述代码,我们定义了一个 App.vue
组件,该组件引入并渲染了 TodoList
组件。
运行项目
npm run serve
项目测试
可以使用 Jest 或 Vue Test Utils 进行单元测试和集成测试。
安装测试工具:
npm install --save-dev jest @vue/test-utils
创建测试文件:
vue add jest
编写测试用例:
import { describe, it, expect } from 'vitest';
import { shallowMount } from '@vue/test-utils';
import TodoList from '@/components/TodoList.vue';
describe('TodoList.vue', () => {
it('renders todo items', () => {
const wrapper = shallowMount(TodoList);
expect(wrapper.findAll('li').length).toBe(2);
});
});
通过上述代码,我们定义了一个测试用例,验证了 TodoList
组件是否正确渲染了待办事项。
项目部署与上线
使用 npm run build
命令构建项目,然后将生成的 dist
目录上传到服务器。
npm run build
将生成的 dist
目录上传到服务器,例如使用 FTP 或者 Git。
scp -r dist/* user@server:/path/to/deploy
或者使用 Git:
git add dist
git commit -m "deploy"
git push
通过上述步骤,你就可以成功地实现一个简单的待办事项应用,并完成项目测试和部署。
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章