() => ()是什么?
对于一个没有JS基础的人来说,这个函数结构一眼看上去是懵的,这个和C、matlab、python的函数结构体是完全不同的。
- getter
js
const 变量名 = computed(() => {
// 这里就是 Getter 函数体
return 计算结果
})
//
() => ()
-- -- ---
入参 后跟函数体 函数体
js
// JS 代码
import { ref, computed } from 'vue'
const price = ref(100) // 原价
const isMember = ref(true) // 是否会员
// total 就是计算属性,括号里的箭头函数就是 Getter
const total = computed(() => {
return isMember.value ? price.value * 0.8 : price.value
})
- "满屏的箭头"
箭头函数对我来说是最难理解的,但是我们可以用python中的匿名函数lambda来理解。
| 语言 | 语法结构 | 拆解含义 |
|---|---|---|
| JS (箭头函数), | () => x + y,() 代表参数为空, | => 指向函数体,后面是返回值。 |
| Python (lambda), | lambda: x + y,lambda 是关键字, | : 后面是表达式。 |
- 为什么有两个括号?
第一个括号 ():是函数的**"入口"(参数列表)。如果不需要参数,就写个空括号;如果有一个参数 x,就写 (x)。
第二个括号(或表达式):是函数的"执行逻辑"**。
针对第一个括号,我们可以将其分为有入参的函数和无入参的函数(计算属性,一般不需要根据变量实时计算的),针对第二个括号,我们可以将其分为简单函数和复杂函数。简单函数一般来说就像lambda一样,一行代码就能计算完了,这个我们使用()或者不带括号都行,对于有几行表达式的函数体来说,就要使用{}进行包裹起来了,不过要记得{}中应该加上return关键字作为返回值。典型结构为:
js
[x, () => y.value],
([newX, newY]) => { ...return xxx }
注意后面的{}如果有多行可以用()进行包裹,以便告诉编译器,这是一个横跨多行的对象,而避免编译器解释错误。() => ({ }),另外需要注意一点的是,js中的数据的结构体和函数体都使用的{},所以平时还是最好用()包裹一下,告诉编译器括号内的东西要解释成字面量。
如果是作为函数体来进行的,那么就是直接() => { ...return xxx }这个模式就好了。
| 语法结构, | JS 引擎的理解, | 返回值 |
|---|---|---|
| () => 5, | 返回数字 5, | 5 |
| () =>() | 想在()中写多行代码 | 达咩,语法不支持,要转到{} |
| () => { return 5 }, | 执行代码块,手动返回 5, | 5 |
| () => { a: 1 }, | 误以为是代码块,报错或运行失败, | undefined |
| () => ({ a: 1 }), | 明确知道是返回一个对象, | { a: 1 } |
| 语法结构, | 属于什么, | 自动返回?, | 适用场景 |
|---|---|---|---|
| () => x + 1, | 简写表达式, | 是, | 简单的数学运算或逻辑判断 |
| () => (x + 1), | 带括号表达式, | 是, | 逻辑较长需要换行美观时 |
| () => ({ a: 1 }), | 对象表达式, | 是, | 必须加 () 否则会被当成函数体 |
| () => { ... }, | 函数代码块, | 否, | 必须手动写 return,支持多行、if、for 等 |
- 匿名函数返回值的问题
一般来说,简单的匿名函数的返回值就是整个语句计算后的结果,
| 简写(你看到的), | 完整写法(幕后逻辑), | Python 类比 |
|---|---|---|
| () => x.value + y.value, | function() { return x.value + y.value }, | lambda: x.value + y.value |
-
存值器
默认:computed(() => x) ------ 只读。
进阶:computed({ get: () => x, set: (val) => x = val }) ------ 可读可写。
-
一个多入参变量的示例代码
(x,y) => (x+y)但是一般计算属性的getter不需要入参。
计算属性
计算属性有取值器和存值器两种功能函数,如下面的代码:
html
<script setup>
import { ref, computed } from 'vue'
const celsius = ref(0) // 内部原始数据:摄氏度
// 华氏度计算属性:具备取值与存值功能
const fahrenheit = computed({
// 1. 取值器 (Getter):把内部的摄氏度"加工"成华氏度展示出来
get: () => {
return (celsius.value * 9) / 5 + 32
},
// 2. 存值器 (Setter):当用户修改华氏度时,反向"拆解"出摄氏度存回原变量
// temp 是用户赋给 fahrenheit 的新值
set: (temp) => {
celsius.value = ((temp - 32) * 5) / 9
}
})
</script>
//在vue3中调用
<template>
<div>
<p>当前摄氏度: {{ celsius }}</p>
<label>修改华氏度:</label>
<input v-model.number="fahrenheit" type="number" />
</div>
</template>
但是,存值器用的比较少,所以一般而言,一个计算属性的经典结构为:
vue3
// 默认写法 = 只有 get
const double = computed(() => count.value * 2)
// 此时如果你尝试修改:double.value = 100
// Vue 会在控制台给你一个警告:Write operation failed: computed value is readonly.
在没有指明get和set的情况下,就默认是取值器.