是什么
是组件的一个配置属性-computed,本质是根据已有的数据得到新的数据
意义
为什么不写一个方法去得到要用的值而是通过计算属性?
-
因为假如方法比较复杂,且多次调用,那么会很耗时,会降低效率。
原理
举例说明原理:
<p>姓:{{firstName}}</p>
<p>名:{{lastName}}</p>
<p>全名:{{fullName}}</p>
data(){
return {
firstName:'袁',
lastName:'进'
}
},
computed:{
fullName(){
return this.firstName + this.lastName
}
}
计算属性就是多了一个缓存,当我们使用数据(模版中的fullName)的时候,本质上是调用这个方法(fullName),得到一个结果。在调用这个方法(fullName)的过程中,vue会做一件事,记录这个依赖,即这个方法依赖的数据(firstName、lastName),只要这个数据(firstName、lastName)不变,这个方法(fullName)就没有必要重新计算。
完整写法
<p>姓:{{firstName}}</p>
<p>名:{{lastName}}</p>
<p>全名:{{fullName}}</p>
<button @click="fullName='张三'">修改姓名为张三</button>
computed: {
fullName: {
get() {
console.log("fullName called")
return this.firstName + this.lastName;
},
set(val){
console.log("正在设置全名" + value);
}
},
},
提问:
点击修改姓名的按钮时,要不要重新调用get()?(即:运行fullName='张三'的时候,最终的结果会不会导致重新运行get)
回答:
看要不要重新调用get,要看它依赖的数据有没有变。若数据没有变,则不重新调用,若数据变化,则重新调用。
运行fullName='张三',实际上是调用set函数,set函数里没有改动它的依赖(即,没有改动firstName和lastName),没有改动数据就不会重新渲染虚拟dom,就不会重新运行get。
那么,什么情况下会重新调用get?
依赖数据改变,举例说明:
computed: {
fullName: {
get() {
console.log("fullName called");
return this.firstName + this.lastName;
},
set(val) {
console.log("正在设置全名" + val);
this.firstName = val[0];
this.lastName = val.substr(1);
},
},
},
99%的情况只会用到get,不会用到set。
面试题:计算属性和方法有什么区别?
计算属性本质上是包含getter和setter方法。
-
运行getter时,会把依赖数据收集起来,只要依赖数据不变,就会一直使用缓存。 而方法没有缓存,每一次调用都会重新执行;
-
getter和setter的参数固定。而方法参数是不限的;
由于有以上这些区别,所以计算属性通常是根据已有数据得到其他数据,并且在得到其他数据的过程中不建议使用异步、当前时间、随机数等副作用操作(副作用操作:对外部造成影响、不可预计的操作)。
为什么不建议? 因为它只会运行一次。 举例说明:在依赖数据后面加一个时间戳
get() { return this.firstName + this.lastName + Date.now(); },时间戳并不全是当前时间,因为依赖数据没变,时间戳有缓存。
那么,时间戳不是依赖项吗? 依赖数据只能是响应式数据,即注入到vue里的数据,这里的时间戳变化,因为不是响应式数据,vue并不会收到通知。
-
含义上的区别:计算属性的含义是一个数据,可读取可赋值;方法的含义是一个操作,用来处理一些事情
父组件样式对子组件样式的影响
父组件
<style scoped></style>里的样式最多会影响子组件最外层的样式
应用场景:如果需要子组件去适应父组件的样式,可以在父组件的style里定义子组件的样式
举例说明:在父组件定义子组件的样式,只能影响子组件最外层的样式
// 父组件
<template>
<div>
<h1>APP组件</h1>
<Icon type="phoenix_icon_wechat-fill"/>
</div>
</template>
<script>
// 引入图标组件
import Icon from './components/Icon'
export default {
components:{
Icon
}
};
</script>
<style scoped>
.phoenix_icon{color:green;font-size:40px;}
</style>
// 子组件
<template>
<i class="phoenix_icon" :class="type"></i>
</template>
<script>
export default {
props:{
type:{
type:String,
required:true
}
}
}
</script>
<style scoped>
/* 引入css */
@import url('//at.alicdn.com/t/font_1242919_4rtvy7ph1ky.css');
</style>