学习Vue3 第九章(认识computed计算属性)
computed用法计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值。1 函数形式import { computed, reactive, ref } from 'vue'let price = ref(0)//$0let m = computed<string>(()=>{return `$` + price.
·
computed用法
计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值。
1 函数形式
import { computed, reactive, ref } from 'vue'
let price = ref(0)//$0
let m = computed<string>(()=>{
return `$` + price.value
})
price.value = 500
2 对象形式
<template>
<div>{{ mul }}</div>
<div @click="mul = 100">click</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
let price = ref<number | string>(1)//$0
let mul = computed({
get: () => {
return price.value
},
set: (value) => {
price.value = 'set' + value
}
})
</script>
<style>
</style>
computed购物车案例
<template>
<div>
<input placeholder="请输入名称" v-model="keyWord" type="text">
<table style="margin-top:10px;" width="500" cellspacing="0" cellpadding="0" border>
<thead>
<tr>
<th>物品</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in searchData">
<td align="center">{{ item.name }}</td>
<td align="center">{{ item.price }}</td>
<td align="center">
<button @click="item.num > 1 ? item.num-- : null">-</button>
<input v-model="item.num" type="number">
<button @click="item.num < 99 ? item.num++ : null">+</button>
</td>
<td align="center">{{ item.price * item.num }}</td>
<td align="center">
<button @click="del(index)">删除</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" align="right">
<span>总价:{{ total }}</span>
</td>
</tr>
</tfoot>
</table>
</div>
</template>
<script setup lang='ts'>
import { reactive, ref,computed } from 'vue'
let keyWord = ref<string>('')
interface Data {
name: string,
price: number,
num: number
}
const data = reactive<Data[]>([
{
name: "小满的绿帽子",
price: 100,
num: 1,
},
{
name: "小满的红衣服",
price: 200,
num: 1,
},
{
name: "小满的黑袜子",
price: 300,
num: 1,
}
])
let searchData = computed(()=>{
return data.filter(item => item.name.includes(keyWord.value))
})
let total = computed(() => {
return data.reduce((prev: number, next: Data) => {
return prev + next.num * next.price
}, 0)
})
const del = (index: number) => {
data.splice(index, 1)
}
</script>
<style scoped lang='less'></style>
手写源码
effect.ts
interface Options {
scheduler?: Function
}
let activeEffect;
export const effect = (fn: Function,options:Options) => {
const _effect = function () {
activeEffect = _effect;
let res= fn()
return res
}
_effect.options = options
_effect()
return _effect
}
const targetMap = new WeakMap()
export const track = (target, key) => {
let depsMap = targetMap.get(target)
if (!depsMap) {
depsMap = new Map()
targetMap.set(target, depsMap)
}
let deps = depsMap.get(key)
if (!deps) {
deps = new Set()
depsMap.set(key, deps)
}
deps.add(activeEffect)
}
export const trigger = (target, key) => {
const depsMap = targetMap.get(target)
const deps = depsMap.get(key)
deps.forEach(effect => {
if(effect?.options?.scheduler){
effect?.options?.scheduler?.()
}else{
effect()
}
})
}
reactive.ts
import { track, trigger } from './effect'
const isObject = (target) => target != null && typeof target == 'object'
export const reactive = <T extends object>(target: T) => {
return new Proxy(target, {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver) as object
track(target, key)
if (isObject(res)) {
return reactive(res)
}
return res
},
set(target, key, value, receiver) {
const res = Reflect.set(target, key, value, receiver)
trigger(target, key)
return res
}
})
}
computed.ts
import { effect } from './effect'
export const computed = (getter: Function) => {
let _value = effect(getter, {
scheduler: () => { _dirty = true }
})
let catchValue
let _dirty = true
class ComputedRefImpl {
get value() {
if (_dirty) {
catchValue = _value()
_dirty = false;
}
return catchValue
}
}
return new ComputedRefImpl()
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import {computed} from './computed.js'
import {reactive} from './reactive.js'
window.a = reactive({name: 'a', age: 18})
window.b = computed(() => {
console.log('重新计算')
return a.age + 10
})
</script>
</body>
</html>
更多推荐
已为社区贡献45条内容
所有评论(0)