(一)响应式数据
1. 简单例子
从最简单的数据绑定开始,在 Vue 2.0 中,我们这样将一个数据绑定到模板的指定位置:
在组件创建参数的 data 构造函数中返回一个用来绑定的数据对象,其中有个 now 字段,会被渲染到模板内的 .app > p 内。
<template> <div class="app"> <h1>Hello world!</h1> <p>Now is: {{now.toString()}}</p> </div> </template> <script> // Vue 2.0 export default { data() { return { now: new Date(), }; }, }; </script>
用 Vue3 的组装 API 实现的话,则是这样:
// Vue 3.0 export default { setup() { return { now: new Date(), }; }, };
2. 更新数据
奇怪,看起来好像没啥区别,只是把 data 改成了 setup 吗?
并不是,假如我们现在对这个 DEMO 做个小改动,让它每秒钟刷新一次时间,用 Vue2 大概是这样实现:
// Vue 2.0 export default { data() { return { now: new Date(), }; }, mounted() { setInterval(() => this.now = new Date(), 1000); }, };
而 Vue3 的等效实现则为:
// Vue 3.0 import { ref, onMounted } from 'vue'; export default { setup() { const now = ref(new Date()); onMounted(() => { setInterval(() => now.value = new Date(), 1000); }); return { now, }; }, };
3. 对比分析
写了太多 Vue 的我们可能已经忘了,Vue2 的代码从标准 JS 模块的角度来看有多奇怪:
这一切,是因为整个模块 default 对象其实是 vm 对象的构造参数。其背后隐藏了对象的创建逻辑,在构造对象时构造参数中的一些不同层级的字段被绑定到了 vm 对象上。
不少新手可能都犯过一个错误,在 data 中返回的数据字段和 props、methods 或者 computed 中的字段命名撞车(尤其是使用名为 data 的字段),在编码阶段并不能被 IDE 直接发现。就是因为上面的原因,这些字段创建时隶属于不同的位置,在之后构造时才被绑在了同一个对象上,导致了运行时才能发现的冲突。
Vue3 中,改成提供 ref、reactive、toRef、onMounted 等函数的形式实现,例子中:
可以说 Vue3 是直接将响应数据的创建决定权、生命周期的通知回调,都通过 API 的形式交给了开发者,更直观明了和可控。
4. API 说明
下面详细说说常用的几个响应式数据相关 API:ref, reactive 和 toRefs。
(1) ref
上面例子中使用到的 ref,可以将一个数据包装成响应式数据代理对象。
const count = ref(0); console.log(count.value); // => 0 count.value++; console.log(count.value); // => 1
当你修改代理对象的 count.value 属性时,模板中使用到 count 的位置将响应数据的变化,更新视图中的数据状态。
(2) reactive
对于对象的响应式封装,使用 ref 稍显麻烦:
const state = ref({ count: 0, }); console.log(state.value.count); // => 0 state.value.count++; console.log(state.value.count); // => 1
这时可以改为使用 reactive,像操作普通对象的字段一样修改 count 即可更新视图:
const state = reactive({ count: 0, }); console.log(state.count); // => 0 state.count++; console.log(state.count); // => 1
对代理对象 state 添加新的字段也可触发视图更新。
(3) toRefs
有时候,对象的名字过长,我们想直接在模板内使用对象内部字段,直接使用解构是不行的:
import { reactive } from 'vue'; export default { setup() { const position = reactive({ x: 0, y: 0, }); return { // 错误,解构出来的 x, y 并没有响应式代理。绑定到模板上后,数据变化无法触发视图更新 ...position, }; }, };
这个情况下,使用 toRefs 处理后再解构赋值即可:
import { reactive, toRefs } from 'vue'; export default { setup() { const position = reactive({ x: 0, y: 0, }); return { ...toRefs(position), }; }, };
但需要注意,toRefs 只处理调用时 position 的现有字段,如果在之后对 position 增加新字段,将无法触发视图更新。
以上就是浅析 Vue 3.0 的组装式 API(一)的详细内容,更多关于Vue 组装式 API的资料请关注小牛知识库其它相关文章!
本文向大家介绍浅谈Vue3.0新版API之composition-api入坑指南,包括了浅谈Vue3.0新版API之composition-api入坑指南的使用技巧和注意事项,需要的朋友参考一下 关于VUE3.0 由于vue3.0语法跟vue2.x的语法几乎是完全兼容的,本文主要介绍了如何使用composition-api,主要分以下几个方面来讲 使用vite体验vue3.0 compositio
本文向大家介绍精读《Vue3.0 Function API》,包括了精读《Vue3.0 Function API》的使用技巧和注意事项,需要的朋友参考一下 1. 引言 Vue 3.0 的发布引起了轩然大波,让我们解读下它的 function api RFC 详细了解一下 Vue 团队是怎么想的吧! 首先官方回答了几个最受关注的问题: Vue 3.0 是否有 break change,就像 Pyth
本文向大家介绍vue3.0 的 Composition API 的使用示例,包括了vue3.0 的 Composition API 的使用示例的使用技巧和注意事项,需要的朋友参考一下 网上讨论的文章已经很多了,这里举一个简单的例子来讨论一下 Composition API 的用法,具体问题才好具体讨论嘛。 假如我们要做一个论坛的讨论列表和分页,以前是把需要的数据都放在data里面,事件都放在met
本文向大家介绍浅析Node.js 中 Stream API 的使用,包括了浅析Node.js 中 Stream API 的使用的使用技巧和注意事项,需要的朋友参考一下 本文由浅入深给大家介绍node.js stream api,具体详情请看下文吧。 基本介绍 在 Node.js 中,读取文件的方式有两种,一种是用 fs.readFile ,另外一种是利用 fs.createReadStream 来
本文向大家介绍浅析python的Lambda表达式,包括了浅析python的Lambda表达式的使用技巧和注意事项,需要的朋友参考一下 在python项目中,我们经常会用到lambda,那么lambda是什么呢,有什么作用,下面我们开始介绍 1、可以使用lambda关键字创建匿名函数。Lambda函数可以在需要函数对象的任何地方使用。它们在语法上限于单个表达式。所谓匿名就是无名。 例如定义两个书加
本文向大家介绍浅析C# 装箱和拆箱,包括了浅析C# 装箱和拆箱的使用技巧和注意事项,需要的朋友参考一下 Object类型是所有类型的基类,其下面有ValueType类型。什么结构啊,枚举啊,都继承ValueType,这些都是值类型。其他的什么类啊,数组啊,字符串啊等等都是引用类型。 简单的说,直接继承Object的都是引用类型,继承ValueType的都是值类型。 那样的话,像整形这样的结构按理说