第2章 Vue.js基础语法
第3节:Vue实例与模板语法
Vue.js的核心是创建Vue实例,通过实例来管理数据和DOM。在本节中,我们将学习Vue实例的创建与配置,以及模板语法的使用。
2.3.1 Vue应用实例创建与配置
Vue 3中,我们使用createApp函数来创建Vue应用实例。一个Vue应用由一个通过createApp函数创建的根实例,以及可选的嵌套组件树组成。
选项式API创建Vue实例
// main.js
import { createApp } from 'vue'
import App from './App.vue'
// 创建Vue应用实例
const app = createApp({
// 数据选项
data() {
return {
message: 'Hello Vue!',
count: 0
}
},
// 方法选项
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
},
increment() {
this.count++
}
},
// 计算属性
computed: {
doubleCount() {
return this.count * 2
}
},
// 生命周期钩子
mounted() {
console.log('Vue实例已挂载')
}
})
// 挂载应用到DOM
app.mount('#app')应用配置选项
Vue应用实例提供了一些配置选项,用于自定义应用的行为:
const app = createApp({
/* 根组件选项 */
})
// 配置全局属性
app.config.globalProperties.$api = axios
app.config.globalProperties.$formatDate = formatDate
// 配置错误处理
app.config.errorHandler = (err, vm, info) => {
console.error('Vue错误:', err)
console.error('组件:', vm)
console.error('错误信息:', info)
}
// 配置警告处理
app.config.warnHandler = (msg, vm, trace) => {
console.warn('Vue警告:', msg)
console.warn('组件:', vm)
console.warn('调用栈:', trace)
}
// 挂载应用
app.mount('#app')2.3.2 模板插值语法深度解析
Vue的模板语法允许我们将数据绑定到DOM中,主要有以下几种插值方式:
1. 文本插值:{{ }}
最基本的数据绑定形式是文本插值,使用双大括号:
<template>
<h1>{{ message }}</h1>
<p>{{ count }}</p>
<p>{{ count + 1 }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
</template>2. 原始HTML:v-html指令
如果需要输出原始HTML,可以使用v-html指令:
<template>
<div v-html="rawHtml"></div>
</template>
<script>
export default {
data() {
return {
rawHtml: '<h2 style="color: red;">这是红色的标题</h2>'
}
}
}
</script>注意:使用v-html可能会导致XSS攻击,只在可信内容上使用,不要在用户提供的内容上使用。
3. JavaScript表达式使用
在插值中,我们可以使用JavaScript表达式:
<template>
<!-- 算术运算 -->
<p>{{ count + 1 }}</p>
<p>{{ count * 2 }}</p>
<!-- 字符串操作 -->
<p>{{ message.toUpperCase() }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
<!-- 三元表达式 -->
<p>{{ count > 0 ? '正数' : '零' }}</p>
<!-- 数组操作 -->
<p>{{ [1, 2, 3].map(item => item * 2) }}</p>
<!-- 对象操作 -->
<p>{{ { name: 'Vue', version: 3 }.name }}</p>
</template>注意:模板插值只能包含单个表达式,不能包含语句或流控制结构。
2.3.3 指令系统入门
指令是带有v-前缀的特殊属性,用于在表达式的值改变时,将某些行为应用到DOM上。
1. v-bind绑定属性
用于动态绑定HTML属性:
<template>
<!-- 绑定元素属性 -->
<img v-bind:src="imageUrl" alt="Vue logo">
<a v-bind:href="linkUrl">Vue官网</a>
<!-- 简写形式 -->
<img :src="imageUrl" alt="Vue logo">
<a :href="linkUrl">Vue官网</a>
<!-- 绑定CSS类 -->
<div :class="{ active: isActive, 'text-danger': hasError }">状态</div>
<div :class="[activeClass, errorClass]">状态</div>
<!-- 绑定内联样式 -->
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">样式绑定</div>
<div :style="styleObject">样式对象绑定</div>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://vuejs.org/images/logo.png',
linkUrl: 'https://vuejs.org/',
isActive: true,
hasError: false,
activeClass: 'active',
errorClass: 'text-danger',
textColor: 'red',
fontSize: 18,
styleObject: {
color: 'blue',
fontSize: '20px'
}
}
}
}
</script>2. v-on监听事件
用于监听DOM事件:
<template>
<!-- 监听点击事件 -->
<button v-on:click="increment">点击增加</button>
<!-- 简写形式 -->
<button @click="increment">点击增加</button>
<!-- 传递参数 -->
<button @click="add(5)">增加5</button>
<!-- 访问事件对象 -->
<button @click="handleClick">点击事件</button>
<!-- 使用事件修饰符 -->
<button @click.stop="handleClick">阻止冒泡</button>
<form @submit.prevent="handleSubmit">提交表单</form>
<a @click.prevent href="https://vuejs.org/">阻止默认跳转</a>
<!-- 键修饰符 -->
<input @keyup.enter="submitForm" placeholder="按回车提交">
<input @keyup.esc="clearInput" placeholder="按ESC清空">
<!-- 系统修饰符 -->
<button @click.ctrl="ctrlClick">按住Ctrl点击</button>
<button @click.alt="altClick">按住Alt点击</button>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
},
add(amount) {
this.count += amount
},
handleClick(event) {
console.log('事件对象:', event)
console.log('当前元素:', event.target)
},
handleSubmit() {
console.log('表单提交')
},
submitForm() {
console.log('表单提交')
},
clearInput() {
console.log('清空输入')
},
ctrlClick() {
console.log('Ctrl+点击')
},
altClick() {
console.log('Alt+点击')
}
}
}
</script>3. v-model双向绑定
用于在表单元素上创建双向数据绑定:
<template>
<!-- 文本输入 -->
<input v-model="message" type="text" placeholder="输入消息">
<p>消息:{{ message }}</p>
<!-- 多行文本 -->
<textarea v-model="content" rows="4"></textarea>
<!-- 复选框 -->
<input v-model="checked" type="checkbox">
<p>是否选中:{{ checked }}</p>
<!-- 多个复选框绑定到数组 -->
<input v-model="checkedFruits" type="checkbox" value="apple"> 苹果
<input v-model="checkedFruits" type="checkbox" value="banana"> 香蕉
<input v-model="checkedFruits" type="checkbox" value="orange"> 橙子
<p>选中的水果:{{ checkedFruits }}</p>
<!-- 单选按钮 -->
<input v-model="picked" type="radio" value="A"> 选项A
<input v-model="picked" type="radio" value="B"> 选项B
<p>选中的选项:{{ picked }}</p>
<!-- 下拉选择 -->
<select v-model="selected">
<option value="">请选择</option>
<option value="vue">Vue.js</option>
<option value="react">React</option>
<option value="angular">Angular</option>
</select>
<p>选中的框架:{{ selected }}</p>
<!-- 多选下拉 -->
<select v-model="selectedFrameworks" multiple>
<option value="vue">Vue.js</option>
<option value="react">React</option>
<option value="angular">Angular</option>
</select>
<p>选中的框架:{{ selectedFrameworks }}</p>
</template>
<script>
export default {
data() {
return {
message: '',
content: '',
checked: false,
checkedFruits: [],
picked: '',
selected: '',
selectedFrameworks: []
}
}
}
</script>2.3.4 计算属性与侦听器
计算属性
计算属性是基于它们的依赖进行缓存的,只有在依赖发生变化时才会重新计算。这使得计算属性比方法更高效,尤其是在依赖不变的情况下。
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
// 计算属性的getter
fullName() {
return this.firstName + ' ' + this.lastName
},
// 可写的计算属性
fullNameWithSetter: {
get() {
return this.firstName + ' ' + this.lastName
},
set(newValue) {
const parts = newValue.split(' ')
this.firstName = parts[0]
this.lastName = parts[1] || ''
}
}
},
methods: {
// 方法,每次调用都会重新计算
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
}计算属性 vs 方法
| 特性 | 计算属性 | 方法 |
|---|---|---|
| 缓存 | 有,依赖变化才重新计算 | 无,每次调用都重新计算 |
| 调用方式 | 直接作为属性使用:{{ fullName }} |
作为方法调用:{{ getFullName() }} |
| 适用场景 | 基于现有数据派生新数据 | 需要传入参数或执行复杂逻辑 |
侦听器
侦听器用于观察和响应数据的变化,可以执行异步操作或复杂逻辑。
export default {
data() {
return {
question: '',
answer: '请输入问题',
user: {
name: '',
age: 0
}
}
},
watch: {
// 基本侦听
question(newQuestion, oldQuestion) {
if (newQuestion.includes('?')) {
this.getAnswer()
}
},
// 深层侦听对象
user: {
handler(newUser, oldUser) {
console.log('用户信息变化:', newUser)
},
deep: true, // 深层侦听
immediate: true // 立即执行
},
// 侦听对象的单个属性
'user.name'(newName, oldName) {
console.log('用户名变化:', oldName, '->', newName)
}
},
methods: {
async getAnswer() {
this.answer = '思考中...'
try {
// 模拟异步请求
await new Promise(resolve => setTimeout(resolve, 1000))
this.answer = '这是一个答案'
} catch (error) {
this.answer = '请求失败'
}
}
}
}本章小结
在本节中,我们学习了Vue实例与模板语法的核心内容:
- Vue应用实例创建与配置
- 模板插值语法深度解析
- 文本插值:
{{ }} - 原始HTML:
v-html指令 - JavaScript表达式使用
- 文本插值:
- 指令系统入门
v-bind绑定属性v-on监听事件v-model双向绑定
- 计算属性与侦听器
- 计算属性的定义与使用
- 计算属性vs方法
- 侦听器的使用场景
掌握这些基础内容是学习Vue.js的关键,它们将帮助我们构建更复杂的Vue应用。