[前端暴龙机,Vue2.x 进化 Vue3 ] Day28.Vue3 小补充 Magic ~

https://ithelp.ithome.com.tw/upload/images/20210825/20120722BU3BxcILPM.jpg
下面来介绍一下,Vue 3 的一些小小魔法(个人觉得很 Magic ~ 哈哈),
有些是补充说明,
有些可能会很少使用到,就连官方都有提醒 " 请谨慎使用 "
至於要不要使用,我觉得还是看个人或者专案需求 (我也觉得有点复杂 /images/emoticon/emoticon16.gif)

Composition API 的高度弹性

还记得 Composition API 让我们撰写的弹性变得非常大,我们可以将相同的资料与处理逻辑写在同一个区块,所以其实像是生命周期钩子这类的也一样,假如 A 的处理逻辑会在 onMounted 触发, B 的处理逻辑也会在 onMounted 触发,所以我们的 onMounted 是允许可以分别写在两个区块,范例如下 :

createApp({
  setup() {
    
    // A 的相关处理逻辑
    const A = ref("A");
  
    function Afunc(){
      // ...
    }
    
    onMounted(()=>{
     Afunc()
    })
    
    // B 的相关处理逻辑
    const B = ref("B");
  
    function Bfunc(){
      // ...
    }
    
    onMounted(()=>{
     Bfunc()
    })
    
    return {
      A,
      Afunc,
      B,
      Bfunc
    }
  }
}).mount('#app')

深层监听

记得前面有提过 ref 不会对物件或阵列内部的属性变动做监听,又或是其它某些状况,我们需要自己写监听器

在 Vue2 的写法

data:{
    todos:[]
},
watch : {
    todos:{
        deep: true,
        handler() {
            // do something ...
        }
    }
}

在 Vue3 的写法

watch(要被监听的变数, ()=>{
    // 监听到变更时要做的事
},
{deep:true }
)
const todos = ref([]);
watch(todos,()=>{
  // do something ...
},
{deep:true}
)

