Vue基础学习之ref响应式数据、v-指令、computed

 更新时间:2026年03月05日 11:10:41   作者:南山安  
Vue3引入了全新的响应式系统,使得数据管理更为灵活和高效,这篇文章主要介绍了Vue基础学习之ref响应式数据、v-指令、computed的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

本文将带你从一个Todos清单组件,上手Vue基础语法以及核心思想,设计内容有ref响应式数据,v-指令、computed计算属性

完整代码:

<!-- App.vue -->
<script setup>
import { ref, computed } from 'vue'

// 1. 响应式数据:所有 UI 都靠它们驱动
const title = ref('')                     // 输入框内容
const todos = ref([
  { id: 1, title: '睡觉', done: true },
  { id: 2, title: '吃饭', done: true }
])

// 添加任务
function addTodo() {
  if (!title.value.trim()) return
  todos.value.push({
    id: Math.random(),
    title: title.value.trim(),
    done: false
  })
  title.value = ''                         // 清空输入框
}

// 2. 计算属性:派生数据,自动更新
// 统计未完成的数量
const active = computed(() => {
  return todos.value.filter(t => !t.done).length
})

// 全选/全不选的高级玩法
const allDone = computed({
  get() {
    return todos.value.length > 0 && todos.value.every(t => t.done)
  },
  set(val) {
    todos.value.forEach(t => t.done = val)
  }
})
</script>

<template>
  <div class="container">
    <h2>我的 Todos 任务清单</h2>

    <!-- 双向绑定 + 回车添加 -->
    <input type="text" placeholder="今天还要干啥?回车添加" v-model="title" @keydown.enter="addTodo" />

    <!-- 任务列表 -->
    <ul v-if="todos.length">
      <li v-for="todo in todos" :key="todo.id">
        <input type="checkbox" v-model="todo.done">
        <span :class="{ done: todo.done }">{{ todo.title }}</span>
      </li>
    </ul>
    <div v-else class="empty">暂无计划,摸鱼去吧~</div>

    <!-- 统计 + 全选 -->
    <div class="footer">
      <label>
        <input type="checkbox" v-model="allDone" />
        全选
      </label>
      <span>未完成 {{ active }} / 共 {{ todos.length }} 条</span>
    </div>
  </div>
</template>

<style scoped>
.container {
  max-width: 400px;
  margin: 40px auto;
  font-family: sans-serif;
}

input[type="text"] {
  width: 100%;
  padding: 8px;
  font-size: 16px;
}

ul {
  padding-left: 0;
  list-style: none;
}

