##Python项目-Day55-vue-watch-computed-class与style绑定-列表渲染-事件处理-表单输入绑定
-
侦听器watch
当有一些数据改变时,watch会监听到这些数据的改变
<div id="myapp"> <input type="text" v-model="firstName"> <input type="text" v-model="lastName"> <h1 v-text="fullName"></h1> </div> let app =new Vue({ el:'#myapp', data:{ firstName:"abc", lastName:"edf", }, watch:{ firstName:function (newval,oldval) { console.log(newval,oldval) }, lastName:function (newval,oldval) { console.log(newval,oldval) } } //比如说这里会监听到firstName和lastName的变化,第一个参数是新值,第二个参数是旧值
-
计算属性computed
在computed:{}中定义的属性可以直接用,但是不能和data里面的属性重名
<div id="myapp"> <input type="text" v-model="firstName"> <input type="text" v-model="lastName"> <h1 v-text="fullName"></h1> </div> let app =new Vue({ el:'#myapp', data:{ firstName:"abc", lastName:"edf", }, computed:{ fullName:function (val) { return this.firstName+this.lastName; } }}) //这里firstName和lastName发生变化时,fullName都会发生变化
setter和getter
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
computed:{ fullName:{ get:function () { return this.firstName+this.lastName; }, set:function (newval,oldval) { this.firstName=1; this.lastName=2; console.log(this.firstName,this.lastName) } }, } app.fullName=1 当运行app.fullName=1的时,setter会被调用this.firstName和this.lastName会被刷新
-
class与style绑定
在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
-
对象语法
我们可以传给 v-bind:class 一个对象,以动态地切换 class:
例如:实现点击切换背景颜色
<div style="width: 200px;height: 200px" :class="{'background-green':ok}"></div> <button @click="ok=!ok"></button> el:'#myapp', data:{ ok:true, },
-
数组语法
<div :class="[borderClass,backClass]"></div> //或者这样写 //<div :class="['haveBorder',backClass]"></div> data:{ borderClass:'haveBorder', backClass:'background-green' }
-
多重值
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。
-
-
条件渲染
使用v-if可以使元素显示或者不显示
<h1 v-if="!ok">123</h1>
v-else:
<h1 v-if="!ok">123</h1> <h1 v-else>NO</h1> //这时只显示一个
-
在 元素上使用 v-if 条件渲染分组
v-if只能控制本身,如果想要控制一组元素,可以使用再一组元素之外加上div或者template,但是div会被渲染出来,而template不会被渲染出来
<template v-if="ok"> <h1 >123</h1> <h1 >234</h1> <h1 >456</h1> </template>
-
v-else-if
<template v-if="ok==1"> <h1 >123</h1> </template> <template v-if="ok==2"> <h1 >456</h1> </template> <template v-if="ok==3"> <h1 >789</h1> </template>
当ok=2的时候 456 出现
-
用key管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder。
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template> //添加了key属性之后,两个input就会被区分开
-
-
v-show
用于根据条件展示元素的选项是 v-show 指令,类似v-if
<h1 v-show="ok">123</h1>
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
注意,v-show 不支持 元素,也不支持 v-else。
-
v-if和v-show的区别:
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
-
v-if 与 v-for 一起使用
当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,官方不推荐v-if和v-for同时使用。
若想要同时使用:
<template v-for="job in jobs"> <h1 v-text="job.title"></h1> </template>
-
-
列表渲染
用 v-for 指令根据一组数组的选项列表进行渲染。v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。
在 v-for 块中,我们拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引。
<template v-for="(job,index) in jobs"> <h1 v-text="job.title+index"></h1> </template> data:{ jobs:[ {"id":"001","title":"python","salary":8000}, {"id":"001","title":"pytshon","salary":8000}, {"id":"001","title":"pytshon","salary":80}, ] } //结果 python0 pytshon1 pytshon2
-
循环列出json
<template v-for="(value,key) in jobs"> <h1 v-text="value+'---'+key"></h1> </template> <template v-for="key in jobs"> <h1 v-text="key"></h1> </template> jobs:{ "name":"tom", "age":18, "hobby":"eat" } //结果 tom---name 18---age eat---hobby tom 18 eat
-
建议在遍历的时候使用key
<template v-for="(value,key,index) in jobs"> <h1 v-text="value+'---'+key" :key="key+index"></h1> </template>
-
数组更新检测
Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:
push() pop() shift() unshift() splice() sort() reverse()
在控制输入app.jobs.pop(),会发现页面会少一个h1标签
-
注意事项
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
app.jobs[2]="爬虫"
但是下面的变动会被检测到:
app.jobs[2].title="爬虫"
修改长度也不是响应式的:
app.jobs.length=7
可以使用$set来使数组被检测到:
app.$set(app.jobs,2,"爬虫")
-
对象更改检测注意事项
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。例如,对于:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
你可以添加一个新的 age 属性到嵌套的 userProfile 对象:
Vue.set(vm.userProfile, 'age', 27)
你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:
vm.$set(vm.userProfile, 'age', 27)
-
-
显示过滤/排序结果
有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。
<li v-for="n in evenNumbers">{{ n }}</li> data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
-
一段取值范围的 v-for
v-for 也可以取整数。在这种情况下,它将重复多次模板。
<div> <span v-for="n in 10">{{ n }} </span> </div>
-
-
事件处理
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div> var example1 = new Vue({ el: '#example-1', data: { counter: 0 } })
事件处理方法:
<div id="example-2"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div>
方法传值:
<button @click="say('hi')"></button> say:function(msg){ console.log(msg) },
把特殊变量$event传入方法:
<button @click="say('hi',$event)"></button> say:function(msg,event){ console.log(msg,event.target.nodeName)//button },
事件修饰符:
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div>
案件修饰符:
在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<input type="text" v-on:keyup.enter="say()" v-model="txt">
检测用户输入按键:
<input type="text" v-on:keyup="say($event)" v-model="txt"> say:function(event){ console.log(event.key); },
-
表单输入绑定
你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
也就是说:v-model和value同时存在时,v-model起作用
-
复选框
<input type="checkbox" v-model="checkedNames" value="1" id="1"> <label for="1">1</label> <input type="checkbox" v-model="checkedNames" value="2" id="2"> <label for="2">2</label> <input type="checkbox" v-model="checkedNames" value="3" id="3"> <label for="3">3</label> <span v-text="'checkedNames'+checkedNames"></span> checkedNames: []
可以实现添加标签的效果
简单点说:v-model和value,在选中时value会被添加到checkedNames这个数组中,取消时从数组中取下来
-
值绑定
对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):
<!-- 当选中时,`picked` 为字符串 "a" --> <input type="radio" v-model="picked" value="a"> <!-- `toggle` 为 true 或 false --> <input type="checkbox" v-model="toggle"> <!-- 当选中第一个选项时,`selected` 为字符串 "abc" --> <select v-model="selected"> <option value="abc">ABC</option> </select>
-
修饰符
-
.lazy
<input type="text" v-model.lazy="checkedNames">
在输入的时候checkedNames不会变,当鼠标焦点离开输入框之后,checkedNames值会被改变
-
.trim
<input v-model.trim="msg">
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
-
-