🐸 青蛙编程网
首页 / 前端 / Vue / 4. 响应式数据

4. 响应式数据

这是什么:响应式数据 = 被 Vue「盯上」的数据,一旦值变了,引用它的视图就自动重算更新。

为什么用:上一章模板里输入框的内容会变,但那只是 v-model 的功劳。想让自己的数据驱动页面,得先把数据包成响应式。

如何用:本章从 ref() 包单个值讲到 computed 和 watch,先跑一个点击加一的计数器。

4.1 ref:单个值的响应式包装

完整页面(可直接贴进运行场,试试连点):

<!DOCTYPE html>
<html lang='zh-CN'>
<head>
  <meta charset='utf-8'>
  <title>ref 计数器</title>
  <script src='https://registry.npmmirror.com/vue/3.5.44/files/dist/vue.global.prod.js'></script>
</head>
<body>
  <div id='app'>
    <button @click='add'>点了我 {{ count }} 次</button>
  </div>

  <script>
    const { createApp, ref } = Vue
    createApp({
      setup() {
        const count = ref(0)
        function add() {
          count.value++   // JS 里逢读写用 .value
        }
        return { count, add }
      }
    }).mount('#app')
  </script>
</body>
</html>

要点:

  • ref(0) 把 0 包成响应式对象
  • 在 JS 里读写都要 .value
  • 在模板里自动解包,直接写 {{ count }}(别加 .value)

「模板自动解包」新手最容易混。口诀:JS 里 .value,模板里裸用。

4.2 reactive:对象的响应式

<script>
const { reactive } = Vue
const user = reactive({ name: '青蛙', age: 11 })

user.age = 12   // 直接改属性即可,不用 .value
</script>
对比 ref reactive
适合 单值 / 需整体替换 固定结构的对象
访问 .value 直接 obj.xxx
替换自身 可以 ref = ref(新值) 不可整体替换(响应性会丢失)

教学建议:入门阶段简单场景统一用 ref,对象也 ref() 包起来,心智负担最小。

4.3 computed:由数据算出来的值

<script>
const { ref, computed } = Vue
const tasks = ref(['a', 'b', 'c'])
const done = ref(1)

const percent = computed(() =>
  Math.round((done.value / tasks.value.length) * 100)
)
</script>

配合模板:<p>完成度:{{ percent }}%</p>。

computed 会缓存:依赖(tasks/done)不变时反复显示不重算。

4.4 watch:数据变化时执行副作用

computed 算值;watch 干活(请求、日志、localStorage 存储):

<script>
const { ref, watch } = Vue
const msg = ref('')

watch(msg, (newValue, oldValue) => {
  console.log(`从 ${oldValue} 变成 ${newValue}`)
})
</script>

4.5 动手改

  1. 写 count + 按钮,每点击一次 +10,用 computed 显示是否超过 50
  2. 给 user 对象加 city 并在模板中显示
  3. watch msg,输入长度超 20 时 console 警告(记得在运行场里看输出区)

4.6 小结

  • 免构建写法开头一句:const { createApp, ref } = Vue——从全局 Vue 对象解构,代替工程写法的 import
  • ref 包值,JS 里 .value、模板裸用
  • reactive 包对象,属性直改不换壳
  • computed 算、watch 干活

下一章:事件与方法 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。