本文详细介绍了Vue3的核心概念、与Vue2的区别、安装配置、基础语法、响应式原理、生命周期、路由与状态管理,并通过实战项目展示了实际应用。文章涵盖了Vue3的各个方面,帮助开发者全面了解和掌握Vue3的使用。
Vue3简介 Vue3的核心概念Vue3 是 Vue.js 的最新版本,它引入了许多新特性来改善开发体验和性能。Vue3的核心概念包括但不限于:
- 响应式系统:Vue3 使用 Proxy 重写了响应式系统,提供了更强大的功能和更好的性能。
- 组合式API:通过使用
setup
函数和 Composition API,实现了更强大的逻辑复用和更清晰的逻辑组织。 - Teleport:允许组件的内容在DOM 中渲染到任何位置。
- Fragments:允许在单个组件中返回多个根节点。
- Provide 和 Inject:提供了一种更方便的方式在祖孙组件之间传递数据。
- Suspense:允许组件在异步加载时显示一个自定义的占位符。
- TypeScript 支持:Vue3 提供了更好的类型支持,使得开发变得更加安全和易于维护。
Vue3 引入了许多新特性和改进,与 Vue2 相比,主要改进包括:
- 性能提升:Vue3 使用 Proxy 重写响应式系统,并引入了更高效的渲染引擎,从而提升了渲染速度。
- Tree Shaking:Vue3 的代码更小,通过 Tree Shaking 提供了更好的按需加载支持。
- Composition API:提供了更强大的逻辑复用和更清晰的逻辑组织方式。
- 更好的 TypeScript 支持:Vue3 提供了更好的类型支持,使得开发更加安全。
- 更灵活的组件结构:Vue3 允许在单个组件中返回多个根节点,并支持 Teleport 和 Fragments。
- 更完善的响应式系统:Vue3 的响应式系统更强大,支持更复杂的响应式场景。
使用 Vue CLI 快速搭建 Vue3 项目
- 安装 Vue CLI:
npm install -g @vue/cli
- 创建一个新的 Vue3 项目:
vue create my-vue3-app
- 选择 Vue3 版本:
在创建项目时,选择 Vue 3.x 版本或手动选择 Vue 3.x 模板。 - 安装依赖:
cd my-vue3-app npm install
- 运行项目:
npm run serve
这将启动开发服务器,你可以在浏览器中访问
http://localhost:8080
查看你的 Vue3 项目。
Vue3 的模板语法允许在 HTML 中夹带 Vue 的特殊属性来描述视图。Vue3 的模板语法与 Vue2 非常相似,但引入了一些改进。
插值
使用双大括号表示插值:
<div id="app">
{{ message }}
</div>
// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
<!-- App.vue -->
<template>
<div id="app">
{{ message }}
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue3!'
};
}
}
</script>
指令
Vue3 中有许多指令,如 v-if
、v-for
、v-bind
、v-on
等。
<div v-if="visible">Visible</div>
<div v-for="item in items">{{ item }}</div>
<a v-bind:href="url">Link</a>
<button v-on:click="onClick">Click me</button>
// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
<!-- App.vue -->
<template>
<div>
<div v-if="visible">Visible</div>
<div v-for="item in items">{{ item }}</div>
<a v-bind:href="url">Link</a>
<button v-on:click="onClick">Click me</button>
</div>
</template>
<script>
export default {
data() {
return {
visible: true,
items: [1, 2, 3],
url: 'https://www.example.com'
};
},
methods: {
onClick() {
console.log('Button clicked');
}
}
}
</script>
计算属性与方法
计算属性
计算属性是基于它们的依赖缓存的,只有当依赖发生改变时才会重新计算。
<template>
<div>
<p>原始数据: {{ message }}</p>
<p>计算后的数据: {{ reversedMessage }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue3!'
};
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
}
}
</script>
方法
方法是普通的 JavaScript 函数,会在触发时执行,不会缓存。
<template>
<div>
<p>{{ message }}</p>
<p>{{ reversedMessage() }}</p>
<button @click="reverseMessage">Reverse Message</button>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue3!'
};
},
methods: {
reversedMessage() {
return this.message.split('').reverse().join('');
},
reverseMessage() {
this.message = this.message.split('').reverse().join('');
}
}
}
</script>
组件化开发
声明式组件
Vue3 中的组件是自定义的可复用的 Vue 实例,可以像使用 HTML 元素一样在应用中使用。
<!-- Button.vue -->
<template>
<button @click="onClick">Click me</button>
</template>
<script>
export default {
methods: {
onClick() {
this.$emit('click');
}
}
}
</script>
<!-- App.vue -->
<template>
<div>
<Button v-on:click="handleClick">Click me</Button>
</div>
</template>
<script>
import Button from './Button.vue';
export default {
components: {
Button
},
methods: {
handleClick() {
console.log('Button clicked');
}
}
}
</script>
动态组件
可以在运行时根据条件动态切换组件。
<template>
<div>
<button @click="component = 'Button'">Button</button>
<button @click="component = 'Input'">Input</button>
<component :is="component"></component>
</div>
</template>
<script>
import Button from './Button.vue';
import Input from './Input.vue';
export default {
components: {
Button,
Input
},
data() {
return {
component: 'Button'
};
}
}
</script>
Vue3的响应式原理
响应式系统概述
Vue3 的响应式系统是其核心特性之一,它允许 Vue 实例自动侦听数据的变化,并更新视图。Vue3 使用了更现代的 JavaScript 语法,如 Proxy,来实现更高效和更灵活的响应式系统。
Proxy 与 DefineProperty
Vue3 使用 Proxy 代替 Vue2 中的 Object.defineProperty 方法来设置响应式数据。Proxy 可以拦截对对象的任何操作,使 Vue 能够自动追踪数据变化。
const handler = {
get(target, key) {
console.log(`Reading ${key}`);
return target[key];
},
set(target, key, value) {
console.log(`Setting ${key} to ${value}`);
target[key] = value;
}
};
const proxy = new Proxy({}, handler);
proxy.a = 1; // Setting a to 1
console.log(proxy.a); // Reading a
响应式数据的创建
Vue3 中的数据默认情况下是响应式的,但可以使用 ref
和 reactive
来手动创建响应式对象。
import { ref, reactive } from 'vue';
const count = ref(0); // 使用 ref 创建响应式数据
const state = reactive({ count: 0 }); // 使用 reactive 创建响应式数据
Ref与Reactive的使用
Ref
ref
是一个包装器对象,可以用来包装原始值(通常是基本类型),使其能够追踪变化。
import { ref } from 'vue';
const count = ref(0);
function increment() {
count.value++;
}
console.log(count.value); // 0
increment();
console.log(count.value); // 1
Reactive
reactive
可以用来创建一个可监听的对象。
import { reactive } from 'vue';
const state = reactive({ count: 0 });
function increment() {
state.count++;
}
console.log(state.count); // 0
increment();
console.log(state.count); // 1
响应式数据的监听与修改
Vue3 使用 watch
和 computed
来监听数据的变化。
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});
count.value++; // Count changed from 0 to 1
计算属性与方法
计算属性
计算属性是基于它们的依赖缓存的,只有当依赖发生改变时才会重新计算。
import { ref, computed } from 'vue';
const count = ref(0);
const reversedCount = computed(() => {
return count.value.split('').reverse().join('');
});
count.value = '12345';
console.log(reversedCount.value); // 54321
count.value = '56789';
console.log(reversedCount.value); // 98765
方法
方法是普通的 JavaScript 函数,会在触发时执行,不会缓存。
import { ref } from 'vue';
const count = ref('12345');
function reverseCount() {
return count.value.split('').reverse().join('');
}
console.log(reverseCount()); // 54321
count.value = '56789';
console.log(reverseCount()); // 98765
Vue3的生命周期
生命周期钩子的介绍
Vue3 提供了一套完整的生命周期钩子,这些钩子允许你在组件的特定阶段执行自定义逻辑。这些钩子包括:
beforeCreate
:在实例初始化之前,可以在此阶段访问this
,但数据和方法尚未初始化。created
:实例创建完成后,此时数据和方法已初始化,但 DOM 尚未渲染。beforeMount
:组件挂载到 DOM 之前,此时可以访问this.$el
,但 DOM 尚未渲染。mounted
:组件挂载到 DOM 之后,此时 DOM 已渲染,可以访问this.$el
。beforeUpdate
:数据更新时触发,此时新数据尚未渲染,可以访问this.$el
。updated
:数据更新并重新渲染后触发,此时 DOM 已更新。beforeUnmount
:组件卸载之前,此时组件仍然处于 DOM 中。unmounted
:组件完全卸载后触发。实例
<template> <div> <p>{{ message }}</p> </div> </template>
<script>
export default {
data() {
return {
message: 'Hello Vue3!'
};
},
beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
},
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
beforeUnmount() {
console.log('beforeUnmount');
},
unmounted() {
console.log('unmounted');
}
}
</script>
## 生命周期钩子的应用实例
### 使用生命周期钩子进行数据预处理
可以在 `beforeCreate` 或 `created` 钩子中进行数据预处理。
```vue
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
},
beforeCreate() {
console.log('beforeCreate');
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((data) => {
this.message = data.message;
});
},
created() {
console.log('created');
}
};
</script>
使用生命周期钩子进行页面渲染优化
可以在 beforeMount
或 mounted
钩子中进行页面渲染优化,如初始化 DOM 节点。
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
this.$el.style.color = 'red';
}
};
</script>
生命周期钩子的注意事项
- 生命周期钩子仅在组件实例中可用,全局方法如
Vue.prototype
中无法使用。 - 组件卸载时,确保清理任何在
beforeUnmount
中注册的监听器,以避免内存泄漏。 - 访问组件实例时,请确保在正确的生命周期阶段进行访问。
Vue Router 是 Vue.js 的官方路由管理器,它可以实现应用的路由功能。
安装 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;
<!-- App.vue -->
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-view></router-view>
</div>
</template>
<script>
import router from './router';
export default {
name: 'App',
router
};
</script>
<!-- Home.vue -->
<template>
<div>
<h1>Home</h1>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<!-- About.vue -->
<template>
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: 'About'
};
</script>
Vuex的基本概念与安装
Vuex 是 Vue.js 的官方状态管理库,可以用来实现全局状态管理。
安装 Vuex
npm install vuex@next
基本使用示例
import { createStore } from 'vuex';
const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit('increment');
}
},
getters: {
count: state => state.count
}
});
export default store;
在 Vue 项目中使用 Vuex
<!-- App.vue -->
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import store from './store';
export default {
store,
computed: {
...mapState(['count'])
},
methods: {
...mapActions(['increment'])
}
};
</script>
使用Vuex管理全局状态
状态管理示例
// store.js
import { createStore } from 'vuex';
const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit('increment');
}
},
getters: {
count: state => state.count
}
});
export default store;
<!-- App.vue -->
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import store from './store';
export default {
store,
computed: {
...mapState(['count'])
},
methods: {
...mapActions(['increment'])
}
};
</script>
Vue3实战项目
项目需求分析
假设我们正在开发一个简单的待办事项应用。需求如下:
- 用户可以添加新的待办事项。
- 用户可以标记待办事项为已完成。
- 用户可以删除待办事项。
- 应用可以保存和加载待办事项列表。
使用 Vue CLI 创建项目
vue create todo-app
cd todo-app
npm install vue-router vuex
创建项目结构
todo-app/
├── src/
│ ├── main.js
│ ├── App.vue
│ ├── components/
│ │ ├── AddTodo.vue
│ │ ├── TodoList.vue
│ │ ├── TodoItem.vue
│ ├── router/
│ │ ├── index.js
│ ├── store/
│ │ ├── index.js
│ ├── assets/
│ │ ├── logo.png
│ ├── styles/
│ │ ├── App.css
├── package.json
└── README.md
编写组件代码
AddTodo.vue
<template>
<div>
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a new todo">
</div>
</template>
<script>
export default {
data() {
return {
newTodo: ''
};
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.$store.commit('addTodo', this.newTodo);
this.newTodo = '';
}
}
}
};
</script>
TodoList.vue
<template>
<div>
<ul>
<TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" />
</ul>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
components: {
TodoItem
},
computed: {
todos() {
return this.$store.getters.todos;
}
}
};
</script>
TodoItem.vue
<template>
<li :class="{ completed: todo.completed }">
<input type="checkbox" v-model="todo.completed">
<span>{{ todo.text }}</span>
<button @click="removeTodo">Delete</button>
</li>
</template>
<script>
export default {
props: ['todo'],
methods: {
removeTodo() {
this.$store.commit('removeTodo', this.todo.id);
}
}
};
</script>
编写 Vuex Store
// store/index.js
import { createStore } from 'vuex';
const store = createStore({
state: {
todos: []
},
mutations: {
addTodo(state, todo) {
state.todos.push({ id: Date.now(), text: todo, completed: false });
},
removeTodo(state, id) {
state.todos = state.todos.filter(todo => todo.id !== id);
}
},
actions: {
addTodo({ commit }, todo) {
commit('addTodo', todo);
},
removeTodo({ commit }, id) {
commit('removeTodo', id);
}
},
getters: {
todos: state => state.todos
}
});
export default store;
项目调试与部署
调试
- Vue Devtools:使用 Vue Devtools 插件来调试 Vue 应用,可以帮助你查看组件树、状态管理等。
- console.log:通过在代码中添加
console.log
语句来调试应用。 - 断点调试:在开发工具中设置断点来调试代码。
部署
- 构建项目:
npm run build
这将生成
dist
目录,里面包含了构建好的 HTML、CSS 和 JavaScript 文件。 - 部署到服务器:
将dist
目录中的所有文件上传到你的服务器,确保服务器支持静态文件托管。 - 使用 CDN:
如果使用 CDN,将生成的dist
目录中的文件上传到 CDN,并在服务器上配置相应的路径。
通过以上步骤,你可以完成一个简单的待办事项应用的开发、调试和部署。
共同学习,写下你的评论
评论加载中...
作者其他优质文章