Vue自定义方法
let vm = new Vue({
el:'#app',
data:{
msg:'hello'
},
methods:{
//自定义方法,多个方法之间用逗号分隔
a:function(){
let str = this.msg //获取data中的msg属性
},
b(){
this.msg = 'hello again' //为data中的msg属性重新赋值
}
}
})
注意事项:
-
自定义的方法中,this代表着vue实例对象;
-
自定义的方法不能使用箭头函数;因为箭头函数不会绑定其父级作用域。
Vue事件处理
Vue中的事件通过v-on
指令监听DOM事件,并在触发时执行一些JavaScript代码。
<div id="example-1">
<!--<button v-on:click="counter += 1">Add 1</button>-->
<!--简写形式-->
<button @click="counter += 1">Add 1</button>
<p>上面的按钮被点击了 {{ counter }} 次。</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接调用方法
example2.greet() // => 'Hello Vue.js!'
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
总结:
-
使用v-on:xxx或者@xxx绑定事件,其中xxx是事件名
-
事件的回调需要配置在methods对象中,最终会在绑定在vm上
-
methods中配置的函数,不要用箭头函数,否则this就不是vm了
-
methods中配置的函数,都是被vue所管理的函数,this的指向是vm或者组件实例对象
-
@click="demo"和@click="demo($event)"效果一样,但是后者可以传参
事件修饰符
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
-
prevent:阻止默认行为(常用)
-
stop:阻止事件冒泡(常用)
-
once:事件只触发一次(常用)
-
capture:使用事件的捕获模式
-
self:只有event.target是当前操作的元素才触发事件
-
passive:事件的默认行为立即执行,无需等待事件回调执行完毕,一般使滚动条立即滚动而不等待事件回调执行结束后才滚动。
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 阻止单击事件冒泡 -->
<div @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
</div>
<!-- 点击事件将只会触发一次 -->
<buton v-on:click.once="showInfo">点我提示信息</buton>
<!-- 修饰符可以连续写 -->
<div @click="showInfo">
点我提示信息
<a v-on:click.stop.prevent="showInfo">点我提示信息</a>
</div>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 事件在触发时,默认先进行捕获阶段,再进行冒泡阶段,事件的处理默认是在冒泡阶段。
通过设置capture,使事件在捕获阶段触发
-->
<div v-on:click.capture="showMsg(1)">
div1
<div v-on:click="showMsg(2)">
div2
</div>
</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<div v-on:click.self="showMsg($event)">
div1
<div v-on:click="showMsg($event)">
div2
</div>
</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
-
enter -> 回车键
-
delete -> 删除键(捕获删除和退格)
-
esc -> 退出
-
space -> 空格
-
tab -> 换行(特殊,必须配合keydown使用)
-
up -> 上
-
down -> 下
-
left -> 左
-
right -> 右
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。
<input v-on:keyup.page-down="onPageDown">
在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。
计算属性
计算属性是一个依赖了data中已有的属性;当data中依赖的属性值发生改变时,计算属性的值也对应发生变化。
<!--插值语法表示逻辑的写法,插值语法中支持表达式-->
判断奇偶数: {{number % 2 === 0 ? '偶数' : '奇数'}} <br />
插值语法中也可以调用方法,反转字符串:{{title.split('').reverse().join('') }} <br />
<script>
const vm = new Vue({
data(){
return {
number: 0,
title: 'abc'
}
}
})
</script>
在插值语法中的表达式如果逻辑比较复杂,则增加的代码的阅读成本。
<div id="app">
判断奇偶数: {{numStr}} <br />
插值语法中也可以调用方法,反转字符串:{{reverse}} <br />
</div>
<script>
const vm = new Vue({
data(){
return {
number: 0,
title: 'abc'
}
},
computed:{
// 计算属性要求返回的是一个函数
numStr(){
// 计算属性必须有返回值
return this.number % 2 === 0 ? '偶数' : '奇数'
},
reverse(){
return this.title.split('').reverse().join('')
}
}
})
vm.$mount('#app')
</script>
姓,名联动案例
-
插值语法实现联动
-
自定义函数实现联动
-
计算属性实现联动
理解计算属性的缓存特性。
<div id="app">
姓:<input type="text" v-model="firstName" /> <br />
名:<input type="text" v-model="lastName" /> <br />
全名:<span>???</span>
</div>
new Vue({
el:'#app',
data:{
firstName:'张',
lastName:'三'
},
computed:{
//简写,fullName只有getter
/*fullName: function () {
return this.firstName + ' ' + this.lastName
}*/
//完整写法
fullName:{
/*
get的作用:当fullName属性被读取时,get就会被调用,且函数返回的值就是fullName的值
get的使用:
1.初次读取fullName属性时调用,并将fullName属性值缓存。
2.当fullName属性所依赖的属性发生变化时,从新调用get
*/
get:function(){
console.log('get被调用了');
return this.firstName + ' ' + this.lastName
},
/*
当fullName属性被修改时调用set
*/
set:function(value){
console.log('set被调用了');
let name = value.split('-')
this.firstName = name[0]
this.lastName = name[1]
}
}
}
})
总结:
-
定义:要用的属性不存在,要通过data中的属性计算得来
-
原理:底层借助了Object.defineproperty()提供的getter和setter
-
计算属性get函数什么时候被执行? (1).初次读取计算属性时执行一次 (2).当计算属性依赖的数据发生变化时会被再次调用
-
优势:与methods相比,计算属性内部有缓存机制(属性可重复使用)只有计算属性依赖的数据没有发生变化,则多次调用计算属性的get方法,会直接获取缓存的数据。效率更高,调试更方便。
使用普通方法,则每次调用方法,都需要重复执行函数。
-
计算属性最终会出现在vm对象上,直接读取即可
-
如果计算属性要被修改,则必须写set函数修改,且set中要引起计算时依赖的数据改变。
侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<div id="app">
姓名:<input type="text" v-model="userName" />
</div>
<script>
const vm = new Vue({
data(){
return {
userName: ''
}
},
watch: {
// watch中定义的都是函数,函数名必须和属性名完全一致
userName(newValue, oldValue) { // 改变的值, 老的值
console.log('userName修改后的值:',newValue,' , 修改前的值:',oldValue);
},
// 如果监听的属性是对象中的属性,则需要用''修饰属性
'link.url'(val){
console.log('修改后的url:',val);
}
},
})
vm.$mount('#app')
</script>
computed和watch的区别:
-
computed能完成的事情watch也能完成。
-
watch中可以进行异步操作,而computed不行。
-
所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例。
-
单向数据绑定: 页面中通过{{}}插值语法或者通过v-bind绑定的属性来自于data中声明的属性;当data中属性发生变化时,页面引用属性的地方随之发生改变;
可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model
会忽略所有表单元素的 value
、checked
、selected
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
-
text 和 textarea 元素使用
value
property 和input
事件; -
checkbox 和 radio 使用
checked
property 和change
事件; -
select 字段将
value
作为 prop 并将change
作为事件。