li {
  padding: 8px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.done {
  color: #999;
  text-decoration: line-through;
}

.empty {
  color: #999;
  text-align: center;
  padding: 20px;
}

.footer {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

实际展示:

一、拆解Vue代码

其实Vue主界面的代码就是我们的HTML+JS+CSS,它是一个三明治结构

    <script setup></script>  //JavaScript
    
    <template></template>    //HTML

    <style scoped></style>   //CSS

二、 响应式数据:Vue 的灵魂

传统写法(jQuery 时代):

// 想改标题?先找 DOM 再改 innerText
document.querySelector('h2').innerText = '新标题'

Vue 写法:

const title = ref('Todos任务清单')

然后模板里直接 {{ title }},你改 title.value = '新标题',页面就自动变了。

为什么这么神奇?因为 Vue 把 todos、title 这些 ref 包装成了响应式对象,只要你通过 .value 去改它,Vue 就知道「有数据变了」,然后自动把所有用到这个数据的地方更新一遍。

记住一句话:在 Vue 里,你只需要操心数据怎么变,页面怎么变 Vue 帮你搞定

三、 Vue 基础指令

指令作用本例中的用法
v-model双向绑定,表单专属神器输入框和任务的 checkbox 都用了它
v-for循环渲染数组遍历 todos 渲染每一行
v-if / v-else条件渲染没任务时显示「暂无计划」
v-bind动态绑定HTML属或者组件的props完成的任务加上删除线和灰色
@click / @keydown.enter事件监听简写回车添加任务

这些指令就是 Vue 给我们提供的「魔法语法糖」,让我们几乎不用写原生 DOM 操作。

1.v-model——双向数据绑定

<input type="text" v-model="title" @keydown.enter="addTodo" />
<input type="checkbox" v-model="todo.done">
<input type="checkbox" v-model="allDone" />

作用:

  • 自动同步表单输入和响应式数据

  • 对于 <input type="text">
    v-model="title" 等价于:

    :value="title" @input="title = $event.target.value"
    

    用户输入 → title.value 自动更新;title.value 变化 → 输入框内容更新。

  • 对于 <input type="checkbox">
    v-model="todo.done" 绑定的是布尔值:

    :checked="todo.done" @change="todo.done = $event.target.checked"
    
  • 对于 allDone(计算属性):
    因为 allDonegetset,所以 v-model 能读也能写,实现“全选”联动。

2.v-for——列表渲染

<li v-for="todo in todos" :key="todo.id">
  <input type="checkbox" v-model="todo.done">
  <span :class="{ done: todo.done }">{{ todo.title }}</span>
</li>

作用:

  • 遍历数组(或对象),为每个元素生成一个 DOM 节点。
  • todo in todostodos 是源数组,todo 是当前项。
  • 必须加 :key:Vue 用 key 来高效追踪每个节点的身份(避免复用错误)。你用了 todo.id,很好!

注意:

  • 不要使用 index 作为 key(除非列表只增不删),否则可能引发状态错乱。
  • v-for 的优先级高于 v-if(如果同时用),但一般建议避免两者同用。

3.v-if与v-else——条件渲染

<ul v-if="todos.length">
  <!-- 渲染任务列表 -->
</ul>
<div v-else class="empty">暂无计划,摸鱼去吧~</div>

作用:

  • v-if="todos.length":当 todos.length > 0(真值)时,渲染 <ul>
  • v-else:必须紧跟在 v-if 或 v-else-if 后面,表示“否则”。
  • 完全销毁/重建 DOM(不是隐藏),适合切换不频繁的场景。

对比v-show:

  • v-show 是通过 CSS display: none 切换,DOM 始终存在。
  • 你的场景用 v-if/v-else 更合适,因为“空状态”和“有任务”是互斥的两种 UI。

4.v-bind(简写:)——动态绑定属性

<span :class="{ done: todo.done }">{{ todo.title }}</span>
<li v-for="todo in todos" :key="todo.id">

作用:

  • 将 HTML 属性(如 classidsrckey 等)绑定到 JS 表达式
  • :class="{ done: todo.done }"
    当 todo.done === true 时,给 <span> 添加 class="done",从而应用样式(删除线+灰色)。
  • :key="todo.id":将 key 属性绑定到 todo.id 的值。

其他常见用法:

<img :src="imageUrl" />
<div :style="{ color: textColor }"></div>
<a :href="linkUrl" rel="external nofollow" >链接</a>

v-bind 是 Vue 实现“数据驱动视图”的关键桥梁。

5.@(即v-on)——事件监听

在你的代码中:

<input ... @keydown.enter="addTodo" />

作用:

  • 监听 DOM 事件,并执行方法。

  • @keydown.enter 是修饰符写法,等价于:

    @keydown="(e) => { if (e.key === 'Enter') addTodo() }"
    
  • 常见修饰符:

    • .enter:回车键
    • .stop:阻止事件冒泡
    • .prevent:阻止默认行为
    • .once:只触发一次

其他例子:

<button @click="deleteTodo(id)">删除</button>
<input @input="handleInput" />
<form @submit.prevent="handleSubmit">...</form>

@v-on: 的缩写,就像 :v-bind: 的缩写。

总结:

  1. 用户在输入框输入 → v-model 同步到 title

  2. 按回车 → @keydown.enter 触发 addTodo() → 新任务加入 todos

  3. v-for 重新遍历 todos,渲染新 <li>

  4. 每个任务的复选框用 v-model 双向绑定 todo.done

  5. 勾选复选框 → todo.done 更新 →

    • active 计算属性自动更新(未完成数)
    • allDone.get() 重新计算(是否全选)
  6. 底部全选框用 v-model="allDone" → 点击时调用 allDone.set() → 批量更新所有 todo.done

  7. 如果 todos 为空 → v-if 切换到 v-else 显示“摸鱼”提示

四、 computed 计算属性:自动缓存的派生数据

我们想显示「未完成的任务有几条」,最笨的写法是:

{{ todos.filter(t => !t.done).length }} / {{ todos.length }}

这样每次渲染都会重新 filter 一遍,数据一大就废。

聪明做法:

const active = computed(() => 
  todos.value.filter(t => !t.done).length
)

computed 有两大杀招:

  1. 缓存:只有当 todos 真的变了,它才会重新计算
  2. 响应式:todos 一变,页面上所有用了 active 的地方立刻更新

更牛的全选 checkbox:

const allDone = computed({
  get() {
    return todos.value.length > 0 && todos.value.every(t => t.done)
  },
  set(val) {
    todos.value.forEach(t => t.done = val)
  }
})

这样 就能实现「全选/全不选」双向功能,代码量少到令人发指。

在 Vue 3 的 computed 中,get 和 set 是用于定义「可读写计算属性」的两个函数。默认情况下,computed 只有一个 getter(即只读),但当你需要让计算属性也能被赋值(比如用在 v-model 中),就需要提供一个 setter(即 set 函数)。

const myComputed = computed({
  get() {
    // 返回派生值(必须)
    return someDerivedValue
  },
  set(newValue) {
    // 处理赋值逻辑(可选)
    // 根据 newValue 更新原始数据
  }
})

get()——读取时触发

  • 当你在模板中使用 {{ myComputed }},或在 JS 中读取 myComputed.value 时,会调用 get()
  • 它应该返回一个值,这个值通常基于其他响应式数据(如 ref 或 reactive 对象)计算而来。
  • Vue 会自动追踪 get() 内部访问的所有响应式依赖,并在它们变化时重新计算

set(newValue)——赋值时触发

  • 当你执行 myComputed.value = someValue(例如通过 v-model),就会调用 set(newValue)
  • newValue 就是你试图赋给计算属性的值。
  • 在 set 中,你不能直接修改计算属性本身(因为它没有存储空间),而是要反向更新它所依赖的原始数据

五、 Vue 开发的核心思维转变

传统开发(操作 DOM)Vue 开发(操作数据)
想加一条任务 → appendChild 一个 li想加一条任务 → todos.push(新对象)
想改标题 → getElementById().innerText = xxx想改标题 → title.value = '新标题'
想全选 → 遍历所有 checkbox 打钩想全选 → allDone = true

你看,Vue 让我们彻底从「操作页面元素」变成了「操作数据」,代码更清晰、更容易维护、也更好测试。

最后总结:

  • ref 响应式数据(核心核心)
  • v-model 双向绑定(表单必备)
  • v-for / v-if 指令(模板必备)
  • computed 计算属性(性能+优雅)
  • Composition API 的 script setup(现代写法)

到此这篇关于Vue基础学习之ref响应式数据、v-指令、computed的文章就介绍到这了,更多相关Vue ref响应式数据、v-指令、computed内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue实现远程获取路由与页面刷新导致404错误的解决

    Vue实现远程获取路由与页面刷新导致404错误的解决

    这篇文章主要介绍了Vue实现远程获取路由与页面刷新导致404错误的解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • vue-router 导航完成后获取数据的实现方法

    vue-router 导航完成后获取数据的实现方法

    这篇文章主要介绍了vue-router 导航完成后获取数据,通过使用生命周期的 created() 函数,在组件创建完成后调用该方法,本文结合实例代码给大家讲解的非常详细需要的朋友可以参考下
    2022-11-11
  • vue使用原生swiper代码实例

    vue使用原生swiper代码实例

    这篇文章主要介绍了vue使用原生swiper代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • vue升级之路之vue-router的使用教程

    vue升级之路之vue-router的使用教程

    自动安装的vue-router,会在src 文件夹下有个一个 router -> index.js 文件 在 index.js 中创建 routers 对象,引入所需的组件并配置路径。这篇文章主要介绍了vue-router的使用,需要的朋友可以参考下
    2018-08-08
  • vue 中引用gojs绘制E-R图的方法示例

    vue 中引用gojs绘制E-R图的方法示例

    这篇文章主要介绍了vue 中引用gojs绘制E-R图的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 解决vue单页面应用进入页面加载所有 js 的问题

    解决vue单页面应用进入页面加载所有 js 的问题

    这篇文章主要介绍了解决vue单页面应用进入页面加载所有 js 的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue axios中的get请求方式

    vue axios中的get请求方式

    这篇文章主要介绍了vue axios中的get请求方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • vue实现静态页面点赞和取消点赞功能

    vue实现静态页面点赞和取消点赞功能

    这篇文章主要为大家详细介绍了vue实现静态页面点赞和取消点赞的功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • vue+ElementUI 关闭对话框清空验证,清除form表单的操作

    vue+ElementUI 关闭对话框清空验证,清除form表单的操作

    这篇文章主要介绍了vue+ElementUI 关闭对话框清空验证,清除form表单的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Vue 刷新当前路由的实现代码

    Vue 刷新当前路由的实现代码

    这篇文章主要介绍了Vue 刷新当前路由的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09

最新评论