本文全面介绍了Vue3的基础知识,包括Vue3的主要变化和核心特性。文中详细讲解了Vue3的安装和使用方法,并深入探讨了Vue3的组件化开发、响应式系统以及路由管理等内容。此外,文章还提供了实战项目的设计思路和开发过程,帮助读者更好地理解和应用Vue3。
Vue.js 是一个用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库专注于视图层,因此很容易与其它库或现有的项目集成。Vue 3 是 Vue.js 的最新版本,它在性能、API 设计、工具链支持等方面有了很大改进。
Vue 3 的主要变化包括:
Vue 3 使用了 Proxy 替代 Object.defineProperty 构造响应式对象。这使得 Vue 3 能够更好地支持数组和对象的全部属性的响应式,并且更简洁易用。
Vue 3 引入了 Composition API,它提供了一种更灵活的组织逻辑的方式,能够在组件之间共享逻辑。
Vue 3 对模板编译进行了优化,使框架的运行速度更快。
Vue 3 提供了更好的工具支持,包括更好的 TypeScript 支持和更详细的错误报告。
Vue 3 的核心库体积更小,使得应用的加载和启动速度更快。
安装 Vue CLI:
npm install -g @vue/cli
创建一个新的 Vue 3 项目:
vue create my-vue3-project
选择 Vue 3 作为基础:
? Please pick a preset (Use arrow keys) - default (Vue 2) default (Vue 2) manual (Allows customizing features) Vue 3
选择 Vue 3:
Vue 3
在生成的项目中,你可以找到 src
目录,这是你的项目代码所在的地方。在 src
目录下,有一个 main.js
文件,这是应用的入口文件。在 src
目录下还有一个 App.vue
文件,这是应用的根组件。你可以打开 App.vue
文件,看到默认的模板。
<template> <div id="app"> <h1>Hello Vue 3</h1> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
运行项目:
cd my-vue3-project npm run serve
在 Vue 中,组件是 Vue 应用的基本构建模块,一个 Vue 应用通常由多个组件构成。组件可以被看作自定义 HTML 标签,可以被复用、组合,以实现复杂 UI 功能。每个组件都是一个独立的单元,它有自己独立的视图、逻辑和数据。
创建组件的步骤:
示例:
<template> <div> <h1>{{ title }}</h1> <p>{{ message }}</p> </div> </template> <script> export default { name: 'HelloWorld', data() { return { title: 'Hello', message: 'This is a Vue component' } } } </script> <style scoped> h1 { font-family: Arial, sans-serif; } </style>
组件可以在全局或局部注册。全局注册可以在 main.js
文件中进行,局部注册则在父组件中进行。
全局注册:
import HelloWorld from './components/HelloWorld.vue'; Vue.component('hello-world', HelloWorld);
局部注册:
<template> <div> <hello-world></hello-world> </div> </template> <script> import HelloWorld from './HelloWorld.vue'; export default { components: { HelloWorld } } </script>
在模板中使用组件:
<template> <div> <hello-world></hello-world> </div> </template>
父组件可以通过 props 将数据传递给子组件,子组件可以通过事件(event)将数据传递给父组件。
父组件传递数据给子组件:
<template> <div> <child-component :msg="parentMessage"></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from Parent' } } } </script>
子组件接收数据并传递给父组件:
<template> <div> {{ message }} <button @click="sendMessage">Send Message</button> </div> </template> <script> export default { props: ['msg'], data() { return { message: this.msg } }, methods: { sendMessage() { this.$emit('message-from-child', this.message); } } } </script>
非父子组件之间的通信可以使用 Vuex 或者 Vue 事件总线(bus)。
使用 Vue 事件总线:
// main.js import Vue from 'vue'; import App from './App.vue'; import EventBus from './eventBus'; const app = new Vue({ render: h => h(App), components: { App }, beforeCreate() { Vue.prototype.$eventBus = EventBus; } }); export default app; // eventBus.js import Vue from 'vue'; import VueBus from 'vue-bus'; VueBus.init(Vue); export const EventBus = new Vue({ mixins: [VueBus], data() { return { message: '' }; } }); // ComponentA.vue <template> <div> <button @click="sendMessage">Send Message</button> </div> </template> <script> export default { data() { return { message: 'Message from Component A' }; }, methods: { sendMessage() { this.$eventBus.$emit('message-event', this.message); } } } </script> // ComponentB.vue <template> <div> {{ message }} </div> </template> <script> export default { data() { return { message: '' }; }, created() { this.$eventBus.$on('message-event', (message) => { this.message = message; }); } } </script>
Vue 通过 Proxy
对象来实现数据的响应式。当数据发生改变时,Vue 会自动更新视图。Proxy
可以拦截一些操作,比如读取和设置属性,从而使得 Vue 能够在数据变化时自动更新视图。
Proxy
对象Proxy
可以用来创建一个对象的代理,从而拦截并定义操作。它有两个参数,第一个参数是目标对象,第二个参数是一个 handler 函数,这个函数定义了一系列操作方法。
示例:
const obj = { name: 'Vue', age: 26 }; const proxy = new Proxy(obj, { get(target, key) { console.log(`Getting ${key}`); return target[key]; }, set(target, key, value) { console.log(`Setting ${key} to ${value}`); target[key] = value; } }); console.log(proxy.name); // Getting name, 输出 Vue proxy.age = 27; // Setting age to 27
Vue 中的数据绑定是双向的,当数据变化时,视图会自动更新;当视图变化时,数据也会被更新。这得益于 Vue 的响应式系统。
示例:
<template> <div> <input type="text" v-model="message" /> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: 'Hello Vue' }; } } </script>
计算属性是基于它们的依赖进行缓存的,只有当依赖的数据发生变化时,计算属性才会重新计算。
示例:
<template> <div> {{ fullName }} </div> </template> <script> export default { data() { return { firstName: 'Vue', lastName: '3' }; }, computed: { fullName() { return `${this.firstName} ${this.lastName}`; } } } </script>
侦听器是用来监听数据变化的,当数据发生变化时,侦听器中的回调函数会被调用。
示例:
<template> <div> <button @click="increment">Click me</button> <p>{{ count }}</p> </div> </template> <script> export default { data() { return { count: 0 }; }, watch: { count(newVal, oldVal) { console.log(`The count changed from ${oldVal} to ${newVal}`); } }, methods: { increment() { this.count++; } } } </script>
安装 Vue Router:
npm install vue-router@next
创建 router 配置文件:
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 Vue from 'vue'; import App from './App.vue'; import router from './router'; new Vue({ render: h => h(App), router }).$mount('#app');
路由参数的使用:
const routes = [ { path: '/user/:id', component: User } ];
在组件中通过 this.$route.params
获取参数:
export default { created() { console.log(this.$route.params.id); } }
动态路由的使用:
const routes = [ { path: '/posts/:id', component: Post }, { path: '/posts/:id/comments/:id', component: Comment } ];
路由守卫是用来控制路由变化的,有多种守卫类型,包括全局守卫、路由守卫和导航守卫。
全局守卫:
router.beforeEach((to, from, next) => { console.log(`Navigating from ${from.name} to ${to.name}`); next(); });
路由守卫:
const User = { beforeRouteEnter(to, from, next) { console.log(`Entering User from ${from.name}`); next(); }, beforeRouteLeave(to, from, next) { console.log(`Leaving User to ${to.name}`); next(); } };
导航守卫:
router.beforeResolve((to, from, next) => { console.log(`Navigating from ${from.name} to ${to.name}`); next(); });
Vue 组件的生命周期通常包括创建、挂载、更新、销毁等阶段。每个阶段都有对应的生命周期钩子,这些钩子可以用来执行一些自定义的逻辑。
beforeCreate
:实例初始化完成后,数据观测 (data observer) 和事件配置 (events configuration) 之前被调用。created
:实例创建完成后被调用。此时,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算, watch / computed 等。beforeMount
:在挂载开始之前被调用。此时,实例的模板编译还没有完成。mounted
:挂载完成后被调用。此时,组件渲染完毕,实例的 el
被挂载到指定的 DOM 元素上。beforeUpdate
:数据更新时调用,发生在虚拟 DOM 打补丁之前。可以在这里执行数据同步等操作。updated
:数据更新时调用,发生在虚拟 DOM 打补丁之后。此时,DOM 已经更新。beforeUnmount
:在卸载组件之前调用,此时组件的实例还存在。unmounted
:组件卸载后调用,此时组件的实例已不可访问。beforeCreate
在实例初始化之后,数据观测 (data observer) 和事件配置 (events configuration) 之前被调用。
export default { beforeCreate() { console.log('Before Create'); } }
created
实例创建完成后被调用。此时,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算, watch / computed 等。
export default { created() { console.log('Created'); } }
beforeMount
在挂载开始之前被调用。此时,实例的模板编译还没有完成。
export default { beforeMount() { console.log('Before Mount'); } }
mounted
挂载完成后被调用。此时,组件渲染完毕,实例的 el
被挂载到指定的 DOM 元素上。
export default { mounted() { console.log('Mounted'); } }
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。
export default { beforeUpdate() { console.log('Before Update'); } }
updated
数据更新时调用,发生在虚拟 DOM 打补丁之后。此时,DOM 已经更新。
export default { updated() { console.log('Updated'); } }
beforeUnmount
在卸载组件之前调用,此时组件的实例还存在。
export default { beforeUnmount() { console.log('Before Unmount'); } }
unmounted
组件卸载后调用,此时组件的实例已不可访问。
export default { unmounted() { console.log('Unmounted'); } }
在进行项目设计之前,首先需要进行需求分析,明确项目的功能需求和目标用户。需求分析通常包括以下几个步骤:
设计项目的整体架构,包括前端和后端的设计。前端主要考虑如何组织视图组件,后端则考虑如何组织数据接口。
前端架构方面,可以使用 Vue Router 管理路由,使用 Vuex 管理状态。后端架构方面,可以考虑使用 RESTful API,也可以使用 gRPC 或 GraphQL。
选择合适的技术栈,包括前端框架、后端框架、数据库等。Vue 3 是前端框架的常见选择,后端框架可以选择 Express、Koa 或 Django 等。数据库可以选择 MySQL、MongoDB 或 PostgreSQL 等。
安装项目所需依赖:
npm install axios vue-router vuex
创建项目目录结构,配置 webpack
或其他构建工具,配置环境变量等。
编写项目代码,包括前端和后端代码。前端代码主要使用 Vue 3,后端代码可以使用 Node.js 或其他后端语言。
前端代码示例:
<template> <div> <nav> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </nav> <router-view /> </div> </template> <script> 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; </script>
后端代码示例:
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(3000, () => { console.log('Server running on port 3000'); });
进行单元测试和集成测试,确保代码质量和功能正确性。
使用浏览器调试工具和后端调试工具调试代码,确保代码运行无误。
将代码托管到代码托管平台,如 GitHub、GitLab 等。代码托管的目的是为了备份和协作。
使用 CI/CD 工具进行自动构建和部署。CI/CD 工具可以将代码从代码托管平台拉取到构建服务器,进行构建和测试,最后部署到生产环境。
部署后,需要对应用进行监控和维护,确保应用的稳定性和性能。监控可以使用 Prometheus、Grafana 等工具进行。维护可以使用 GitOps 等技术进行。