计算属性

前面我们讲完关于VUE3如何创建响应式数据,现在我们来了解一下VUE3的计算属性和VUE2又有何不同。

如何使用计算属性

很简单的举个例子,输入一个姓,再输入一个名,然后通过计算属性去拼接这个姓名展示出来。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{}}
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
let firstName = ref("月");
let lastName = ref("亮");
</script>

现在就差计算属性去拼接这个姓和名了,我们前面讲refreactive的时候说了使用这些之前都要先引入,计算属性也不例外,我们也要先引入这个计算属性computed

然后也是使用这个computed去包裹一个函数,这个函数return出去一个值就是计算属性的值。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

// 声明计算属性
let fullName = computed(() => {
  return firstName.value + lastName.value;
});
</script>

使用起来还是很简单的,没啥复杂性,下面顺带讲一下计算属性的特性,和VUE2里特性一样,计算属性是有缓存的

我们知道计算属性里面所依赖的数据发生了变化,计算属性就会重新执行,我们在计算属性里打印一个东西,然后去修改所依赖的数据,我们修改多少次这个东西就会打印多少次。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

// 声明计算属性
let fullName = computed(() => {
  console.log(1);
  return firstName.value + lastName.value;
});
</script>

这是刚开始计算属性打印的第一次。

这是修改了三次以后打印的数据,会发现又打印了三次。

那我们直接在页面上多展示几次这个fullName,会不会也重复执行这个计算属性呢?

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}<br />
    全名: {{ fullName }}<br />
    全名: {{ fullName }}<br />
    全名: {{ fullName }}<br />
    全名: {{ fullName }}<br />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

// 声明计算属性
let fullName = computed(() => {
  console.log(1);
  return firstName.value + lastName.value;
});
</script>

看到这里打印了五次fullName,那么是否也会打印五次呢?

其实只打印了一次,这就说明计算属性是有缓存的,如果所依赖的数据没有发生改变,是不会重新执行的。

这就是跟方法不一样的地方,我们用方法也可以去return这个fullName,但是方法可没有缓存,你用了几次就会去执行几次。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName2() }}<br />
    全名: {{ fullName2() }}<br />
    全名: {{ fullName2() }}<br />
    全名: {{ fullName2() }}<br />
    全名: {{ fullName2() }}<br />
    全名: {{ fullName2() }}<br />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

// 方法
function fullName2() {
  console.log(1);
  return firstName.value + lastName.value;
}
</script>

对了我们打印一下这个计算属性,看看是什么东西,毕竟前面讲refreactivetoRefs的时候打印值都不是像VUE2那样简单的字符串或者对象,而是RefImpl对象或者Proxy对象或者ObjectRefImpl对象,所以这次我们看看这个计算属性到底是个什么东西。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

let fullName = computed(() => {
  return firstName.value + lastName.value;
});

console.log(fullName);
</script>

看出来了,计算属性是一个ComputedRefImpl对象,显而易见,其实也是一个RefImpl对象,它还有value属性。

讲到这里,计算属性的使用就基本数讲完了,很简单。但是这样的计算属性是不可修改的。

如何修改计算属性

哎,前面讲计算属性的时候,不是通过修改所依赖的数据而去修改计算属性了嘛,为什么说这样的计算属性是不可以修改的呢?

这里说的修改是直接修改计算属性而不是修改所依赖的数据。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}
    <button @click="changeName">修改全名</button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

let fullName = computed(() => {
  return firstName.value + lastName.value;
});

function changeName() { 
  fullName.value = 'yueliang'
}
</script>

都不用看结果,代码里就已经报错了。

报错提示里很清楚地就告诉你了,此时的计算属性只可读,不能修改。

那我们怎么才能直接去修改这个计算属性?

我们前面使用计算属性的时候是在computed里包裹一个函数然后去return。现在我们在computed里包裹一个对象,对象里面有两个方法,一个是get方法,一个是set方法。其实如果了解访问器属性会发现这就是一个getter,一个setter

我们在get方法里面获取计算属性的值,在set方法里面去修改计算属性。

html 复制代码
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

let fullName = computed({
  get() {
    return firstName.value + lastName.value;
  },
  set() {},
});

function changeName() {
  fullName.value = "yueliang";
}

其实加上这个set方法以后,下面的代码就不会报错了。

我们在修改计算属性的时候,会把修改的值传给set方法,然后在set方法里去修改计算属性的依赖,嘻嘻嘻,其实还是通过修改计算属性的依赖数据来改变计算属性的值,但是这是内部的处理,在外部看来我们还是直接修改的计算属性。

html 复制代码
<template>
  <div>
    姓: <input type="text" v-model="firstName" /><br />
    名: <input type="text" v-model="lastName" /><br />
    全名: {{ fullName }}
    <button @click="changeName">修改全名</button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
let firstName = ref("月");
let lastName = ref("亮");

let fullName = computed({
  get() {
    return firstName.value + lastName.value;
  },
  set(value) {
    let arr = value.split(" ");
    firstName.value = arr[0];
    lastName.value = arr[1];
  },
});

function changeName() {
  fullName.value = "yue liang";
}
</script>

这样我们就可以直接修改计算属性了。

相关推荐
小兵张健8 小时前
价值1000的 AI 工作流:Codex 通用前端协作模式
前端·aigc·ai编程
sunny_9 小时前
面试踩大坑!同一段 Node.js 代码,CJS 和 ESM 的执行顺序居然是反的?!99% 的人都答错了
前端·面试·node.js
拉不动的猪9 小时前
移动端调试工具VConsole初始化时的加载阻塞问题
前端·javascript·微信小程序
ayqy贾杰11 小时前
Agent First Engineering
前端·vue.js·面试
IT_陈寒11 小时前
SpringBoot实战:5个让你的API性能翻倍的隐藏技巧
前端·人工智能·后端
iceiceiceice11 小时前
iOS PDF阅读器段评实现:如何从 PDFSelection 精准还原一个自然段
前端·人工智能·ios
大金乄11 小时前
封装一个vue2的elementUI 表格组件(包含表格编辑以及多级表头)
前端·javascript
葡萄城技术团队12 小时前
【性能优化篇】面对万行数据也不卡顿?揭秘协同服务器的“片段机制 (Fragments)”
前端
程序员阿峰12 小时前
2026前端必备:TensorFlow.js,浏览器里的AI引擎,不写Python也能玩转智能
前端
Jans13 小时前
Shipfe — Rust 写的前端静态部署工具:一条命令上线 + 零停机 + 可回滚 + 自动清理
前端