本文详细介绍了Vue3的基本概念和环境搭建步骤,包括Node.js和Vue CLI的安装,以及如何创建第一个Vue3项目。文章还深入讲解了Vue3的基本语法、组件化开发、路由与导航,以及状态管理等关键知识点。此外,文中还提供了丰富的示例代码和实战演练,帮助读者更好地理解和应用Vue3。
Vue3简介与环境搭建Vue.js 是一个用于构建用户界面的渐进式框架,它易于上手,且具有强大的功能。Vue3是Vue.js的最新版本,它带来了许多重要的改进和新特性,包括更高效的状态管理、更灵活的渲染机制、更友好的开发者体验等。选择Vue3,您将获得以下优势:
在开始使用Vue3之前,首先需要安装Node.js和Vue CLI。
安装Node.js
node -v
命令来检查安装是否成功。安装Vue CLI
打开终端或命令行工具(如Windows的cmd或PowerShell),输入以下命令来全局安装Vue CLI:
npm install -g @vue/cli
vue -V
来检查Vue CLI的版本。使用Vue CLI创建第一个Vue3项目,包括以下步骤:
初始化Vue CLI项目:
vue create my-vue-app
在选择预设时,选择Manually select features
,然后选择Vue 3
。
继续初始化项目,完成后进入项目目录:
cd my-vue-app
启动项目:
npm run serve
此时,Vue CLI会启动一个本地服务器,您可以在浏览器中访问http://localhost:8080
来查看您的项目。
Vue3中的模板语法提供了多种指令来实现数据绑定和事件处理。两个常见的指令是v-bind
和v-on
。
v-bind
v-bind
用于动态绑定元素的属性,如类名、内联样式或属性。例如:
<div v-bind:class="{ active: isActive }"></div>
等同于:
<div :class="{ active: isActive }"></div>
v-on
v-on
用于监听DOM事件,例如点击事件:
<button v-on:click="onClick">点我</button>
等同于:
<button @click="onClick">点我</button>
计算属性
计算属性是基于它们的依赖缓存的,只要依赖没有更新,计算属性就不会重新计算。这使它比侦听器更加高效。
例如,计算属性可以用于根据输入字段来计算另一个字段的值:
export default { data() { return { firstName: '', lastName: '' }; }, computed: { fullName() { return `${this.firstName} ${this.lastName}`; } } }
侦听器
侦听器可以监听数据的变化,并在变化时执行自定义的回调函数。例如:
export default { data() { return { message: 'Hello' }; }, watch: { message(newVal, oldVal) { console.log(`新值: ${newVal},旧值: ${oldVal}`); } } }
v-if
v-if
用于在条件为真时渲染元素。条件为假时,该元素将被删除并从DOM中移除。
<div v-if="show">显示这个</div>
v-for
v-for
用于迭代数组或对象的每一项。例如:
<ul> <li v-for="item in items" :key="item.id">{{ item.name }}</li> </ul>
在上述例子中,items
是一个数组,每个item
都有一个id
和name
字段。
组件是Vue应用的基本构建块,每个组件都有自己的模板、逻辑和样式。创建一个名为HelloWorld
的简单组件:
<template> <div> <h1>{{ message }}</h1> <p>{{ description }}</p> </div> </template> <script> export default { name: 'HelloWorld', props: { message: String, description: String } } </script>
组件可以通过props
接收来自父组件的数据,也可以通过事件将数据传递给父组件。
父组件传递给子组件
<template> <div> <HelloWorld :message="helloMessage" :description="helloDescription" /> </div> </template> <script> import HelloWorld from './HelloWorld.vue'; export default { components: { HelloWorld }, data() { return { helloMessage: 'Hello World', helloDescription: '这是一个例子' }; } } </script>
子组件传值给父组件
<template> <div> <input v-model="message" @input="sendMessage"> <button @click="sendMessage">发送</button> </div> </template> <script> export default { name: 'HelloWorld', props: { message: String }, methods: { sendMessage() { this.$emit('change', this.message); } } } </script>
在父组件中监听这个事件:
<template> <div> <HelloWorld :message="helloMessage" @change="setMessage" /> </div> </template> <script> import HelloWorld from './HelloWorld.vue'; export default { components: { HelloWorld }, data() { return { helloMessage: 'Hello World' }; }, methods: { setMessage(message) { this.helloMessage = message; } } } </script>
组件可以嵌套,可以将内容传递给子组件的插槽。例如,以下是一个包含子组件的父组件:
<template> <div> <parent> <child slot="header">这里是头部内容</child> <child slot="footer">这里是底部内容</child> </parent> </div> </template> <script> import Parent from './Parent.vue'; import Child from './Child.vue'; export default { components: { Parent, Child } } </script>
在Parent.vue
中:
<template> <div> <slot name="header"></slot> <slot name="footer"></slot> </div> </template>
在Child.vue
中:
<template> <div> <p>{{ message }}</p> </div> </template> <script> export default { name: 'Child', props: { message: String } } </script>路由与导航
首先,安装Vue Router:
npm install vue-router@next
创建一个router.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 { createApp } from 'vue'; import App from './App.vue'; import router from './router'; createApp(App).use(router).mount('#app');
在路由中使用动态参数,例如:
const routes = [ { path: '/user/:id', component: User } ];
在User.vue
中接收参数:
<template> <div> <h1>User {{ $route.params.id }}</h1> </div> </template>
在组件中访问路由的参数:
import { onMounted } from 'vue'; import { useRoute } from 'vue-router'; export default { setup() { const route = useRoute(); const id = route.params.id; onMounted(() => { console.log(`动态参数ID: ${id}`); }); } }状态管理
首先,安装Vuex:
npm install vuex@next
创建一个store.js
文件,配置Vuex:
import { createStore } from 'vuex'; export default createStore({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { increment({ commit }) { commit('increment'); } } });
在主入口文件中引入Vuex模块:
import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; createApp(App).use(router).use(store).mount('#app');
在组件中访问Store:
<template> <div> {{ count }} <button @click="increment">+</button> </div> </template> <script> import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const count = store.state.count; const increment = () => { store.dispatch('increment'); }; return { count, increment }; } } </script>资源与实战
项目需求:构建一个简单的待办事项应用,支持添加、删除和标记已完成的事项。
项目结构:
src/App.vue
: 主应用组件src/views/AddItem.vue
: 添加事项组件src/store/index.js
: Vuex状态管理主应用组件:
<template> <div> <h1>待办事项</h1> <AddItem @addItem="addItem" /> <ul> <li v-for="item in items" :key="item.id" :class="{ completed: item.completed }" @click="toggle(item)"> {{ item.text }} </li> </ul> </div> </template> <script> import AddItem from './views/AddItem.vue'; import { useStore } from 'vuex'; export default { components: { AddItem }, setup() { const store = useStore(); const items = store.state.items; const addItem = (item) => { store.dispatch('addItem', item); }; const toggle = (item) => { store.dispatch('toggle', item); }; return { items, addItem, toggle }; } } </script>
添加事项组件:
<template> <div> <input v-model="itemText" placeholder="输入待办事项" /> <button @click="addItem">添加</button> </div> </template> <script> import { useStore } from 'vuex'; export default { setup() { const store = useStore(); const itemText = store.state.itemText; const addItem = () => { store.dispatch('addItem', { text: itemText, completed: false }); itemText.value = ''; }; return { itemText, addItem }; } } </script>
Vuex状态管理:
import { createStore } from 'vuex'; export default createStore({ state: { items: [], itemText: '' }, mutations: { addItem(state, item) { state.items.push(item); }, toggle(state, item) { item.completed = !item.completed; } }, actions: { addItem({ commit }, item) { commit('addItem', item); }, toggle({ commit }, item) { commit('toggle', item); } } });
问题1: 组件通信方式选择困难
Vue3推荐使用Composition API来组织代码,通过provide
和inject
来实现组件间通信,避免使用复杂的props
和events
。
// 父组件 import { provide } from 'vue'; export default { setup() { const message = 'Hello'; provide('message', message); return { message }; } } // 子组件 import { inject } from 'vue'; export default { setup() { const message = inject('message'); return { message }; } }
问题2: 路由跳转时状态丢失
使用Vuex来持久化状态,或使用localStorage
存储状态,确保在路由切换时数据不会丢失。
import { createStore } from 'vuex'; export default createStore({ state: { items: JSON.parse(localStorage.getItem('items')) || [] }, mutations: { addItem(state, item) { state.items.push(item); localStorage.setItem('items', JSON.stringify(state.items)); } }, actions: { addItem({ commit }, item) { commit('addItem', item); } } });
通过以上内容,您应该能够获得对Vue3的深入理解,并开始构建复杂的应用程序。