vue-计算属性computed

388 阅读3分钟

是什么

是组件的一个配置属性-computed,本质是根据已有的数据得到新的数据

意义

为什么不写一个方法去得到要用的值而是通过计算属性?

  • 因为假如方法比较复杂,且多次调用,那么会很耗时,会降低效率。

    image.png

原理

举例说明原理:

<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方法。

  1. 运行getter时,会把依赖数据收集起来,只要依赖数据不变,就会一直使用缓存。 而方法没有缓存,每一次调用都会重新执行;

  2. getter和setter的参数固定。而方法参数是不限的;

    由于有以上这些区别,所以计算属性通常是根据已有数据得到其他数据,并且在得到其他数据的过程中不建议使用异步、当前时间、随机数等副作用操作(副作用操作:对外部造成影响、不可预计的操作)。

    为什么不建议? 因为它只会运行一次。 举例说明:在依赖数据后面加一个时间戳

    get() {
        return this.firstName + this.lastName + Date.now();
    },
    

    image.png

    时间戳并不全是当前时间,因为依赖数据没变,时间戳有缓存。

    那么,时间戳不是依赖项吗? 依赖数据只能是响应式数据,即注入到vue里的数据,这里的时间戳变化,因为不是响应式数据,vue并不会收到通知。

  3. 含义上的区别:计算属性的含义是一个数据,可读取可赋值;方法的含义是一个操作,用来处理一些事情

父组件样式对子组件样式的影响

image.png

image.png 父组件<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>

image.png