目录
[watch(监听器 监听属性)](#watch(监听器 监听属性))
事件机制
概述 在dom阶段,我们已经讲述了事件机制的特点:
事件三要素
事件绑定
事件流
事件对象
事件代理
事件类型 这些概念在vue中依旧存在,但是vue中的事件机制要更加的简单便捷一
事件绑定
可以用 v-on 指令监听DOM 事件,并在触发时运行一些 JavaScript 代码。v-on 还可以接收一个需要调用的方法名称。
<button v-on:click="handler">good</button>
methods: { handler: function (event) { if (event) { alert(event.target.tagName) } //event
是原生 DOM 事件 } } 除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法,通过$
event传递原生事件对象:<button v-on:click="say('hi',$event)">Say hi</button>
methods: { say: function (message,event) { alert(message) } } 由于事件绑定在vue中使用概率较大,所以这里提供了简写形式 <button @click="say('hi',$event)">Say hi</button>
事件参数
在事件调用时,可以进行参数的传递 :
javascript
<div id="app">
<el-button @click="toAdd" type="primary" size="small">新增</el-button>
<div>
<el-table type="index" size="small" :data="tableData" style="width: 50%">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="small" @click="toEdit(scope.row)" type="primary">编辑</el-button>
<el-button size="small" type="danger" @click="toDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog :title="title" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="时间" :label-width="formLabelWidth">
<el-input v-model="form.date" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="姓名" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="地址" :label-width="formLabelWidth">
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: {
dialogFormVisible: false,
formLabelWidth: "120px",
form: {},
title: '',
tableData: [{
id: 1,
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
id: 2,
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
id: 3,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 4,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
},
methods: {
toAdd() {
this.dialogFormVisible = true;
this.form = {};
this.title = '新增数据'
},
toEdit(row) {
this.form = { ...row };
this.dialogFormVisible = true;
this.title = '修改数据';
},
toDelete(id) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.tableData.splice(id,1)
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
}
})
</script>
进行事件绑定时,可以将v-on:事件名 缩写为**@事件名**,此方式经常使用 :
事件修饰符
事件修饰符 在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。Vue提供了更好的方式:事件处理函数只有纯粹的数据逻辑,而不是去处理 DOM 事件细节,通过事件修饰符来完成这些细节。
<button v-on:click.prevent="handler">点我点我</button>
常见修饰符如下 .stop 停止事件冒泡 .prevent 阻止事件默认行为 .capture 在事件捕获阶段执行事件处理函数 .self 只当在 event.target 是当前元素自身时触发处理函数 .once 事件处理函数执行一次后解绑 .passive 滚动事件的默认行为 (即滚动行为) 将会立即触发 ,一般与scroll连用,能够提升移动端的性能 按键修饰符 一般与keyup事件类型配合使用 .enter、.tab、.delete、.esc、.space、.up、.down、.left、.right .ctrl、.alt、.shift、.meta 鼠标修饰符mouseup事件 .left、.right、.middle
javascript
new Vue({
el: "#app",
data: {
msg: '事件修饰符'
},
methods: {
keyupHandle() {
console.log('按下某些特殊键');
},
toJump() {
console.log('跳转');
alert(1);
},
outer(e) {
// e.target是触发事件的源头元素,目标元素
// e.currentTarget 当前执行事件处理程序的元素,当前目标元素
// console.log('outer', e.target, e.currentTarget);
console.log('outer')
for (let i = 0; i < 100; i++) {
console.log(i);
}
},
inner(e) {
// e.stopPropagation();
// console.log('inner', e.target, e.currentTarget);
console.log('inner');
}
}
})
<div id="app">
<!-- <input type="text" @keyup.enter="keyupHandle"> -->
<input type="text" @keyup.13="keyupHandle">
<!-- <input type="text" @mouseup.left="keyupHandle"> -->
{{msg}}
<a @click.prevent="toJump" href="http://www.baidu.com">百度一下</a>
<!-- 点击inner event.target -->
<!-- <div class="outer" @click.self.once="outer"> -->
<!-- <div class="outer" @click.self="outer"> -->
<!-- <div class="outer" @click.capture="outer"> -->
<div class="outer" @scroll.passive="outer">
outer
<div class="inner" @click="inner">
<!-- <div class="inner" @click.stop="inner"> -->
inner
</div>
</div>
</div>
表单
可以用 v-model 指令在表单
<input>
、<textarea>
及<select>
元素上创建双向数据绑定。 它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。使用v-model绑定了值, 那么name属性就可以不用写了。
javascript
<div id="app">
{{msg}}
<br>
{{stu}}
<br>
<!-- 用户名:<input type="text" v-model.lazy="stu.username"> -->
用户名:<input type="text" v-model.trim="stu.username">
<br>
<!-- .number修饰符,可以将采集到的数据转为number类型,然后再存储到数据模型中 -->
年龄:<input type="text" v-model.number="stu.age">
<br>
<!-- 性别 -->
性别:<input type="radio" value="male" v-model="stu.gender">男
<input type="radio" value="female" v-model="stu.gender">女
<br>
<!-- 爱好 -->
爱好:<input type="checkbox" value="basketball" v-model="stu.hobby">篮球
<input type="checkbox" value="swimming" v-model="stu.hobby">游泳
<input type="checkbox" value="dancing" v-model="stu.hobby">跳舞
<br>
<!-- 城市 -->
城市:
<!-- <select multiple v-model="stu.city"> -->
<select v-model="stu.city">
<option value="shanghai">上海</option>
<option value="beijing">北京</option>
<option value="guangzhou">广州</option>
</select>
<br>
<!-- 简介 -->
简介:<textarea v-model="stu.info" cols="30" rows="10"></textarea>
</div>
### js代码
new Vue({
el: '#app',
data: {
msg: 'hello',
stu: {
// 复选框
hobby: []
}
},
methods: {}
})
watch(监听器 监听属性)
当需要在数据变化时执行异步或开销较大的操作时,使用监听器是最有用的
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的 。
javascript
<div id="app">
{{msg}}
<br>
a:<input type="text" v-model.number="a">
<br>
+
<br>
b:<input type="text" v-model.number="b">
<br>
=
<br>
<output>{{total}}</output>
</div>
new Vue({
el: '#app',
data: {
msg: 'hello',
a: 0,
b: 0,
total: 0
},
methods: {},
// 监听 侦听
watch: {
a(newValue, oldValue) {
this.total = this.a + this.b;
},
b(newValue, oldValue) {
this.total = this.b + this.a;
}
}
})
javascript
//深度监听
new Vue({
el: '#app',
data: {
msg: 'hello',
a: 1,
obj: {
name: 'zhangsan',
age: 12
},
},
watch: {
a(newValue, oldValue) {
console.log('a数据发生变化...');
},
/* obj(newValue, oldValue) {
console.log('obj数据发生变化...');
} */
// 深度监听
obj: {
handler(newValue, oldValue) {
console.log('obj数据发生变化...');
},
// 深度监听
deep: true
}
},
methods: {
changeObj() {
// 更改内部数据
this.obj.name = 'lisi';
}
}
})
<div id="app">
{{msg}}
<br>
{{obj}}
<button @click="changeObj">更改obj</button>
</div>
computed(计算属性)
计算属性 有依赖关系的数据
我们希望一个变量是经过某种计算然后输出而不是直接输出的时候可以使用到计算属性 计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。而每次调用函数都会导致函数的重新执行。
javascript
<div id="app">
{{msg}}
<br>
a:<input type="text" v-model.number="a">
<br>
+
<br>
b:<input type="text" v-model.number="b">
<br>
=
<br>
{{total}}
</div>
new Vue({
el: '#app',
data: {
msg: 'hello',
a: 0,
b: 0,
// total: 0
},
// 计算属性
computed: {
total(){
console.log('计算属性');
// return 111
return this.a+this.b
}
},
methods: {}
})
面试题
watch和computed的区别?
computed
- 具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数
2.计算属性计算某一个属性得变化,如果某一个值改变了,计算属性会见监听到进行返回
watch
- 监听值的变化,执行异步操作【axios请求】
'$route.query':{
this.loadArticle()
}
- 无缓存性,只有当当前值发生变化时才会执行/响应