【Vue全家桶】Options API
文章目录
一、data
data属性是传入一个函数,并且该函数需要返回一个对象:
- 在Vue2的时候,也可以传入一个对象(虽然官方推荐是一个函数);
- 在Vue3的时候,必须传入一个函数,否则就会直接在浏览器中报错;
- data中返回的对象会被Vue的响应式系统劫持,之后对该对象的修改或者访问都会在劫持中被处理:
二、methods
methods属性是一个对象,通常我们会在这个对象中定义很多的方法:
-
这些方法可以被绑定到模板中;
-
在该方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性;
-
声明的方法可以直接通过组件实例访问,或者在模板语法表达式中使用。所有的方法都会将它们的
this
上下文自动绑定为组件实例,即使在传递时也如此。在声明方法时避免使用箭头函数,因为它们不能通过
this
访问组件实例。
为什么不能使用箭头函数?
- 理由是箭头函数绑定了父级作用域的上下文,所以
this
将不会按照期望指向组件实例- 箭头函数使用this的查找规则,它会在自己的上层作用于中来查找this
- 最终刚好找到的是script作用于中的this,所以就是window
- 而
this
不可以是window,因为window中我们无法获取到data返回对象中的数据
三、计算属性
推荐使用计算属性来描述依赖响应式状态的复杂逻辑。
3.1 computed基本用法
详细信息:
计算属性的用法:
- 选项:computed
- 类型:{[key:string]:funcition|(get:funcition,set function)}
- 计算属性是有缓存机制的,当我们多次使用计算属性时,计算属性中的运算只会执行一次,只有当计算属性所依赖的数据发生改变时才会重新执行计算属性
举个栗子:逆序输出单词
<div id="example">
<p>Original message: "{
{ message }}"</p>
<p>Computed reversed message: "{
{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello world'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
return this.message.split(' ').reverse().join(' ')
}
}
})
3.2 Computed与methods的区别
- 我们可以将同一函数定义为一个方法而不是一个计算属性。
- 两种方式的最终结果确实是完全相同的。
- 然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
- 这就意味着只要
message
还没有发生改变,多次访问reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。 - 相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
- 我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
四、侦听属性
4.1 watch的基本用法
什么是侦听器呢?
- 开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中;
- 当数据变化时,template会自动进行更新来显示最新的数据;
- 但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器watch来完成了;
侦听器的用法如下:
- 选项:watch
- 类型:{ [key: string]: string | Function | Object | Array}
watch
默认是浅层的:被侦听的属性,仅在被赋新值时,才会触发回调函数——而嵌套属性的变化不会触发(只会针对监听的数据本身的变化(内部发生的改变是不能侦听的))
4.2 即时回调的侦听器
watch
默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。
我们可以用一个对象来声明侦听器,这个对象有 handler
方法和 immediate: true
选项,这样便能强制回调函数立即执行:
watch: {
question: {
handler(newQuestion) {
// 在组件实例创建时会立即调用
},
// 强制立即执行回调
immediate: true
}
}
4.3 深度监听
watch
默认是浅层的:被侦听的属性,仅在被赋新值时,才会触发回调函数——而嵌套属性的变化不会触发。如果想侦听所有嵌套的变更,你需要深层侦听器:
watch: {
someObject: {
handler(newValue, oldValue) {
// 注意:在嵌套的变更中,
// 只要没有替换对象本身,
// 那么这里的 `newValue` 和 `oldValue` 相同
},
deep: true
}
}
4.4 Computed 和 Watch 的区别
对于Computed:
- 它支持缓存,只有依赖的数据发生了变化,才会重新计算
- 不支持异步,当Computed中有异步操作时,无法监听数据的变化
- computed的值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data声明过,或者父组件传递过来的props中的数据进行计算的。
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,一般会使用computed
- 如果computed属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法。
对于Watch:
- 它不支持缓存,数据变化时,它就会触发相应的操作
- 支持异步监听
- 监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
- 当一个属性发生变化时,就需要执行相应的操作
- 监听数据必须是data中声明的或者父组件传递过来的props中的数据,当发生变化时,会触发其他操作,函数有两个的参数:
- immediate:组件加载立即触发回调函数
- deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化。
当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用watch。
总结:
- computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。
- watch 侦听器 : 更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
运用场景:
- 当需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。
- 当需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许执行异步操作 ( 访问一个 API ),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
五、components
一个对象,用于注册对当前组件实例可用的组件。
export default {
components: {
TabControl }
}