Vue3全家桶学习涵盖了Vue3的基础知识、组件化开发、响应式原理、Vue Router与Vuex的使用,以及与TypeScript的结合,帮助开发者全面掌握Vue3的开发技巧。文章详细介绍了从安装配置到实战演练的全过程,旨在帮助读者快速上手并构建实际项目。此外,还提供了部署上线和常见问题的解决方法,确保项目顺利运行。
Vue3基础知识入门 Vue3简介Vue.js 是一个渐进式 JavaScript 框架,它让构建优秀的用户界面变得非常轻松。Vue3 是 Vue.js 的最新版本,它带来了许多新特性、优化及增强,包括更好的性能、TypeScript 支持、Composition API 等。Vue3 提供了一个灵活的架构,支持自定义渲染器,这使得 Vue 可以应用于广泛的环境和运行时环境,如服务端渲染、静态站点生成、Web Components 等。
Vue3安装与配置-
安装 Node.js
首先,你需要确保已经安装了 Node.js。你可以从 Node.js 官方网站下载并安装最新版本的 Node.js。Node.js 的安装将自动安装 npm(Node Package Manager),这是 Node.js 的包管理器。 -
安装 Vue CLI
Vue CLI 是一个用于快速创建 Vue.js 项目的命令行工具。安装 Vue CLI 可以使用以下命令:npm install -g @vue/cli
-
创建 Vue3 项目
使用 Vue CLI 创建一个新的 Vue3 项目:vue create my-vue3-project
在创建过程中,选择 Vue3 版本,或者在默认配置中手动选择 Vue3。
-
项目初始化
创建项目后,可以使用以下命令进入项目目录并启动开发服务器:cd my-vue3-project npm run serve
这将启动开发服务器,你可以在浏览器中打开
http://localhost:8080
查看项目。
一个典型的 Vue3 项目结构如下:
my-vue3-project/
├── node_modules/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── assets/
│ ├── components/
│ ├── App.vue
│ ├── main.js
│ └── router/
│ └── index.js
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock
- public:存放静态文件,如
index.html
和favicon.ico
。 - src:存放源代码,包括组件、资源文件、路由配置等。
- App.vue:项目的根组件。
- main.js:项目的入口文件。
- router:存放路由配置文件。
示例代码:根组件 App.vue
<template>
<div id="app">
<h1>Hello Vue3</h1>
<router-view></router-view>
</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>
Vue3组件化开发
组件的基本使用
Vue3 使用组件构建用户界面。组件可以看作是可重用的自包含的 Vue 实例。每个组件都有自己的模板、样式和逻辑。
创建组件
组件是通过 Vue 的 defineComponent
函数定义的:
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
},
template: `
<div class="hello">
<h1>{{ msg }}</h1>
</div>
`,
});
使用组件
在其他组件中使用上面定义的组件:
<template>
<h1>{{ title }}</h1>
<HelloWorld msg="Hello Vue3" />
</template>
<script>
import HelloWorld from './components/HelloWorld.vue';
export default {
name: 'App',
components: {
HelloWorld
},
data() {
return {
title: 'App Title'
};
}
}
</script>
组件间的数据传递
父组件向子组件传递数据
父组件可以通过 props
向子组件传递数据:
<!-- Parent.vue -->
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent'
};
}
}
</script>
<!-- ChildComponent.vue -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
name: 'ChildComponent',
props: {
message: String
}
}
</script>
子组件向父组件传递数据
子组件可以通过 $emit
触发事件,向父组件传递数据。
<!-- ChildComponent.vue -->
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
name: 'ChildComponent',
methods: {
sendMessage() {
this.$emit('messageSent', 'Hello from child');
}
}
}
</script>
<!-- Parent.vue -->
<template>
<ChildComponent @messageSent="handleMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
name: 'Parent',
components: {
ChildComponent
},
methods: {
handleMessage(message) {
console.log(message);
}
}
}
</script>
插槽(Slot)的使用
插槽用于向子组件传递内容。插槽可以分为默认插槽、具名插槽和作用域插槽。
默认插槽
<!-- Parent.vue -->
<template>
<ChildComponent>
<h2>This is default slot content</h2>
</ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
}
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<slot></slot>
</div>
</template>
具名插槽
<!-- Parent.vue -->
<template>
<ChildComponent>
<template v-slot:header>
<h1>This is header slot content</h1>
</template>
<template v-slot:footer>
<p>This is footer slot content</p>
</template>
</ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
}
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>
</template>
作用域插槽
作用域插槽允许子组件传递数据给父组件。
<!-- ChildComponent.vue -->
<template>
<slot v-bind:item="item"></slot>
</template>
<script>
export default {
name: 'ChildComponent',
data() {
return {
item: { id: 1, name: 'John' }
};
}
}
</script>
<!-- Parent.vue -->
<template>
<ChildComponent>
<template v-slot:default="{ item }">
<p>ID: {{ item.id }}</p>
<p>Name: {{ item.name }}</p>
</template>
</ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
}
</script>
Vue3响应式原理与应用
响应式数据绑定
Vue3 使用 Proxy 来实现响应式系统,这比 Vue2 中的 Object.defineProperty
更加强大。响应式数据绑定是通过 ref
和 reactive
实现的。
使用 ref
ref
用于基本数据类型:
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
return { count };
}
}
在模板中使用:
<template>
<div>
<p>{{ count }}</p>
<button @click="count++">Increment</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
return { count };
}
}
</script>
使用 reactive
reactive
用于复杂的数据对象:
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
name: 'John'
});
return { state };
}
}
在模板中使用:
<template>
<div>
<p>{{ state.count }}</p>
<p>{{ state.name }}</p>
</div>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
name: 'John'
});
return { state };
}
}
</script>
computed
计算属性
计算属性是基于组件内部的状态计算出的结果。
import { ref, computed } from 'vue';
export default {
setup() {
const a = ref(1);
const b = ref(2);
const sum = computed(() => a.value + b.value);
return { a, b, sum };
}
}
在模板中使用:
<template>
<div>
<p>{{ a }}</p>
<p>{{ b }}</p>
<p>{{ sum }}</p>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const a = ref(1);
const b = ref(2);
const sum = computed(() => a.value + b.value);
return { a, b, sum };
}
}
</script>
watch
侦听器
侦听器用于监听数据的变化,并在数据变化时执行回调。
import { ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${oldValue} to ${newValue}`);
});
return { count };
}
}
计算属性与侦听器
计算属性 vs 侦听器
计算属性和侦听器都可以用于数据处理,但它们的工作方式不同。
- 计算属性:计算属性基于依赖关系进行缓存,仅在依赖变化时重新计算。
- 侦听器:侦听器直接监听数据的变化,并在变化时执行回调。
示例代码
import { ref, computed, watch } from 'vue';
export default {
setup() {
const a = ref(1);
const b = ref(2);
const sum = computed(() => a.value + b.value);
watch([a, b], (newValues, oldValues) => {
console.log(`Values changed from ${JSON.stringify(oldValues)} to ${JSON.stringify(newValues)}`);
});
return { a, b, sum };
}
}
在模板中使用:
<template>
<div>
<p>{{ a }}</p>
<p>{{ b }}</p>
<p>{{ sum }}</p>
</div>
</template>
<script>
import { ref, computed, watch } from 'vue';
export default {
setup() {
const a = ref(1);
const b = ref(2);
const sum = computed(() => a.value + b.value);
watch([a, b], (newValues, oldValues) => {
console.log(`Values changed from ${JSON.stringify(oldValues)} to ${JSON.stringify(newValues)}`);
});
return { a, b, sum };
}
}
</script>
深浅响应式对比
示例代码:浅响应式
import { ref } from 'vue';
export default {
setup() {
const state = ref({
a: 1,
b: { text: 'hello' }
});
return { state };
}
}
示例代码:深响应式
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
a: 1,
b: { text: 'hello' }
});
return { state };
}
}
Vue3全家桶中的Router与Vuex
Vue Router基本使用
Vue Router 是 Vue.js 官方的路由插件,用于管理前端路由。它支持路由参数、重定向、命名路由、嵌套路由等。
安装 Vue Router
npm install vue-router
基本配置
import { createRouter, createWebHistory } from 'vue-router';
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');
示例代码:定义路由和组件
// router/index.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;
<!-- views/Home.vue -->
<template>
<div>
<h1>Home Page</h1>
</div>
</template>
<!-- views/About.vue -->
<template>
<div>
<h1>About Page</h1>
</div>
</template>
Vuex状态管理
Vuex 是一个集中式的状态管理库,用于 Vue.js 应用。它可以帮助你管理应用中的状态,使状态管理更加一致且可预测。
安装 Vuex
npm install vuex
基本配置
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment(context) {
context.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');
示例代码:定义 Vuex 状态和操作
// store/index.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment(context) {
context.commit('increment');
}
}
});
实战案例:使用Router与Vuex构建应用
项目结构
my-vue3-project/
├── node_modules/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── assets/
│ ├── components/
│ ├── App.vue
│ ├── main.js
│ └── router/
│ └── index.js
│ └── store/
│ └── index.js
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock
示例代码:定义路由和组件
// router/index.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;
<!-- views/Home.vue -->
<template>
<div>
<h1>Home Page</h1>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count'])
},
methods: {
...mapActions(['increment'])
}
}
</script>
<!-- views/About.vue -->
<template>
<div>
<h1>About Page</h1>
</div>
</template>
示例代码:定义 Vuex 状态和操作
// store/index.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment(context) {
context.commit('increment');
}
}
});
Vue3与TypeScript结合
TypeScript基础入门
TypeScript 是 JavaScript 的超集,提供了静态类型检查,使得代码更加健壮和易于维护。TypeScript 的主要特性包括类型注解、接口、泛型等。
安装 TypeScript
npm install typescript
基本语法
// TypeScript 基本类型
let a: number = 1;
let b: string = 'hello';
let c: boolean = true;
let d: null = null;
let e: undefined = undefined;
// 数组
let arr: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];
// 对象
let obj: { name: string, age: number } = { name: 'John', age: 30 };
// 接口
interface Person {
name: string;
age: number;
}
let person: Person = { name: 'John', age: 30 };
// 泛型
function identity<T>(arg: T): T {
return arg;
}
let result = identity<string>('hello');
Vue3项目中引入TypeScript
安装 Vue CLI TypeScript 插件
npm install -g @vue/cli-plugin-typescript
创建 Vue3 项目并配置 TypeScript
vue create my-vue3-project
选择 Vue3 项目模板并启用 TypeScript 插件。
示例代码:使用 TypeScript 编写 Vue 组件
<script setup lang="ts">
import { ref } from 'vue';
const count = ref(0);
function increment() {
count.value++;
}
</script>
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<style scoped>
p {
font-size: 20px;
}
</style>
Type安全的组件开发
使用 TypeScript 定义 Props
<script setup lang="ts">
import { defineComponent, ref, defineProps } from 'vue';
interface Props {
message: string;
}
const props = defineProps<Props>();
const count = ref(0);
function increment() {
count.value++;
}
</script>
<template>
<div>
<p>{{ props.message }}</p>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
使用 TypeScript 定义 Emits
<script setup lang="ts">
import { defineComponent, ref, defineEmits } from 'vue';
interface Props {
message: string;
}
const props = defineProps<Props>();
const count = ref(0);
const emit = defineEmits<{
(e: 'incremented', value: number): void;
}>();
function increment() {
count.value++;
emit('incremented', count.value);
}
</script>
<template>
<div>
<p>{{ props.message }}</p>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
Vue3项目实战演练
小项目实战:从零开始搭建Vue3项目
项目需求
假设我们需要创建一个简单的待办事项(To-Do List)应用。该应用需要有以下功能:
- 添加新的待办事项。
- 显示所有待办事项。
- 删除已添加的待办事项。
项目结构
to-do-list/
├── node_modules/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── assets/
│ ├── components/
│ │ └── TodoItem.vue
│ ├── App.vue
│ ├── main.ts
│ └── router/
│ └── index.ts
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock
示例代码:定义根组件 App.vue
<script setup lang="ts">
import { ref } from 'vue';
import TodoItem from './components/TodoItem.vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const todoList = ref<string[]>([]);
const newTodo = ref('');
function addTodo() {
if (newTodo.value) {
todoList.value.push(newTodo.value);
newTodo.value = '';
}
}
function deleteTodo(index: number) {
todoList.value.splice(index, 1);
}
</script>
<template>
<div id="app">
<h1>To-Do List</h1>
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Type a new todo">
<button @click="addTodo">Add</button>
<ul>
<TodoItem
v-for="(todo, index) in todoList"
:key="index"
:todo="todo"
@delete="deleteTodo(index)"
/>
</ul>
</div>
</template>
<style>
#app {
width: 50%;
margin: 0 auto;
}
input {
width: 50%;
padding: 5px;
}
button {
padding: 5px 10px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 5px 0;
}
</style>
示例代码:定义 TodoItem 组件
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
interface Props {
todo: string;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(e: 'delete', index: number): void;
}>();
function deleteTodo(index: number) {
emit('delete', index);
}
</script>
<template>
<li>
{{ props.todo }}
<button @click="deleteTodo">Delete</button>
</li>
</template>
项目部署与上线
-
构建项目
使用 Vue CLI 构建项目:npm run build
这将在
dist
目录下生成静态文件。 -
部署到服务器
将生成的静态文件部署到服务器。常见的部署方式包括使用服务器托管、云服务托管等。 - 域名和 DNS 设置
如果你有自己的域名,可以在 DNS 服务提供商处设置域名解析到服务器 IP 地址。
问题:开发环境运行不正常
- 检查依赖是否安装正确
npm install
- 检查环境配置
确保项目的.env
文件和package.json
中的配置正确。
问题:生产环境构建失败
- 确保所有依赖已安装
npm ci
- 检查构建脚本
确保package.json
中的scripts
配置正确。
问题:Vue3项目性能问题
- 优化代码
使用v-if
或v-show
代替频繁的 DOM 操作。 - 减少 DOM 操作
尽量减少对 DOM 的频繁操作,使用虚拟 DOM 优化。 - 预渲染
使用vue-server-renderer
进行服务端渲染。
问题:TypeScript 报错
- 检查类型定义
确保所有模块和组件都有对应的类型定义文件。 - 更新依赖版本
更新 Vue CLI 和 TypeScript 版本,确保兼容性。
通过以上步骤和示例代码,你可以从零开始搭建一个完整的 Vue3 项目,并将其部署到生产环境。希望这篇教程对你有所帮助!