Vue.js 入门指南:核心概念与指令详解
Vue.js 基础应用
要开始使用 Vue.js,首先需要引入 Vue 库文件,然后创建 Vue 实例对象:
// Vue 控制的目标区域,数据将填充到此元素内
<div id='app'>{{userName}}</div>
<script>
// 创建 Vue 实例
const app = new Vue({
// el 属性指定当前实例控制的页面区域,接收选择器字符串
el: '#app',
// data 对象包含要渲染到页面的数据
data: {
userName: '李明'
}
})
</script>
Chrome 浏览器中安装 Vue Devtools
在 Chrome 浏览器中安装 Vue Devtools 插件可以方便地调试 Vue 应用。
Vue 指令系统详解
Vue 提供了六大类指令,用于实现不同的功能:
1. 内容渲染指令
这些指令用于渲染 DOM 元素的文本内容:
v-text:将内容渲染到标签内部,但会覆盖原有内容,实际开发中使用较少{{}}:插值表达式(Mustache 语法),开发中最常用的内容渲染方式- 作为内容占位符,不会覆盖原有内容
- 支持 JavaScript 表达式运算和函数调用
- 只能用于内容节点,不能用于属性节点
v-html:可以渲染包含 HTML 标签的内容
<!-- v-text 示例 -->
<div id="app">
<p v-text="userName"></p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
userName: '王华',
gender: '男',
description: '<h4 style="color:blue">欢迎学习 Vue.js</h4>',
number: 5
}
})
</script>
<!-- 插值表达式示例 -->
<p>姓名:{{userName}}</p>
<p>性别:{{gender}}</p>
<div>
3 + 2 的结果是:{{3 + 2}}
</div>
<div>
{{message}}反转后:{{message.split('').reverse().join('')}}
</div>
<div :title="'元素' + number">
这是一个 div
</div>
<!-- v-html 示例 -->
<div v-html="description"></div>
2. 属性绑定指令
v-bind 指令用于动态绑定属性值,可简写为冒号 :
<!-- 插值表达式不能用于属性节点 -->
<!-- v-bind 示例 -->
<input type='text' v-bind:placeholder="hint"/>
<input type='text' :placeholder="hint"/>
<img v-bind:src="imageUrl" alt="图片">
<script>
data: {
hint: '请输入账号',
imageUrl: 'https://example.com/image.jpg'
}
</script>
3. 事件绑定指令
v-on 指令用于为 DOM 元素绑定事件监听,可简写为 @
事件修饰符:
- .prevent:阻止默认行为
- .stop:阻止事件冒泡
- .capture:添加事件监听器时使用 capture 模式
按键修饰符(监听键盘事件):
- .esc:监听 ESC 键
- .enter:监听回车键
$event:Vue 提供的内置变量,代表原生 DOM 事件对象
<!-- v-on 示例 -->
<button v-on:click="increment">增加</button>
<button v-on:click="decrement">减少</button>
<!-- 绑定事件处理函数时可以传递参数 -->
<button v-on:click="increment(1)">增加</button>
<!-- 简写形式 -->
<button @click="increment(1)">
增加
</button>
<script>
const app = new Vue({
data: {
counter: 0
},
// methods 定义事件处理函数
methods: {
increment: function() {
console.log('点击了增加按钮')
},
// 简写形式
increment() {
console.log('点击了增加按钮');
app.counter += 1;
// 使用 this
console.log(app === this);
this.counter += 1;
},
// 减少方法
decrement() {
app.counter -= 1;
this.counter -= 1;
},
// 带参数的增加方法
increment(n) {
this.counter += n;
}
}
})
</script>
<!-- $event 示例 -->
<div id="app">
<p>counter 的值是:{{counter}}</p>
<button @click="changeColor">改变颜色</button>
<!-- 默认事件对象 e 被覆盖,手动传递 $event -->
<button @click="changeColor(1, $event)">改变颜色</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0,
},
methods: {
changeColor(e) {
this.counter += 1;
console.log(e)
// 偶数时改变背景色
if(this.counter % 2 === 0) {
e.target.style.backgroundColor = 'blue'
} else {
e.target.style.backgroundColor = ''
}
},
changeColor(n, e) {
this.counter += n;
// 偶数时改变背景色
if(this.counter % 2 === 0) {
e.target.style.backgroundColor = 'blue'
} else {
e.target.style.backgroundColor = ''
}
}
}
})
</script>
<!-- 事件修饰符示例 -->
<div id="app">
<!-- .prevent 阻止默认行为 -->
<a href="https://example.com" @click.prevent="showAlert">链接</a>
</div>
<!-- .stop 阻止事件冒泡 -->
<div @click="divClick">
<button @click.stop="buttonClick">按钮</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {},
methods: {
showAlert() {
alert('链接被点击,但不会跳转')
},
divClick() {
console.log('div 被点击')
},
buttonClick() {
console.log('按钮被点击,事件不会冒泡到 div')
}
}
})
</script>
<!-- 按键修饰符示例 -->
<div id='app'>
<input type="text" @keyup.esc="clearInput" @keyup.enter="submitForm">
</div>
<script>
const app = new Vue({
el: '#app',
data: {},
methods: {
clearInput(e) {
console.log('触发了清空输入')
e.target.value = ''
},
submitForm(e) {
console.log('触发了提交表单')
// 这里可以添加表单提交逻辑
}
}
})
</script>
4. 双向数据绑定指令
v-model 指令用于实现双向数据绑定,在不操作 DOM 的前提下快速获取表单数据
特点:
- 双向数据绑定:数据源和视图的变化会相互影响
- v-bind 是单向数据绑定:只有数据源变化会影响视图
- 适用于表单元素:input、radio、checkbox、textarea、select
v-model 指令的修饰符:
- .number:自动将输入值转换为数值类型
- .trim:自动去除首尾空格(不处理中间空格)
- .lazy:在 change 事件而非 input 事件时更新数据
<!-- v-model 示例 -->
<div id='app'>
<p>用户名:{{userName}}</p>
<!-- v-model 双向数据绑定 -->
<input type="text" v-model="userName">
<!-- v-bind 单向数据绑定 -->
<input type="text" :value="userName">
</div>
<!-- v-model 不适用于非表单元素 -->
<div v-model="userName"></div>
<select v-model="selectedCity">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<script>
const app = new Vue({
el: '#app',
data: {
userName: '张三',
selectedCity: 'beijing' // 设置默认值
}
})
</script>
<!-- v-model 修饰符示例 -->
<div id='app'>
<input type="text" v-model.number="num1"> +
<input type="text" v-model.number="num2"> =
<span>{{num1 + num2}}</span>
<input type="text" v-model.trim="userName">
<button @click="showUserName">显示用户名</button>
<input type="text" v-model.lazy="userName">
</div>
<script>
const app = new Vue({
el: '#app',
data: {
num1: 0,
num2: 0,
userName: ' 李四 '
},
methods: {
showUserName() {
console.log('用户名是:', this.userName)
alert('用户名是:' + this.userName)
}
}
})
</script>
5. 条件渲染指令
用于控制 DOM 元素的显示与隐藏:
v-if:动态创建或移除元素- 适用于初始不需要显示,且后期显示频率低的元素
v-show:通过设置display: none;来隐藏元素- 适用于需要频繁切换显示状态的元素
v-else-if:与 v-if 配合使用,形成多条件分支
<!-- v-if 与 v-show 示例 -->
<div id='app'>
<p v-if="isVisible">这是由 v-if 控制的元素</p>
<p v-show="isVisible">这是由 v-show 控制的元素</p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
// 当 isVisible 为 true 时显示元素,为 false 时隐藏元素
isVisible: true
}
})
</script>
<!-- v-else-if 示例 -->
<div id="app">
<div v-if="status === 'success'">操作成功</div>
<div v-else-if="status === 'warning'">警告信息</div>
<div v-else-if="status === 'error'">错误信息</div>
<div v-else>未知状态</div>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
status: 'success' // 可以改为 'warning' 或 'error' 测试不同状态
}
})
</script>
6. 列表渲染指令
v-for 指令用于基于数组渲染列表:
基本语法:
- item in items
- items 是要循环的数组
- item 是当前循环项
使用索引:
- (item, index) in items
:key 属性:
- 官方建议:只要使用 v-for 指令,就应该绑定一个 :key 属性
- 尽量使用唯一的 id 作为 key 的值
- key 的值必须是字符串或数字类型
- key 的值不能重复,否则会报错:"Duplicate keys detected"
- 不建议使用索引作为 key 值,因为它可能导致性能问题
<!-- v-for 示例 -->
<div id="app">
<table class="data-table">
<thead>
<tr>
<th>索引</th>
<th>ID</th>
<th>姓名</th>
</tr>
</thead>
<tbody>
<!-- 基本用法 -->
<tr v-for="person in peopleList">
<td>-</td>
<td>{{person.id}}</td>
<td>{{person.name}}</td>
</tr>
<!-- 带索引和 key 的用法 -->
<tr v-for="(person, index) in peopleList"
:title="person.name + ' - ' + index"
:key="person.id">
<td>{{index}}</td>
<td>{{person.id}}</td>
<td>{{person.name}}</td>
</tr>
</tbody>
</table>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
peopleList: [
{id: 101, name: '赵六'},
{id: 102, name: '钱七'},
{id: 103, name: '孙八'},
{id: 104, name: '周九'}
]
}
})
</script>