1-事件
1-1 事件处理的基本使用
1 、使用v-on:xxx或@xxx绑定事件,其中xxx是事件名
2、事件的回调需要配置在methods对象中,最终会在vm上;
3、methods中配置的函数不要用箭头函数,否则this指向就不是vm了
4、 methods中配置的函数,都被Vue所管理的函数,this的指向是vm 或组件实例对象
5、 @click="demo"和@click="demo($event)"效果一样,但后者可以传参
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<H1>名称 : {{name}}</H1>
<!-- <button v-on:click="showInfo('淮安', '总理故乡')">点我提示信息</button> -->
<button @click="showInfo('淮安', '总理故乡', $event)">点我提示信息</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
name: 'VUE学习123',
addr: '淮安总理故乡'
}
},
methods: {
showInfo(a , b, c) {
console.log(c);
alert("欢迎来到" + a + b)
}
}
})
</script>
</body>
</html>
1-2 事件修饰符
1、 prevent:阻止默认事件(常用)
2、stop:阻止事件冒泡(常用)
3、once:事件只触发一次(常用)
4、capture:使用事件的捕获模式
5、self:只有event.target是当前操作的元素时才触发事件
6、passive:事件的默认行为立即执行,无需等待事件回调执行完毕
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
<style>
* {
margin-top: 20px;
}
.demo1 {
height: 100px;
background-color: skyblue;
}
.demo2{
height: 100px;
background-color: yellow;
}
.div1 {
background-color: red;
}
.div2 {
background-color: greenyellow;
}
.list {
width: 200px;
height: 200px;
background-color: peru;
overflow: auto;
}
li {
height: 100px;
}
</style>
</head>
<body>
<div id="root">
<H1>名称 : {{name}}</H1>
<!-- 阻止默认事件 常用-->
<a href="http://wwww.baidu.com" @click.prevent="showInfo">点我提示信息</a>
<!-- 阻止事件冒泡 常用-->
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
</br>
<a href="www.baidu.com" @click.stop.prevent="showInfo">先阻止冒泡,再阻止默认事件(阻止a标签跳转)</a>
</div>
<!-- 事件只执行一次 常用-->
<div class="demo2" @click="showInfo">
<button @click.once="showInfo">点我提示信息</button>
</div>
<!--先执行捕获事件-->
<div class="div2" @click.capture="showMsg(2)">
div2
<div class="div1" @click="showMsg(1)">
div1
</div>
</div>
<!-- 只有event.target是当前操作的元素时才触发事件 -->
<div class="div2" @click.self="showMsg(2)">
div2
<div class="div1" @click="showMsg(1)">
div1
</div>
</div>
<!-- 事件的默认行为立即执行,无需等待事件回调执行完毕
比如鼠标wheel 滚事件,只有等方法执行完才会触发滚动,passive则可以先滚动再执行事件-->
<ul @wheel.passive="demo" class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
name: 'VUE学习123'
}
},
methods: {
showInfo(e) {
//阻止事件冒泡
// e.stopPropagation();
alert("欢迎来到得来联盟")
},
showMsg(val) {
console.log(val);
},
demo() {
for (let i = 0; i < 100000; i++) {
console.log('#')
}
console.log('累坏了')
}
},
})
</script>
</body>
</html>
1-3 键盘事件
- keydown:按下按键不用抬起来就触发事件
- keyup:按下按键抬起来才触发事件(常用)
上面代码中通过Enter键按下后抬起触发事件,enter为vue中Enter的别名
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<H1>名称 : {{name}}</H1>
<input type="text" placeholder="按下按键提示" @keyup.enter="showInfo">
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
name: 'VUE学习123'
}
},
methods: {
showInfo(e) {
console.log("打印按键的值",e.key, e.keyCode);
//不如判断不是回车键就不打印输入框的val
// if(e.keyCode != 13){
// return;
// }
console.log("打印输入框的值",e.target.value);
}
},
})
</script>
</body>
</html>
常用的按键别名有总结:
1-
回车=>enter
删除=>delete(捕获“删除”和“退格”键)
退出=>esc
空格=>space
换行=>tab(特殊,必须配合keydown使用)
上=>up
下=>down
左=>left
右=>right2-
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但要注意驼峰命名法的原始key值要转化为短横线命名,例如大小写转换键CapsLock 要写为 caps-lock。
3-
系统修饰键(用法特殊):ctrl、alt、shift、meta(win键),用法如下:
配合keyup使用:按下修饰键的同时再按下其他键,随着释放其他键,事件才被触发
配合kedown使用:正常触发事件
如果只想要修饰键+一个其他键 才能触发事件可以连续写,例如下面这行代码就是只有按下ctrl+y才能触发事件:
@keyup.ctrl.y=“xxx”
2- 计算属性与监视
2-1 计算属性
案例:根据用户输入姓和名来生成全名
1-插值语法实现
表达式太蓉冗长,vue并不推荐
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
全名:(都截取截取前2位)</br>:
<span>{{firstName.slice(0,2)}}-{{secondName.slice(0,2) }}</span>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
firstName: '张',
secondName: '三',
}
},
})
</script>
</body>
</html>
2-调用函数实现
,每次都会调用方法
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
全名:(都截取截取前2位)</br>:
<span>{{fullName()}}</span>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
firstName: '张',
secondName: '三',
}
},
methods: {
fullName() {
console.log('观察函数调用次数');
return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
},
}
})
</script>
</body>
</html>
3-vue提供计算属性 computed 来依赖已定义属性,生成不存在的属性
定义:要用的属性不存在,要通过已有属性计算出来
原理:底层借助了Object.defineproperty方法提供的getterr和setter
get函数什么时候执行?
初次读取时会执行一次
当依赖的数据发生改变时会被再次调用
优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试更方便
备注:
计算属性最终会出现在vm上,直接调用即可
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化
如果计算属性确定不考虑修改,可以使用计算属性的简写形式
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
姓名:(都截取截取前2位)</br>:
<span >{{fullName}}</span>
姓名:(都截取截取前2位)</br>:
<span >{{fullName}}</span>
姓名:(都截取截取前2位)</br>:
<span >{{fullName}}</span>
姓名:(都截取截取前2位)</br>:
<span >{{fullName}}</span>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
firstName: '张',
secondName: '三',
}
},
//计算属性
computed:{
fullName:{
// get被调用的时机
//1-初始化时候,
//2-所依赖的属性发生变化时候
get(){
// 当有人读取fullNmae时候,get就会返回fullNmae的值
console.log('get被调用了');
return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
},
set(val){
//当fullName被修改时
console.log('set', val);
const arr = val.split('-');
this.firstName = arr[0];
this.secondName = arr[1]
}
}
}
})
</script>
</body>
</html>
以上只考虑读取,不考虑修改 的简写
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
姓名:(都截取截取前2位)</br>:
<span >{{fullName}}</span>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
firstName: '张',
secondName: '三',
}
},
computed:{
// fullName:{
// get(){
// console.log('get被调用了');
// return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
// },
// set(val){
// console.log('set', val);
// const arr = val.split('-');
// this.firstName = arr[0];
// this.secondName = arr[1]
// }
// }
//简写 只是考虑读取时候
fullName(){
console.log('get被调用了');
return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
}
}
})
</script>
</body>
</html>
2-2 监视属性
案列 : 点击切换天气按钮,改变文案如图
先点击按钮调用方法,再用用计算属性返回文案
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watth配置
(2).通过vm.$watch监视
=<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}} </h2>
<button @click="changeWeather()">切换天气 </button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
isHot: true
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
isHot: {
//初始化时候让handler调用
immediate: true,
//当值发生改变时候
handler(newval, oldval) {
console.log('ishot新值', newval);
console.log('ishot旧值', oldval);
}
}
}
})
//监视的另外写法
// vm.$watch('isHot', {
// immediate: true,
// handler(newval, oldval) {
// console.log('ishot新值', newval);
// console.log('ishot旧值', oldval);
// }
// })
</script>
</body>
</html>
2-3 深度监视
(1).Vue中的watch默认不监测对象内部值的改变(一层)
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}} </h2>
<button @click="changeWeather()">切换天气 </button>
<hr />
<h3>a的值是:{{numbers.a}}</h3>
<button @click="numbers.a++">点击a+加 </button>
<h3>b的值是:{{numbers.b}}</h3>
<button @click="numbers.b++">点击b+加 </button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
isHot: true,
numbers: {
a: 1,
b: 2
}
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
isHot: {
immediate: true,
handler(newval, oldval) {
console.log('ishot新值', newval);
console.log('ishot旧值', oldval);
}
},
//监视某个属性的变化
'numbers.a': {
handler(newval, oldval) {
console.log('a新值', newval);
console.log('a旧值', oldval);
}
},
//深度监视 numbers里面所有属性变化
numbers:{
deep: true,
handler(newval, oldval) {
console.log('numbers', newval);
console.log('numbers', oldval);
}
}
}
})
</script>
</body>
</html>
以上监视属性也可以简写为以下
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}} </h2>
<button @click="changeWeather()">切换天气 </button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
isHot: true,
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
// 完整写法
// isHot: {
// // immediate: true,
// // deep:true,
// handler(newval, oldval) {
// console.log('ishot新值', newval);
// console.log('ishot旧值', oldval);
// }
// }
//简写
// isHot(newval, oldval) {
// console.log('ishot新值', newval);
// console.log('ishot旧值', oldval);
// }
}
})
//完整写法
// vm.$watch('isHot', {
// handler(newval, oldval) {
// console.log('ishot新值', newval);
// console.log('ishot旧值', oldval);
// }
// })
// 简写
vm.$watch('isHot', function(newval, oldval) {
console.log('ishot新值', newval);
console.log('ishot旧值', oldval);
})
</script>
</body>
</html>
3-计算属性对比监视属性
总结:
computed和watch之间的区别:
computed能完成的功能,watch都可以完成
watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作(如下面例子 异步等待一秒修该姓名)
两个重要的小原则:所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
目标都一个,就是让this指向是vm。
我们按照上面修改姓名为例子对比
<!DOCTYPE html>
<html>
<head>
<mate charset="UTF-8"></mate>
<title> 初识VUE</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- 姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
计算属性实现全名:(都截取截取前2位)</br>:
<span>{{fullName}}</span> -->
姓:<input type="text" v-model="firstName"></br>
名:<input type="text" v-model="secondName"></br>
监视属性实现全名(姓名等一秒改变):</br>:
<span>{{fullName}}</span>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data() {
return {
firstName: '张',
secondName: '三',
fullName: '张-三'
}
},
//计算属性
computed: {
// fullName:{
// get(){
// console.log('get被调用了');
// return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
// },
// set(val){
// console.log('set', val);
// const arr = val.split('-');
// this.firstName = arr[0];
// this.secondName = arr[1]
// }
// }
},
watch: {
firstName(newValue, oldValue) {
// 这边要写成箭头函数, 写成普通函数会指向window
setTimeout(() => {
this.fullName = newValue + '-' + this.secondName;
}, 1000);
},
secondName(newValue, oldValue) {
this.fullName = this.firstName + '-' + newValue;
}
}
})
</script>
</body>
</html>