Vue 3.0 学习笔记(面向数据编程)(二)
内容目录
第二章 Vue 基础语法
1.理解vue中的生命周期函数
2.常用模板语法讲解
3.数据、方法、计算属性和监听器
4.样式绑定语法
5.列表循环渲染
6.时间绑定
7.表单中双向绑定指令的使用
理解Vue中的生命周期函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 生命周期函数:在某一时刻会自动执行的函数。也叫做 钩子函数 hook
const app = Vue.createApp({
data() {
return {
message: 'hello world'
}
},
// 在实例生成之前自动执行的函数 1
beforeCreate() {
console.log('beforeCreate')
},
// 在实例生成之后自动执行的函数 2
created() {
console.log('created')
},
// 在模板已经被编程为函数之后立即执行的函数 3
// 也可以理解为 在组件内容被渲染到页面之前自动执行的函数
// 如果没有vue中没有template,会取挂载点的innerHTML作为模板
beforeMount() {
console.log(document.getElementById('root').innerHTML)
console.log('beforeMount')
},
// 在组件内容被渲染到页面之后自动执行的函数 4
mounted() {
console.log(document.getElementById('root').innerHTML)
console.log('mounted')
},
// 当data中的数据发生变化时,会立即自动执行的函数 5
// 可以在控制台执行:vm.$data.message = 'hi';
beforeUpdate(){
console.log(document.getElementById('root').innerHTML, 'beforeUpdate')
},
// 当data中的数据发生变化,同时页面完成更新后,即页面重新渲染后,自动执行的函数 6
updated(){
console.log(document.getElementById('root').innerHTML, 'updated')
},
// 当vue应用失效时,自动执行的函数 7
// 可以在控制台中执行: app.unmount();
beforeUnmount(){
console.log(document.getElementById('root').innerHTML, 'beforeunmont')
},
// 当vue应用失效,且dom完全销毁之后,自动执行的函数 8
// vue应用失效 = vue实例销毁 = 将挂载的vue移除
unmounted(){
console.log(document.getElementById('root').innerHTML, 'unmounted')
},
template: '<div>{{message}}</div>'
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.生命周期函数,也叫做钩子(hook)函数,即在某一个时刻会自动执行的函数
生命周期函数目前有四对,也就是8个函数,每对函数发生在一个动作的前后
一、创建实例,create,自动触发:
beforeCreate:在实例生成之前会自动执行的函数
created:在实例生成之后会自动执行的函数
二、加载模板,mount,自动触发:
beforeMount:在组件内容被渲染到页面之前自动执行的函数
mounted:在组件内容被渲染到页面之后自动执行的函数
三、渲染模板,update,需要满足条件触发:
beforeUpdate:在data中的数据发生变化时,会立即自动执行的函数
updated:当data中的数据发生变化,同时页面完成更新后,即页面重新渲染后,自动执行的函数
四、销毁实例=vue应用失效=移除挂载,unmount,需要满足条件触发:
beforeUnmount:vue应用失效之前执行的函数
unmounted:vue应用失效之后执行的函数
2.这四对函数,前两对可以自动触发,updata和unmount对应的两对函数需要条件触发
update,可以在控制台中变更data中的数据,来验证函数的效果,如:vm.$data.message = xxx;
unmount,可以控制台中手动销毁实例,来验证函数的效果,如:app.unmount();
常用模板语法讲解
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 8</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// {{}} 插值表达式
// 插值表达式里面可以写data中return的数据,methods中的方法,JS的表达式,但是不能写JS的语句
// template里面的内容,也可以直接写在body对应的挂载标签下面,等价的
// vue指令
// v-html,插值表达式里面不能转义html标签,用这个v方法,可以将data中的html内容进行转换
// 防止转义,让html真的就是html。比如用富文本编辑器保存的一段文本,肯定有大量的Html标签,为了显示的时候该加粗的加粗,该换行的换行,就加上v-html
// v-bind,简写为 : 数据与组件做绑定需要用,比如disabled 、title
// v-once,数据只渲染一次,之后即使值被改变,页面也不会重新渲染
// v-if, 决定标签是否进行展示
// v-show, 和v-if效果相同,也是决定标签是否展示
// v-on,简写为 @ 事件绑定,对应的方法要写在methods对象中
// v-model,双向绑定
// template中的变量和数据来源于vue应用中的data,方法来源于methods
// 动态属性,在template中,使用[]来表示一个属性,在data中传入一个具体的属性值,可以动态变化属性
// v-bind和v-on都可以用动态属性
// 动态属性和动态事件也可以称为 动态参数
const app = Vue.createApp({
data() {
return {
message: '<strong>hello world</strong>',
disabled: false,
show: false,
name: 'title1',
// name可以作为属性名,使属性更灵活,即 动态属性
event: 'mouseenter',
// event 这里为动态事件,可以随便变更event里面的值,从而变更事件
// 动态属性和动态事件也可以称为 动态参数
}
},
methods: {
handleClick() {
alert("click")
},
handleClick1(e) {
// 阻止默认行为
e.preventDefault();
},
handleClick2(e) {
// 修饰符写法
alert("click")
}
},
template: `
<div v-html="message" v-bind:title="message"></div>
<input v-bind:disabled="disabled"/>
<div>{{'a' + 'b'}}</div>
<div>{{Math.max(1,2)}}</div>
<div v-once>{{message}}</div>
<div v-if='show'>{{message}}</div>
<button v-on:click='handleClick'>提示</button>
<br/>
<div :[name]="message">{{message}}</div>
<div @[event]='handleClick'>动态事件</div>
<hr/>
<form action="https://www.baidu.com" @click="handleClick1">
<button type='submit'>提交</button>
</form>
<hr />
<form action="https://www.baidu.com" @click.prevent="handleClick2">
<button type='submit'>提交</button>
</form>
`
// < div > {{ if(true) { console.log(1) } }}</div > 不能写JS的语句,可以写JS的表达式
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.template里面的内容,也可以直接写在body对应的挂载标签下面,效果是一样的,等价写法
template中的变量和数据来源于vue应用中data中return的数据,方法来源于methods
动态属性,在template中,使用[变量]来表示一个属性,在data中传入对应变量的参数值,可以动态变化属性
v-bind和v-on都可以用动态属性
动态事件,写法与动态属性相同,将想要动态变化的事件用变量表示,然后在data中传入对应变量的值
动态事件和动态属性也可以叫做动态参数
2.{{}} 插值表达式,里面用来存放变量,也可以存放JS表达式,但是不能用JS的语句
3.vue指令
一、v-html,因为插值表达式里面不能转义html标签,会按照字符串的样式输出,用这个v方法,可以将data中的html内容按照html的方式展示,该加粗加粗,该换行换行
二、v-bind,简单写法为 : ,用来将属性与数据进行绑定,比如disabled,title
三、v-on,简单写法为 @ ,用来将事件与标签进行绑定,对应的方法写在methods中
四、v-once,数据只渲染一次,之后即使数据的值被改变,页面也不会重新渲染,避免无效渲染,提高性能
五、v-if,决定标签是否要渲染到页面
六、v-show,和v-if一样,也是决定标签是否要渲染到页面,只不过实现方式不同
七、v-model,组件与数据双向绑定
4.修饰符,可以直接跟在时间或者方法的后面,简化常用代码编写,
prevent 阻止默认事件执行,如在表单中加入此修饰符@click.prevent,点击提交按钮时,就不会跳转到提交的网址
计算属性和侦听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 9</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// data & methods & computed & watcher
// computed 和 methods 都能实现的功能,建议使用computed,因为有缓存
// computed 和 watch 都能实现的功能,建议使用computed,因为更加简洁
// 异步操作的话,可以用watch,如果是同步操作的话,还是computed更好,更简洁。
// 异步操作如 等待等待几秒再执行的函数
// 当返回的数据为根数据,也就是数据在最外层时,vm.$data.message = vm.message
// 可以直接使用 vm.message来改变数据的值
// 可以在插值表达式里面直接用methods里面的方法,如 toUpper
const app = Vue.createApp({
// 当返回的数据为根数据,也就是数据在最外层时,vm.$data.message = vm.message
// 可以直接使用 vm.message来改变数据的值
data() {
return {
message: 'hello world',
count: 2,
price: 5,
newTotal: 10
}
},
// watch,监听器,能够监听数据变化,也能在监听数据变化时,执行函数
// 也可以实现methods中的函数
watch: {
// current是当前渲染的值,prev是上一个值
// 这里监听的是price数据,可以在控制台变更price的值来调试页面如:vm.$data.price = 6;
price(current, prev) {
console.log(current, prev)
this.newTotal = current * this.count
}
// 当price的值变化时,延迟三秒在控制台打印字符
// price(){
// setTimeout(() => {
// console.log('price data changed')
// }, 3000)
// }
},
// computed, 计算属性,返回计算后的数据
// 当计算属性依赖的内容发生变更时,才会重新执行计算
// computed里面有缓存属性,相对于methods会更高效,如果依赖的内容没有变更,是不会重新计算的
// 但是像Date这种时间数据是无法监听的,也是一个弊端,因为Date不依赖其他信息,无法监听
// computed 可以实现methods中的一些计算功能
// computed 和 methods 都能实现的功能,建议使用computed,因为有缓存
computed: {
total() {
return this.count * this.price
},
time() {
return Date.now() + this.count;
}
},
// methods内方法中的this都指向vue实例
methods: {
handleClick() {
console.log('click', this.message)
},
// 如果用箭头函数,指向的是外层实例,在这里,因为外层没有其他的this,指向的为window
handleClick1: () => {
console.log('click', this.message, this)
},
formatString(string) {
return string.toUpperCase();
},
// 只要页面重新渲染,就会重新计算。即使是methods方法中无关的数据发生改变,导致页面渲染,也要重新计算
getTotal() {
return this.count * this.price
},
getTime() {
return Date.now();
}
},
template: `
<div @click="handleClick">未使用箭头函数 {{message}}</div>
<hr/>
<div @click="handleClick1">使用箭头函数 {{message}}</div>
<hr/>
<div @click="handleClick">插值表达式使用methods的方法 {{formatString(message)}}</div>
<hr/>
<div>插值表达式使用js表达式 {{ count * price }}</div>
<hr/>
<div>通过计算属性计算 {{total}}</div>
<hr/>
<div>通过methods方法计算 {{getTotal()}}</div>
<hr/>
<div>通过计算属性计算 {{time}}</div>
<hr/>
<div>通过methods方法计算 {{getTime()}}</div>
<hr />
<div>通过watch监听 {{price}},{{newTotal}}</div>
`
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.data 定义数据,data中return的数据可以被其他模块调用
当数据为最外层的实例时,可以不用写vm.$data.message,直接使用vm.message也行
2.methods 定义方法
一、方法中的this都指向vue实例
二、如果用箭头函数,指向的是外层实例,示例中因为外层没有其他的this,指向的是window
三、只要页面重新渲染,就会重新计算。即使变更的是与methods方法无关的数据,导致页面重新渲染,也会重新计算,可能会造成无效渲染,相对于computed性能较差
3.computed 计算属性,返回计算后的数据
因为computed有缓存属性,只有依赖的内容发生变更时,才会重新计算。相对于methods更高效
弊端:但是像Date这种动态时间数据时无法监听的,无法动态计算时间相关的数据
computed和methods都能实现的功能,建议使用computed,因为有缓存,更高效
computed和watch都能实现的功能,建议使用computed,写法更加简洁
4.watch,监听器,能够监听数据变化,也能在监听数据变化时,执行函数
watch中的两个参数,current(当前渲染的值),prev(上一个值)
样式绑定语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 10</title>
<style>
.red {
color: red;
}
.green {
color: green;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// vue中的行内样式,可以直接在template中直接写style样式,也可以使用在data中定义的数据来控制样式
// 也可以通过注册子组件,来控制样式
// 区分父子组件:主动调用的是父组件,被动调用的是子组件
// 当有多个颜色渲染同一个标签式,后面的颜色会覆盖之前的颜色
const app = Vue.createApp({
data() {
return {
classString: 'red',
// 通过创建对象来控制样式
classObject: { red: true, green: true },
// 通过Array数组来控制样式,数组里面可以放对象
classArray: ['red', 'green', { balck: true }],
// 行内样式也可以用字符串或者对象来渲染
styleString: 'color:yellow',
styleObject: {
color: "orange",
background: 'yellow'
}
}
},
template: `
<div :class='classString'>
Hello, World!!!
<demo class='green'/>
</div>
<hr />
<div :class='classArray'>通过Array数组来控制样式</div>
<hr />
<div :class='classObject'>通过对象来控制样式</div>
<hr />
<div :style="styleString">通过字符串控制行内样式</div>
<hr />
<div :style="styleObject">通过对象控制行内样式</div>
<hr />
<p>当子组件中有多个节点时,且每个节点都没有指定样式,是无法通过父组件中的样式进行样式渲染的,需要指定每个节点的样式</p>
<div :class='classString'>
Hello, World!!!
<test class='green'/>
</div>
`
});
// vue实例的组件,被调用的是子组件
app.component('demo', {
// $attrs.class 子组件的样式用的是父组件的class的值
template: `
<div :class="$attrs.class">one</div>
<div class='green'>single</div>
`
}),
app.component('test',{
// 当子组件中有多个节点时,且每个节点都没有指定样式,是无法通过父组件进行样式渲染的,需要指定每个节点的样式
template:`
<div>one</div>
<div>two</div>
`
})
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.vue中的标签样式和行内样式,可以直接在template中定义,也可以使用data中定义的数据来控制
2.使用data中的不同数据类型控制样式,可以使用字符串,对象,数组来控制样式
数组中也可以放对象
如果数组或者对象中有多个颜色渲染后,后面的颜色会覆盖之前的颜色
3.区分父子组件:主动调用的是父组件,被动调用的是子组件
4.子组件中的样式控制,
如果子组件中只有一个标签,那么可以直接使用父组件的样式
如果子组件中有多个标签,那么需要指定每一个标签的样式
如果子组件想要使用父组件的样式,可以使用$attr.class这种写法
条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 11</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 知识点1:v-if和v-show
// v-if 直接移除dom
// v-show 加了display的style属性
// 知识点2:v-if v-else-if v-else
// 使用的时候,对应的标签要挨在一起,通过data中的true或者false来判断
const app = Vue.createApp({
data() {
return {
show: false,
conditionOne: false,
conditionTwo: true,
show1: true
}
},
template: `
<div v-if="show">Hello, World!!!</div>
<div v-if="conditionOne">if</div>
<div v-else-if="conditionTwo">elseif</div>
<div v-else>else</div>
<div v-show="show">Bye, World!!!</div>
`
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.v-if 通过控制元素在dom上的存在与否来控制展示或者有隐藏,也可以理解为v-if是控制否是插入标签的
2.v-show 通过style的display来控制是否展示,只是加了隐藏的style样式,不会频繁销毁dom
v-if和v-show都是控制组件在页面上是否渲染,只是实现方式不同,频繁使用时建议使用v-show,性能更好一点
3. v-if、v-else-if、v-else三个指令使用时要挨在一起,中间不能分隔
除了v-else,v-if和v-else-if都是通过值是否为true或者false来判断标签是否显示
列表循环渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 12</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 列表循环渲染,列表的数据可以用数组来存储,也可以用对象来存储
// 遍历数组:v-for="(item, index) of list"
// 遍历对象:v-for="(value, key, index) of obj"
// 使用 v-for的时候,尽量加一个 key,能够复用之前没有变化的值,减少重复渲染,
// key一般不用index做值,尽量使用key来绑定唯一的值,这样在页面再次渲染的时候,根据key查询对应的值是否发生变化,如果没有就可以直接复用,不需要重新创建DOM,提高性能
// 变更列表中的元素信息,有几种方法
// 第一种:使用列表的变更函数
// push 在列表的末尾增加元素,尾部新增
// pop 删除列表的最后一个元素,尾部删除
// shift 删除列表的第一个元素,头部删除
// unshift 在列表的开头新增一个元素,头部新增
// splice 替换列表中的部分内容
// sort 对列表进行排序
// reserve 翻转列表中元素的位置
// 第二种:直接替换数组
// 第三种:直接更新数组内容
// list对象的渲染 v-for的优先级比v-if的优先级高,如果标签属性中已经有了v-for,后面再加v-if是不会生效的
// 可以使用template替换div,template可以理解为是一个占位符,不会在页面上进行渲染
const app = Vue.createApp({
data() {
return {
listArray: ['dell', 'lee', 'teacher'],
listObject: {
firstName: 'dell',
lastName: 'lee',
job: 'teacher'
}
}
},
methods: {
handleAddBtnClick() {
// 数组的变更函数 push, pop, shift, unshift, splice, sort, reverse
// this.listArray.push("hello")
// this.listArray.pop()
// this.listArray.shift()
// this.listArray.unshift('hello')
// this.listArray.reverse()
// 直接替换数组
// this.listArray = ['bye', 'world']
// this.listArray = ['bye'].concat(['world'])
// this.listArray = ['bye', 'world'].filter(item => item === 'bye')
// 直接更新数组的内容
this.listArray[1] = 'Hello'
},
handleAddBtnClick1() {
// 直接添加对象的内容,也可以自动的展示出来
this.listObject.age = 100;
this.listObject.sex = 'male'
}
},
template: `
<div>
<div v-for="(item, index) in listArray" :key='index'>
{{item}} -- {{index}}
</div>
</div>
<br />
<button @click='handleAddBtnClick'>新增</button>
<hr />
<div>
<template v-for="(value, key, index) in listObject" :key='index'>
<div v-if="key !== 'lastName'">
{{value}} -- {{key}} -- {{index}}
</div>
</template>
</div>
<button @click='handleAddBtnClick1'>新增</button>
<hr />
<div v-for="(item, index) in 5" :key='index'>{{item}} -- {{index}}</div>
<hr />
<template v-for="(item, index) in listArray" :key='index'>
<div v-if="item !== 'lee'">
{{item}} -- {{index}}
</div>
</template>
`
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.列表循环渲染,列表的数据可以用数组来存储,也可以用对象来存储
遍历数组:v-for="(item, index) of list"
遍历对象:v-for="(value, key, index) of obj"
2.在使用v-for对数组或对象进行遍历时,最好加一个key,能够复用之前没有变化的值,减少重复渲染
key一般不用index做值,尽量使用key来绑定唯一的值,这样在页面再次渲染的时候,
根据key查询对应的值是否发生变化,如果没有就可以直接复用,不用创建新的DOM,从而提高性能
3.变更数组列表中的元素信息,有几种方法:
第一种:使用列表的变更函数,没有改变数组的引用
push:在列表末尾增加元素,尾部新增
pop:删除列表的最后一个元素,尾部删除
shift:删除列表的第一个元素,头部删除
unshift:在列表的开头新增一个元素,头部新增
splice:替换列表中的部分内容
sort:对列表进行排序
reserve:翻转列表中元素的位置
第二种:直接替换数组,改变了数组的引用,以上方代码为例
this.listArray = ['bye', 'world']
this.listArray = ['bye'].concat(['world']) //这里用到了JS的表达式
this.listArray = ['bye', 'world'].filter(item => item === 'bye') //这里加了个过滤条件
第三种:直接更新数组的内容,没有改变数组的引用
this.listArray[1]='Hello'
4.列表对象的渲染,与列表数据的写法类似,需要注意遍历返回的每一项是value。
5.v-for的优先级比v-if的优先级高,如果标签属性中已经有了v-for,后面再加v-if是不会生效的
可以将当前标签替换为<template>标签,然后在标签下再去新增一个子标签,将v-if放在子标签内
v-for和v-if不写在同一个标签里面
6.<template></template> 占位符标签,可以替换<div>标签
<template>标签主要是为了体现语义结构,不会渲染出真实的标签,在开发中更实用一些
具体效果可以打开F12查看页面元素
事件绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 13</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 简单的方法可以直接写在@click后面
// 在template中想使用原生的事件,就要在函数中加上 $对应的原生事件名
// 比如事件绑定,有默认参数event,当方法中传入其他参数后再想获取event时,需要传入$event参数
// 同时使用多个事件时,写在一起用逗号分开,且需要在方法名后面加上括号
// 事件修饰符,
// .stop 阻止事件冒泡
// .self 事件不作用在子标签上,一般嵌套标签时使用
// .prevent 阻止默认行为
// .capture 把事件的运营方式由冒泡改为捕获 也就是从内到外,改成从外到内
// .once 事件绑定只执行一次
// .passive scroll滚动事件使用,提升滚动性能
// 事件修饰符:stop, prevent, capture, self, once, passive
// 按键修饰符:enter, tab, delete, esc, up, down, left, right
// 鼠标修饰符:left, right, middle
// 精确修饰符:exact
// 组织单击事件继续传播
// <a href="#top" @click.stop="doThis" > 单击事件</a >
// 提交事件不再重载页面
// <form @submit.prevent="onSubmit" > 提交事件</form >
// 修饰符可以串联
// <a @click.stop.prevent="doThis" > 单击事件</a >
// 只有修饰符
// <form @submit.prevent> 提交事件</form >
const app = Vue.createApp({
data() {
return {
counter: 0,
}
},
methods: {
// 也可以直接写为 @click="counter += 1"
handleBtnClick(num, event) {
console.log(event)
// console.log(event.target)
this.counter += num
},
handleBtnClick1() {
alert(1);
},
handleBtnClick2() {
alert(2);
},
// 修饰符
handleBtnClick3() {
this.counter += 1;
},
handleDivClick() {
alert('div clicked')
},
// 鼠标修饰符
handleKeyDown() {
console.log('keydown')
},
handleClick() {
console.log('click')
}
},
template: `
<div>
{{counter}}
<button @click='handleBtnClick(2, $event)'>button</button>
<hr />
<p>多个事件</p>
<button @click='handleBtnClick1(), handleBtnClick2()'>button</button>
<hr />
<div @click.self="handleDivClick">
{{counter}}
<button @click.stop="handleBtnClick3">button</button>
</div>
</div>
<hr />
<div>
<input @keydown.enter="handleKeyDown"/>
</div>
<hr />
<div>
<div @click="handleClick">123</div>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.在template中想使用原生的事件,就要在函数的参数中加上: $对应的原生事件
如:@click='handleBtnClick(2, $event)
如果同时使用多个事件,写在一起时用逗号分开,且在方法名后面需要加上括号
如:@click='handleBtnClick1(), handleBtnClick2()
有多个事件时,发生的顺序是冒泡的,即由内向外,一层一层执行
2.事件修饰符,可以理解为是对事件的一些影响
stop 阻止事件冒泡
self 事件只作用在标签本身,不作用在子标签上,一般嵌套标签时使用
prevent 阻止默认行为
capture 把事件的运营方式由冒泡改为捕获 也就是由从内到外,改成从外到内
once 事件绑定只执行一次
passive scroll滚动事件使用,提升滚动性能
3.按键修饰符:enter,tab,delete,esc,up,down,left,right
4.鼠标修饰符:left,right,middle
5.精确修饰符:exact
例如:@click.ctrl,只要是按着ctrl键,或者按着ctrl+其他按键,都能触发事件
@click.ctrl.exact,只有只按着ctrl一个键时,才能触发事件
表单中双向绑定指令的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 14</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// input, textarea, checkbox, radio, select
// 修饰符 lazy, number, trim
// 双向绑定v-model:一方改变,另一方同样改变
// input:写了v-model后,可以不用写value
// textarea:使用双向绑定时,可以写成单标签<textarea v-model="..." />
// checkbox:多选,如果想要获取选中的选项,绑定一个空数组,被选中选项的value值会被添加到绑定的数组中
// radio:单选,可以绑定空字符串,因为单选只能选中一个
// 单选和多选都可以绑定一个bool值,尤其单选作为一个开关时,很有用
// 如果只是想存储true/false的时候,可以给checkbox绑定bool值
// 当想要选中状态下,存储或展示的数据不是true,而是hello,未选中的状态下,存储或展示的数据不是false,而是world,
// 可以使用true-value="hello",false-value="world"
// lazy:失去焦点的时候才同步数据,可以提高性能
// number:同步数据的时候,把字符串转换为数值类型
// trim:同步数据的时候,去掉字符串前后的空格
const app = Vue.createApp({
data() {
return {
message: 'hello',
message1: 'hello',
messageList: [],
messageString: '',
selectValue: [],
options: [{
text: 'A', value: { value: 'A' }
}, {
text: 'B', value: 'B'
}, {
text: 'C', value: 'C'
}]
}
},
template: `
<div>
<p>输入框的双向绑定</p>
{{message}}
<input v-model="message" />
<hr />
<p>文本框的双向绑定</p>
<textarea v-model="message"/>
<hr />
<p>checkbox的多选,绑定了一个空数组列表</p>
{{messageList}}
jack <input type="checkbox" v-model="messageList" value="jack-value"/>
dell <input type="checkbox" v-model="messageList" value="dell-value"/>
lee <input type="checkbox" v-model="messageList" value="lee-value"/>
<hr />
<p>redio的单选,绑定了一个空字符串</p>
{{messageString}}
jack <input type="radio" v-model="messageString" value="jack-value"/>
dell <input type="radio" v-model="messageString" value="dell-value"/>
lee <input type="radio" v-model="messageString" value="lee-value"/>
<hr />
<p>可以多选的下拉列表,绑定了一个空数组列表</p>
{{selectValue}}
<select v-model="selectValue" multiple>
<option disabled value=''>请选择内容</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<hr />
<p>可以多选的下拉列表,v-for遍历了一个对象列表</p>
{{selectValue}}
<select v-model="selectValue" multiple>
<option v-for="item in options" :value="item.value">{{item.text}}</option>
</select>
<hr />
<p>控制了不同选中状态的value值</p>
{{message}}
<input type="checkbox" v-model="message" true-value="hello" false-value="world">
<hr />
<p>失去焦点时才同步数据,可以提高性能</p>
{{message}}
<input v-model.lazy="message" type="number"/>
<hr />
<p>将输入的信息转化为数值类型</p>
{{typeof message1}}
<input v-model.number="message1" type="number"/>
<hr />
<p>去除输入字符串的首尾空格</p>
{{message1}}
<input v-model.trim="message1" />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
知识点整理
1.v-model 双向绑定,一方改变,另一方同样改变
input:写了v-model后,可以不用写value
textarea:使用双向绑定时,可以写成单标签<textarea v-model="..." />
checkbox:多选,如果想要获取选中的选项,绑定一个空数组,被选中选项的value值会被添加到绑定的数组中
redio:单选,可以绑定空字符串,因为单选只能选中一个
单选和多选都可以绑定一个bool值
2.当单选或者多选的选项想要选中状态下,存储在data中的数据或者页面展示的数据不是true,而是hello
可以使用true-value="hello",未选中的状态下可以使用false-value
3.v-model的修饰符
lazy:失去焦点的时候才同步数据,可以提高性能
number:同步数据的时候,把字符串转换为数值类型
trim:同步数据的时候,去掉字符串前后的空格