1.理解vue中的生命周期函数
2.常用模板语法讲解
3.数据、方法、计算属性和监听器
4.样式绑定语法
5.列表循环渲染
6.时间绑定
7.表单中双向绑定指令的使用
<!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:同步数据的时候,去掉字符串前后的空格