写法看似很像,不过当初在写的时候,转换不过来/images/emoticon/emoticon06.gif
而且记得不太好找,所以这边稍作补充 ( 哈哈,也可能我的搜寻能力待加强~~

isRef & isReactive

这两个感觉是满好玩的,不过目前我想不出来可以在日常的甚麽地方使用 @@
isRef : 判断是不是透过 ref 建立出来的
isReactive : 判断是不是透过 reactive 建立出来的

import {createApp,ref,reactive,onMounted,isReactive,isRef} from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.1.4/vue.esm-browser.min.js' 

createApp({
  setup() {
    
    const AA = ref({name:"ref"});
    const BB = reactive({ name: "reactive"});

    onMounted(()=>{
      console.log("AA is ref ? ===> ",isRef(AA))
      console.log("AA is isReactive ? ===> ",isReactive(AA))
      console.log("BB is ref ? ===> ",isRef(BB))
      console.log("BB is isReactive ? ===> ",isReactive(BB))
    })

    return {
      AA,
      BB
    }
  }
}).mount('#app')

https://ithelp.ithome.com.tw/upload/images/20210825/20120722Ms0jMhdbba.jpg
演示范例

小心使用的魔法 toRaw

  • 从 Reactive 或 Ref 中得到 原始资料
  • 做一些不想被监听的事情(提升效能 : 因为不会变动就更新画面)
    https://ithelp.ithome.com.tw/upload/images/20210825/20120722mBxWFiEbgz.jpg
    从图中,我们可以看到下面几点
  1. toRaw 出来的跟 reactive 建立是有差异的 (不符合 "==="),所以就没有了双向
  2. toRaw 出来的跟 原始资料相等 (符合 "===")
  3. 变更 reactive 内容,三者资料一起更新,并且更新画面
  4. 变更 toRaw 内容,三者资料一起更新,但是没有更新画面

https://ithelp.ithome.com.tw/upload/images/20210825/201207223ZrcuW154q.jpg
另外,如果是使用 ref 建立的,需要加上 .value 才会拿到原始资料

toRaw 演示范例

toRaw
返回 reactive 或 readonly 代理的原始对象。这是一个转义口,可用于临时读取而不会引起代理访问/跟踪开销,也可用于写入而不会触发更改。不建议保留对原始对象的持久引用。请谨慎使用。
《 Vue3 官方文件 - toRaw 》

魔法 toRefs

将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref。
《 Vue3 官方文件 - toRefs 》

可以将响应式的物件,转换为普通的物件,而物件内的 keyValue 都会被包装成 ref 的型态
https://ithelp.ithome.com.tw/upload/images/20210826/20120722MnjnbmF5WF.jpg

所以啦~ 一开始 开开心心的,想举跟 toRaw 类似的例子,将普通物件reactive 物件ref 物件 通通拿来做 toRefs,结果没想到错了 /images/emoticon/emoticon04.gif

import {createApp,ref,reactive,onMounted,toRefs} from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.1.4/vue.esm-browser.min.js' 

createApp({
  setup() {
    
    // 原始数据
    const obj = {
        name: '小智妈妈',
        age: 18,
        gender: "female"
    }
    
    // 原始数据 toRefs
    const toRefs_obj = toRefs(obj);
    
    // reactive 物件
    const reactive_obj = reactive(obj);
    // reactive toRefs 转换
    const reactive_toRefs = toRefs(reactive_obj);
    
    // ref 物件
    const ref_obj = ref(obj);
    // ref toRefs 转换
    const ref_toRefs = toRefs(ref_obj);
    
    return {
    }
  }
}).mount('#app')

https://ithelp.ithome.com.tw/upload/images/20210826/20120722ZL93zsLirK.jpg
会提示你 toRefs 期望接到的资料型态是 reactive 物件,所以响应式对象不包含 ref,那麽只能使用 reactive 作范例~

先来看一下,资料建立完的样子

https://ithelp.ithome.com.tw/upload/images/20210826/201207221ZdXKUd7BL.jpg

观察数据之间的关系

https://ithelp.ithome.com.tw/upload/images/20210826/201207223NdPyUJp0b.jpg
结果彼此之间都没关系 ⟹ 那麽? 所以如果更改资料会有甚麽影响? 会不会触发介面更新?

资料变动後的变化

1. 更改原始数据 (age: 18 ➛ 16)

https://ithelp.ithome.com.tw/upload/images/20210826/20120722zWEcMVzwHm.jpg
三者的数据全部更新,不过没更新画面

2. 更改 reactive (name: 小智妈妈 ➛ 健美中的小智妈妈)

https://ithelp.ithome.com.tw/upload/images/20210826/20120722HYhNgIt05Z.jpg
三者的数据全部更新,而且画面也都被变动了

3. 更改 toRefs (gender: female ➛ 神的传说)

https://ithelp.ithome.com.tw/upload/images/20210826/20120722HAyKuU9pO7.jpg
只有 toRefs 值被变更,且画面皆无更新
而且因为物件内的 keyValue 都会被包装成 ref 的型态,所以取得 keyValue 值也就必需再加上 .value

<p>toRefs : </p>
<p>{{ reactive_toRefs.name.value }}</p>
<p>{{ reactive_toRefs.age.value }}</p>
<p>{{ reactive_toRefs.gender.value }}</p>

toRefs 演示范例

最後, Vue3 的介绍大致上就介绍到这边,後面就一起使用 Composition API 来实作我们最後的小专案吧~


图片来源

Meme 梗图仓库,李俐彦 - 魔法卡
维基百科 Vue.js
【MAD】digimon03 数码暴龙03 进化集 evaluation | YouTube

参考资料

HINA::工程幼稚园 — Vue3 - 每天来一点雷 Part 2
Vue3 官方文件 - toRaw
快速使用Vue3最新的15个常用API
Vue3 官方文件 - toRefs
vue3 之 reactive && toRefs原始码解析,TW511教学网
Vue3.0学习笔记,程序人生
Vue3.0(四)ref源码分析与toRefs,知乎 - 圈鹅
简单梳理下 Vue3 的新特性, IT人 - lliiooiill


<<:  Day 25 constructors、this、static

>>:  食谱搜寻系统demo

[Java Day24] 6.1. 继承

教材网址 https://coding104.blogspot.com/2021/06/java-i...

Flutter基础介绍与实作-Day13 Onboarding、Login、Sign Up范例实作(1)

今天我们就利用我们之前所学的来做一个和旅游相关的Onboarding介面,事不宜迟赶快开始吧! 我想...

新增表单/编辑表单,共用?或分开?

目前我们写好了一个新增的画面 需求 接下来,常见的需求是,人员的新增之後是人员的编辑。 新增用的画面...

Day 30. E2E Testing Case

测试Router正确跳转 'clicking on a button should redirect...

第39天~~又是JSON+动态增加按钮不是用XML

这篇的上一篇:https://ithelp.ithome.com.tw/articles/10283...