Vue computed与watch
阅读数:99 评论数:0
跳转到新版页面分类
html/css/js
正文
一、computed和watch应用场景
1、computed
computed拥有缓存属性,擅长的处理的场景是一个数据受多个数据影响。
2、watch
擅长处理的场景是一个数据影响多个数据,另外可以有异步操作逻辑。
3、如果我们想让最初时候watch就执行,需要使用handler和immediate属性。
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
immediate: true
}
}
4、深度监听
默认情况下,handler只监听对象的引用变化,对于对象内部属性的变化无法监听 ,使用深度监听可以达到这个目的。
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
但这样做会对性能有很大影响,因为修改对象中的属性都会触发监听器的handler,可以改为下面形式
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}
二. Class与Style绑定
操作元素的class列表和内联样式是数据绑定的一个常见需求. 因为它们都是属性, 所以我们可以用v-bind处理它们: 只需要通过表达式计算出字符串结果即可. 不过, 这符串拼接麻烦且易错. 因此, 在将v-bind用于class和style时, Vue.js 做了专门的增强. 表达式结果的类型除了字符串之外, 还可以是对象和数组.
(1) 绑定HTML Class
#对象语法
v-bind:class指令可以与普通的class属性共存.
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
我们也可以在这里绑定一个返回对象的计算属性
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
数组语法
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
(2) 绑定内联样式
#对象语法
v-bind:style的对象语法十分直观, 看着非常像css, 但其实是一个JavaScript对象. css属性名可以用驼峰式或短横线分隔(记得用引号括起来)来命名.
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
三. 条件渲染
(1) 在<template>元素上使用v-if条件渲染分组
因为v-if是一个指令, 所以必须将它添加到一个元素上. 但是如果想切换多个元素, 可以把一个<template>元素当做不可见的包裹元素, 并在上面使用v-if, 最终的渲染结果不包含<template>元素.
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
(2) v-else -if v-else
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
(3) 用key管理可复用的元素
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>
(4) v-show
v-show的元素始终会被渲染并保留在DOM中, v-show只是简单地切换元素的css属性display.
(5)v-if VS v-show
v-if是"真正"的条件渲染, 因为它会确保在切换过程中条件块中的事件监听器和子组件适当被销毁和重建.
一般来说, v-if有更高的切换开销, 而v-show有更高的初始渲染开销.
5. 列表渲染
(1). 用v-for把一个数组对应为一组元素
我们可以用v-for指令基于一个数组来渲染一个列表, v-for指令需要使用item in items形式的特殊语法, 其中items是源数据数组, 而item 则是被迭代的数组元素的别名.
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
你也可以用of代替in作为分隔符.
(2). 维护状态
当Vue正在更新使用v-for渲染的元素列表时, 它默认使用"就地更新"策略, 如果数据项的顺序被改变, Vue将不会移动DOM元素来匹配数据项的顺序, 而是就地更新每个元素, 并且确保它们在每个索引位置正确渲染.
为了给Vue一个提示, 以便它能跟踪每个节点的身份, 从而重用和得新排序现有元素, 你需要为每项提供一个唯一key属性.
(3). 数组更新检测
#变异方法
这些方法会改变原始的数组
push(), pop(), shift(), unshift(), splice(), sort(), reverse()
# 替换数组
这些方法不会改变原始数组, 而总是返回一个新数组.
filter(), concat(), slice()
由于JavaScript的限制, Vue不能检测以下数组的变动:
当你利用索引直接设置一个数组项时, 例如:
vm.items[indexOfItem] = newValue
但是可以用下面方式来实现:
/ Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
当你修改数组的长度时,
vm.items.length = newLength
可以使用splice
vm.items.splice(newLength)
(4). 对象变更检测
由于JavaScript的限制, Vue不能检测对象属性的添加或删除, 对于已经创建的实例, Vue不允许动态添加根级别的响应式属性. 但是, 可以使用Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性.
四. 监听处理
可以用v-on指令监听DOM事件,
(1) 事件修饰符
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>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
(2) 按键修饰符
五. 表单输入绑定
(1) 基本用法
你可以用v-model指令在表单<input> <textarea>及<select>元素上创建双向数据绑定. 它会根据控件类型自动选取正确的方法来更新元素. 但v-model本质上不过是语法糖, 它负责监听用户的输入事件以及更新数据, 并对一些极端的场景进行一些特殊处理.
(2)值绑定
对于单选按钮, 复选框及选择框的选项, v-model绑定的值通常是静态字符串.