HsuMoonHao HsuMoonHao
首页
  • 前端文章

    • JavaScript
    • 数据结构与算法
  • vue3相关

    • 《JavaScript教程》
GitHub (opens new window)

HsyMoonHao

前端界的小学生
首页
  • 前端文章

    • JavaScript
    • 数据结构与算法
  • vue3相关

    • 《JavaScript教程》
GitHub (opens new window)
  • 前端-设计模式

  • js数据结构与算法

  • js程序设计

  • vue3相关

    • 01.虚拟Dom与diff算法
    • 计算属性
    • watch 侦听器
    • watchEffect高级侦听器
    • 组件和生命周期
    • bem架构
    • 父子组件传值
    • slot插槽
    • provide和inject
    • v-model
    • 自定义指令
    • 自定义hooks
  • 微前端

  • react

  • 前端
  • vue3相关
HsyMoonHao
2023-05-12

计算属性

# 计算属性

  1. 使用
<template>
	<button @click="changeName">
        change name
    </button>
</template>
<script setup lang="ts">
    import { computed, ref } from "vue"
    let first = ref("zhang")
    let lase = ref("san")
   //  1.选项式写法, 支持一个对象,传入get函数以及set函数自定义操作
    let name = computed({
        get (){
            return first.value +"_"+ last.value
        },
        set (newVal){
			[first.value, last.value] = newVal.split("-")
        }
    })

    const changeName = ()=>{
        name.value = "li-si"
        name2.value = "wangwu" // error: 无法为“value”赋值,因为它是只读属性。
    }
    // 2. 函数式写法,只能支持一个getter函数,不允许修改值
    //!!!
	let name2 = computed(()=>{
        return first.value +"_"+ last.value
    })
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  1. 原理
// 1. 格式化参数:
computed函数中传入的参数式是什么类型
	如果是函数,则在setter中提醒
    如果为对象,则读取对象中的get与set函数;
//2. 将参数传入computedRefImpl函数
	定义了`dirty`用于脏值检测,如果为true则会读取缓存中的值,如果为false则会重新计算
    定义effect, 用于收集依赖获取计算值
	定义value,用于返回计算值
1
2
3
4
5
6
7
8
  1. 源码
// ReactiveEffect(fn, scheduler = null, scope) 
// fn: getter函数,
// scheduler: 调度函数
var _a;
class ComputedRefImpl {
    constructor(getter, _setter, isReadonly, isSSR) {
        this._setter = _setter;
        this.dep = undefined;
        this.__v_isRef = true;
        this[_a] = false;
        this._dirty = true;
        //1.1 第一次进入时不会执行,因为第一次执行完`_dirty`的值为false, 
        //1.2 当计算的值发生变化,则触发scheduler将_dirty改为ture
        this.effect = new ReactiveEffect(getter, () => {
            if (!this._dirty) {
                this._dirty = true;
                triggerRefValue(this);
            }
        });
        this.effect.computed = this;
        this.effect.active = this._cacheable = !isSSR;
        this["__v_isReadonly" /* ReactiveFlags.IS_READONLY */] = isReadonly;
    }
    get value() {
        const self = toRaw(this);
        trackRefValue(self);
        // 1.0 第一次进入后,会将dirty该为false,同时去收集依赖计算值
        if (self._dirty || !self._cacheable) {
            self._dirty = false;
            self._value = self.effect.run();
        }
        return self._value;
    }
    set value(newValue) {
        this._setter(newValue);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
编辑 (opens new window)
#vue3
上次更新: 2023/05/16, 17:34:11
01.虚拟Dom与diff算法
watch 侦听器

← 01.虚拟Dom与diff算法 watch 侦听器→

最近更新
01
Async和Defer
01-03
02
typescript utils
12-23
03
对SPA的理解
05-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 HsyMoonHao | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式