事件处理
我们可以使用 v-on
指令 (通常缩写为 @
符号) 来监听 DOM 事件,并在触发事件时执行一些 JavaScript。用法为 v-on:click="methodName"
或使用快捷方式 @click="methodName"
事件处理器的值可以是:
- 内联事件处理器:事件被触发时执行的内联JavaScript语句(与
onclick
类似) - 方法事件处理器:一个指向组件上定义的方法的属性名或是路径。
内联事件处理器
内联事件处理器通常用于简单场景
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<h3>内联事件处理器</h3>
<button @click="count++">Add</button>
<p>{{ count }}</p>
</template>
方法事件处理器(重)
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
addCount() {
console.log('addCount');
// 读取data中的count值,然后加1,使用this
this.count++;
}
}
}
</script>
<template>
<h3>方法事件处理器</h3>
<button @click="addCount">Add</button>
<p>Count is: {{ count }}</p>
</template>
事件参数
事件参数可以获取event
对象和通过事件传递数据
获取event
对象
<script>
export default {
data() {
return {
names: ['Tom', 'Jerry', 'Mickey'],
}
},
methods: {
getNameHander(name){
console.log(name)
}
}
}
</script>
事件传参
<script>
export default {
data() {
return {
names: ['Tom', 'Jerry', 'Mickey'],
}
},
methods: {
getNameHander(e){
console.log(e)
}
}
}
</script>
<template>
<h3>事件传参</h3>
<p @click="getNameHander(item)" v-for="(item,index) in names" :key="index">{{ item }}</p>
</template>
传递参数过程中获取event
<script>
export default {
data() {
return {
names: ['Tom', 'Jerry', 'Mickey'],
}
},
methods: {
getNameHander(name,e){
console.log(name),
console.log(e)
}
}
}
</script>
<template>
<h3>事件传参</h3>
<p @click="getNameHander(item,$event)" v-for="(item,index) in names" :key="index">{{ item }}</p>
</template>
注意$event
事件修饰符
在处理事件时调用event.preventDefault()
或event.stopPropagation()
是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理DOM事件的细节会更好
为解决这一问题,Vue为v-on
提供了事件修饰符,常用有以下几个:
- .stop 阻止冒泡
- .prevent 阻止默认行为
- .once
- .enter
<script>
export default {
data() {
return {
}
},
methods: {
clickHandle(e) {
// 阻止默认行为
// e.preventDefault()
console.log('clickHandle')
},
clickDiv() {
console.log('clickDiv')
},
ClickP(e) {
// 阻止冒泡
// e.stopPropagation()
console.log('ClickP')
}
}
}
</script>
<template>
<h3>事件修饰符</h3>
<a @click.prevent="clickHandle" href="https://baidu.com">百度一下</a>
<div @click="clickDiv">
<p @click.stop="ClickP">测试冒泡</p>
</div>
</template>
数组变化侦测
<script>
export default {
data() {
return {
names: ['张三', '李四', '王五']
}
},
methods: {
addListHandle() {
//引起UI自动更新
// this.names.push('赵六')
this.names.concat(['赵六']) //不会引起UI自动更新
//可以this.names = this.names.concat(['赵六'])
}
}
}
</script>
<template>
<h3>数组变化侦测</h3>
<button @click="addListHandle">添加数据</button>
<ul>
<li v-for="(item, index) in names" :key="index">
{{item}}
</li>
</ul>
</template>
变更方法
Vue能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换一个数组
变更方法,顾名思义,就是会对调用它们的原数组进行变更。相对地,也有一些不可变(immutable)方法,例如filter()
,concat()
和slice()
,这些都不会更改原数组,而总是返回一个新数组。当遇到的是非变更方法时,我们需要将旧的数组替换为新的。
例子
<script>
export default {
data() {
return {
names: ['张三', '李四', '王五'],
Numbers1: [1, 2, 3, 4, 5],
Numbers2: [6, 7, 8, 9, 10],
}
},
methods: {
addListHandle() {
//引起UI自动更新
// this.names.push('赵六')
this.names = this.names.concat(['赵六']) //不会引起UI自动更新
},
concatHandle() {
this.Numbers1 = this.Numbers1.concat(this.Numbers2)
}
}
}
</script>
<template>
<h3>数组变化侦测</h3>
<button @click="addListHandle">添加数据</button>
<ul>
<li v-for="(item, index) in names" :key="index">
{{item}}
</li>
</ul>
<button @click="concatHandle">合并数组</button>
<h3>数组1</h3>
<p v-for="(item, index) in Numbers1" :key="index">{{item}}</p>
<h3>数组2</h3>
<p v-for="(item, index) in Numbers2" :key="index">{{item}}</p>
</template>
计算属性
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。
<script>
export default {
data() {
return {
itbaizhan: {
name: "百战程序员",
content: ["前端", "后端", "全栈"]
}
}
},
//计算属性
computed: {
itbaizhanContent() {
return this.itbaizhan.content.length > 0 ? 'Yes' : 'No'
}
},
//放函数或者方法
methods: {
itbaizhanContents() {
return this.itbaizhan.content.length > 0 ? 'Yes' : 'No'
}
}
}
</script>
<template>
<h3>计算属性</h3>
<h3>{{ itbaizhan.name }}</h3>
<p>{{ itbaizhanContent }}</p>
<p>{{ itbaizhanContents() }}</p>
</template>
计算属性缓存跟方法的比较
在表达式中调用函数会得到跟计算属性相同的结果
计算属性会有缓存,如果运行5次,使用计算属性只会1次,如果使用方法会运行5次