本文详细介绍了Vue3项目实战,从基础知识到组件化开发,再到路由和状态管理,帮助新手入门并提升到初级水平。文章内容涵盖了Vue3的安装、项目搭建、组件使用、路由配置以及状态管理等关键部分。此外,还提供了实战案例,展示了如何创建一个简单的博客应用,并讲解了项目的部署与调试技巧。
在开始使用Vue 3之前,我们需要先安装它。Vue 3 的安装可以通过三种不同的方式完成:使用CDN、使用Vue CLI、或者手动安装。
使用CDN
可以直接在HTML文件中引入Vue的CDN链接,这种方式适合小项目或学习使用。
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/vue@next"></script>
使用Vue CLI
Vue CLI 是一个用于构建 Vue.js 项目的命令行工具。首先需要全局安装 Vue CLI。
npm install -g @vue/cli
然后,通过以下命令创建新的 Vue 项目。
vue create my-vue-project
在创建项目时,可以选择 Vue 3 版本。
npm install vue@next
在安装好 Vue 之后,我们可以开始创建一个简单的 Vue 3 项目。首先创建一个 index.html
文件,然后引入 Vue 和一个简单的 Vue 实例。
<!DOCTYPE html> <html> <head> <title>Vue 3 HelloWorld</title> <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/vue@next"></script> </head> <body> <div id="app"> {{ message }} </div> <script> const { createApp } = Vue; const App = { data() { return { message: 'Hello, Vue 3!' }; }, }; createApp(App).mount('#app'); </script> </body> </html>
Vue 3 使用组件化开发,便于代码维护和复用。组件通常由标签、模板、脚本和样式部分组成。
创建组件
通过创建一个新的 Vue 实例来定义一个组件。
<div id="app"> <my-component></my-component> </div> <script> const { createApp, h } = Vue; const MyComponent = { name: 'MyComponent', template: '<div>这是我的组件</div>', }; const app = createApp({ components: { MyComponent, }, }).mount('#app'); </script>
复用组件
可以将组件引入到其它文件中复用。
<script type="module" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./components/MyComponent.vue"></script>
局部注册组件
除了在全局注册组件,也可以在局部注册。
<script> const { createApp, h } = Vue; const MyComponent = { name: 'MyComponent', template: '局部注册的组件', }; const App = { components: { MyComponent, }, template: '<div><my-component></my-component></div>', }; createApp(App).mount('#app'); </script>
创建组件时,首先定义它的模板和逻辑。
<script> const { createApp, h } = Vue; const MyComponent = { name: 'MyComponent', template: `<div>{{ message }}</div>`, data() { return { message: '这是我的组件', }; }, }; const app = createApp({ components: { MyComponent, }, template: '<my-component></my-component>', }).mount('#app'); </script>
通过 props
将数据从父组件传递给子组件。
<script> const { createApp, h } = Vue; const MyComponent = { name: 'MyComponent', props: ['message'], template: '<div>{{ message }}</div>', }; const app = createApp({ components: { MyComponent, }, template: ` <div> <my-component :message="parentMessage"></my-component> </div> `, data() { return { parentMessage: '从父组件传递的数据', }; }, }).mount('#app'); </script>
事件绑定与触发是组件间通信的常用方式之一。
<script> const { createApp, h } = Vue; const MyComponent = { name: 'MyComponent', template: '<button @click="handleClick">点击我</button>', methods: { handleClick() { this.$emit('custom-event', '事件被触发'); }, }, }; const app = createApp({ components: { MyComponent, }, template: ` <my-component @custom-event="handleCustomEvent"></my-component> `, methods: { handleCustomEvent(message) { console.log(message); // 输出:事件被触发 }, }, }).mount('#app'); </script>
npm install vue-router@next
定义路由
配置路由信息,包括路径和对应的组件。
<script> const { createApp, h } = Vue; import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: () => import('./components/Home.vue'), }, { path: '/about', name: 'About', component: () => import('./components/About.vue'), }, ]; const router = createRouter({ history: createWebHistory(), routes, }); const app = createApp({ router, template: '<router-view></router-view>', }).mount('#app'); </script>
在模板中使用 <router-view>
组件来渲染当前路由对应的组件。
<script> const { createApp, h } = Vue; import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; import Home from './components/Home.vue'; import About from './components/About.vue'; const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home, }, { path: '/about', name: 'About', component: About, }, ]; const router = createRouter({ history: createWebHistory(), routes, }); const app = createApp({ router, template: '<router-view></router-view>', }).mount('#app'); </script>
<script> const routes: Array<RouteRecordRaw> = [ { path: '/user/:id', name: 'User', component: () => import('./components/User.vue'), }, ]; </script>
<script> router.beforeEach((to, from, next) => { if (to.name === 'User') { if (!to.params.id) { next('/home'); return; } } next(); }); </script>
Vuex 是 Vue 3 的官方状态管理库。它使得应用的状态管理更加简单和强大。
npm install vuex@next
配置Vuex
在项目中设置一个 Vuex 实例。
<script> import { createStore } from 'vuex'; const store = createStore({ state: { count: 0, }, mutations: { increment(state) { state.count++; }, }, actions: { increment({ commit }) { commit('increment'); }, }, }); </script>
在组件中通过 store 来读取和修改状态。
<script> import { createStore } from 'vuex'; const store = createStore({ state: { count: 0, }, mutations: { increment(state) { state.count++; }, }, actions: { increment({ commit }) { commit('increment'); }, }, }); const { createApp, h } = Vue; const App = { template: ` <div> <p>{{ count }}</p> <button @click="incrementCount">增加计数</button> </div> `, computed: { count() { return store.state.count; }, }, methods: { incrementCount() { store.dispatch('increment'); }, }, }; createApp(App).use(store).mount('#app'); </script>
创建一个简单的博客应用,包含文章列表、文章详情等功能。
<script> const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: () => import('./components/Home.vue'), }, { path: '/post/:id', name: 'Post', component: () => import('./components/Post.vue'), }, ]; </script>
将博客应用拆分为多个组件。首先定义博客列表组件和文章详情组件。
<script> const Home = { template: '<div><h1>博客列表</h1><ul><li v-for="post in posts" :key="post.id"><router-link :to="`/post/${post.id}`">{{ post.title }}</router-link></li></ul></div>', data() { return { posts: [ { id: 1, title: '第一篇文章' }, { id: 2, title: '第二篇文章' }, ], }; }, }; const Post = { props: ['id'], template: '<div>这是一篇ID为{{ id }}的文章</div>', }; const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home, }, { path: '/post/:id', name: 'Post', component: Post, }, ]; </script>
根据用户的权限动态展示不同的路由。
<script> router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !isAuthenticated()) { next('/login'); return; } next(); }); </script>
使用 Vue CLI 的 build
命令打包项目。
vue-cli-service build
在开发过程中,可以使用 Vue 提供的调试工具和技巧。
Vue.config.productionTip = false; Vue.config.errorHandler = (err, vm, info) => { console.error(`[Vue]: ${info}`, err); };
将项目打包后的文件上传到云服务器,配置服务器端的静态文件服务器。
scp -r dist/ user@your.server.com:/var/www/html/