Vue 3 实例选项语法详解与案例代码
本文将详细介绍 Vue 3 的实例选项语法,包括所有主要的选项,并通过一个完整的案例代码进行演示。每个选项都将附有详细解释和注释,帮助 Vue 3 初学者更好地理解和应用。
一、Vue 3 实例选项概览
Vue 3 的实例选项主要分为以下几类:
-
数据选项(Data Options)
data
props
computed
methods
watch
-
DOM 选项(DOM Options)
el
template
render
renderError
-
生命周期钩子(Lifecycle Hooks)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeUnmount
unmounted
errorCaptured
renderTracked
renderTriggered
-
资源选项(Assets Options)
components
directives
filters
-
组合选项(Composition Options)
setup
-
其他选项(Miscellaneous Options)
mixins
extends
provide
/inject
inheritAttrs
name
delimiters
comments
二、详细选项解释与案例代码
下面将通过一个完整的 Vue 3 应用示例,涵盖上述大部分选项,并附有详细注释。
1. 项目结构
假设我们有一个简单的待办事项(Todo)应用,项目结构如下:
src/
├── components/
│ └── TodoItem.vue
├── App.vue
└── main.js
2. main.js
- 入口文件
// main.js
import { createApp } from 'vue'
import App from './App.vue'
// 创建 Vue 应用实例
const app = createApp(App)
// 全局注册组件(资源选项)
app.component('TodoItem', TodoItem)
// 全局注册指令(资源选项)
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// 挂载应用
app.mount('#app')
解释:
createApp(App)
: 创建 Vue 应用实例,并传入根组件App
。app.component(...)
: 全局注册TodoItem
组件。app.directive(...)
: 全局注册v-focus
指令,用于自动聚焦输入框。app.mount('#app')
: 将应用挂载到页面上的#app
元素。
3. App.vue
- 根组件
<!-- App.vue -->
<template>
<div id="app">
<h1>{{ title }}</h1>
<input
v-focus
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="新增待办事项"
/>
<ul>
<TodoItem
v-for="(todo, index) in todos"
:key="todo.id"
:todo="todo"
@remove="removeTodo(index)"
/>
</ul>
<p>总待办事项数: {{ totalTodos }}</p>
</div>
</template>
<script>
import TodoItem from './components/TodoItem.vue'
export default {
name: 'App', // 组件名称(其他选项)
components: {
TodoItem // 局部注册组件(资源选项)
},
data() { // 数据选项
return {
title: '我的待办事项',
newTodo: '',
todos: []
}
},
computed: { // 计算属性(数据选项)
totalTodos() {
return this.todos.length
}
},
methods: { // 方法(数据选项)
addTodo() {
const trimmedTodo = this.newTodo.trim()
if (trimmedTodo) {
this.todos.push({
id: Date.now(),
text: trimmedTodo
})
this.newTodo = ''
}
},
removeTodo(index) {
this.todos.splice(index, 1)
}
},
watch: { // 侦听器(数据选项)
todos: {
handler(newTodos) {
console.log('Todos changed:', newTodos)
},
deep: true
}
},
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')
},
directives: { // 局部注册指令(资源选项)
focus: {
mounted(el) {
el.focus()
}
}
},
provide() { // 提供/注入(其他选项)
return {
appTitle: this.title
}
}
}
</script>
<style scoped>
#app {
max-width: 600px;
margin: 0 auto;
text-align: center;
}
input {
padding: 8px;
width: 80%;
margin-bottom: 20px;
}
ul {
list-style: none;
padding: 0;
}
li {
margin: 10px 0;
}
</style>
解释:
-
组件名称 (
name
):name: 'App'
: 定义组件名称为App
。
-
局部注册组件 (
components
):components: { TodoItem }
: 局部注册TodoItem
组件。
-
数据 (
data
):data()
: 返回组件的响应式数据,包括title
,newTodo
, 和todos
。
-
计算属性 (
computed
):totalTodos()
: 计算待办事项总数。
-
方法 (
methods
):addTodo()
: 添加新的待办事项。removeTodo(index)
: 移除指定索引的待办事项。
-
侦听器 (
watch
):todos
: 侦听todos
数组的变化,并输出日志。
-
生命周期钩子:
beforeCreate
,created
,beforeMount
,mounted
,beforeUpdate
,updated
,beforeUnmount
,unmounted
: 分别在不同的生命周期阶段输出日志。
-
指令 (
directives
):focus
: 定义一个局部指令,用于自动聚焦输入框。
-
提供/注入 (
provide
):provide()
: 提供appTitle
给子组件使用。
-
模板 (
template
):- 使用
v-focus
指令自动聚焦输入框。 - 使用
v-model
实现双向绑定。 - 使用
v-for
渲染待办事项列表。 - 监听
@keyup.enter
事件,调用addTodo
方法。 - 使用
v-for
和v-bind
传递todo
对象给子组件TodoItem
。 - 监听子组件的
remove
事件,调用removeTodo
方法。
- 使用
-
样式 (
style
):- 使用
scoped
属性,使样式仅作用于当前组件。
- 使用
4. TodoItem.vue
- 子组件
<!-- TodoItem.vue -->
<template>
<li>
<span>{{ todo.text }}</span>
<button @click="remove">删除</button>
</li>
</template>
<script>
export default {
name: 'TodoItem', // 组件名称(其他选项)
props: { // Props(数据选项)
todo: {
type: Object,
required: true
}
},
inject: ['appTitle'], // 提供/注入(其他选项)
methods: { // 方法(数据选项)
remove() {
this.$emit('remove')
}
},
mounted() {
console.log(`TodoItem mounted: ${this.todo.text}, App Title: ${this.appTitle}`)
}
}
</script>
<style scoped>
li {
display: flex;
justify-content: space-between;
align-items: center;
}
button {
padding: 5px 10px;
background-color: #ff4d4d;
border: none;
color: white;
cursor: pointer;
}
button:hover {
background-color: #ff1a1a;
}
</style>
解释:
-
组件名称 (
name
):name: 'TodoItem'
: 定义组件名称为TodoItem
。
-
Props (
props
):todo
: 接收父组件传递的todo
对象,类型为Object
,且为必填。
-
提供/注入 (
inject
):inject: ['appTitle']
: 注入appTitle
属性,用于在子组件中使用。
-
方法 (
methods
):remove()
: 触发remove
事件,通知父组件删除当前待办事项。
-
生命周期钩子:
mounted()
: 在组件挂载后输出日志,显示待办事项文本和 App 标题。
-
模板 (
template
):- 显示待办事项文本。
- 提供一个删除按钮,点击后调用
remove
方法。
-
样式 (
style
):- 使用
scoped
属性,使样式仅作用于当前组件。 - 样式设计为列表项两端对齐,删除按钮为红色。
- 使用
5. 完整示例展示
以下是一个完整的 Vue 3 应用示例,整合了上述所有代码:
main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.component('TodoItem', TodoItem)
app.directive('focus', {
mounted(el) {
el.focus()
}
})
app.mount('#app')
App.vue
<template>
<div id="app">
<h1>{{ title }}</h1>
<input
v-focus
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="新增待办事项"
/>
<ul>
<TodoItem
v-for="(todo, index) in todos"
:key="todo.id"
:todo="todo"
@remove="removeTodo(index)"
/>
</ul>
<p>总待办事项数: {{ totalTodos }}</p>
</div>
</template>
<script>
import TodoItem from './components/TodoItem.vue'
export default {
name: 'App',
components: {
TodoItem
},
data() {
return {
title: '我的待办事项',
newTodo: '',
todos: []
}
},
computed: {
totalTodos() {
return this.todos.length
}
},
methods: {
addTodo() {
const trimmedTodo = this.newTodo.trim()
if (trimmedTodo) {
this.todos.push({
id: Date.now(),
text: trimmedTodo
})
this.newTodo = ''
}
},
removeTodo(index) {
this.todos.splice(index, 1)
}
},
watch: {
todos: {
handler(newTodos) {
console.log('Todos changed:', newTodos)
},
deep: true
}
},
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')
},
directives: {
focus: {
mounted(el) {
el.focus()
}
}
},
provide() {
return {
appTitle: this.title
}
}
}
</script>
<style scoped>
#app {
max-width: 600px;
margin: 0 auto;
text-align: center;
}
input {
padding: 8px;
width: 80%;
margin-bottom: 20px;
}
ul {
list-style: none;
padding: 0;
}
li {
margin: 10px 0;
}
</style>
TodoItem.vue
<template>
<li>
<span>{{ todo.text }}</span>
<button @click="remove">删除</button>
</li>
</template>
<script>
export default {
name: 'TodoItem',
props: {
todo: {
type: Object,
required: true
}
},
inject: ['appTitle'],
methods: {
remove() {
this.$emit('remove')
}
},
mounted() {
console.log(`TodoItem mounted: ${this.todo.text}, App Title: ${this.appTitle}`)
}
}
</script>
<style scoped>
li {
display: flex;
justify-content: space-between;
align-items: center;
}
button {
padding: 5px 10px;
background-color: #ff4d4d;
border: none;
color: white;
cursor: pointer;
}
button:hover {
background-color: #ff1a1a;
}
</style>
6. 运行效果
启动应用后,用户可以:
- 在输入框中输入待办事项,按下回车键或点击“新增”按钮添加待办事项。
- 列表中显示所有待办事项,每个事项旁有一个“删除”按钮,点击后可以删除对应的事项。
- 页面底部显示总待办事项数。
三、总结
通过上述示例,我们全面介绍了 Vue 3 的实例选项语法,包括数据选项、DOM 选项、生命周期钩子、资源选项等。每个选项都在实际代码中得到了应用,并通过注释详细解释了其作用和用法。
希望这份指南能帮助 Vue 3 初学者更好地理解和使用 Vue 3 的实例选项,从而构建功能丰富、结构清晰的 Vue 应用。