iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
Modern Web

前端暴龍機,Vue2.x 進化 Vue3系列 第 27

[前端暴龍機,Vue2.x 進化 Vue3 ] Day27. Vue3 ref & reactive 小練習

說了那麼多,感覺還是有點模糊~ 沒關係,我可能也差不多 ( 哈哈 /images/emoticon/emoticon25.gif
所以還是透過實作練習,讓自己更了解,看見那更明朗的天空吧

目標 : 透過串接 API 接收取到的資料,並且可以點擊按鈕來更新資料

【Vue 3】 ref & reactive 小練習

RandomAPI

ref 方式

可能有聽說過,最不能易出錯的就是一路使用 ref 到底,那麼我們來看看是不是真的這麼好用吧~

<div id="app">
  <h3> 使用 ref 方式 : </h3>
  <ul>
    <li v-for="person in mylist" :key="person.id.value">
      {{ person.name.title }}.{{ person.name.first }} {{ person.name.last }}
    </li>
  </ul>
  <button @click="getAPI">下一筆</button>
</div>

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

createApp({
  setup() {
    
    // 宣告空陣列來接 API 數據
    const mylist = ref([]);
    
    // 呼叫 API 的方法
    function getAPI(){
     axios.get('https://randomuser.me/api/?results=5').then(res=>{

        //  ref 必需透過 .value 來賦予值
        mylist.value = res.data.results;
      })
    }
    
    onMounted(()=>{
     getAPI()
    })

    return {
      mylist,
      getAPI
    }
  }
}).mount('#app')

https://ithelp.ithome.com.tw/upload/images/20210824/20120722u86RcQKKnv.jpg
記得,如果是用 ref 的方式,要加上 .value 來存取值
範例中,一開始呼叫 API 取得資料,接著透過 .value 存值
最後按鈕點擊時,需要再一次呼叫 API 取新一筆資料,剛好直接又透過 .value 存入新的值
目前看起來,好像真的很方便,也不太出錯呢

reactive 方式

接著,來看使用 reactive 是否會變得複雜呢?
以之前的寫法,我自己會寫成下面這樣 ( 不知道是不是跟我一樣 ~ /images/emoticon/emoticon06.gif

<h3> 使用 reactive 方式 : </h3>
<ul>
    <li v-for="member in memberlist" :key="member.id.value">
      {{ member.name.title }}.{{ member.name.first }} {{ member.name.last }}
    </li>
</ul>

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

createApp({
  setup() {
    
    // 使用 reactive 方式來接值
    const memberlist = reactive([]);
    
    function memberAPI(){
       axios.get('https://randomuser.me/api/?results=5').then(res=>{
        memberlist = res.data.results;
      })
    }
    
    onMounted(()=>{
     memberAPI()
    })

    return {
      memberlist,
      memberAPI
    }
  }
}).mount('#app')

使用 reactive 宣告一個空陣列來接,高高興興的直接把值塞進去
因為想說 reactive 是不需要透過 .value 存取值
結果沒想到,為了保持 Proxy 架構,我使用了 const ➪ 結果這麼塞值是錯誤的 /images/emoticon/emoticon02.gif
https://ithelp.ithome.com.tw/upload/images/20210824/20120722QB60YUQG79.jpg

➢ 所以我們再來改寫吧~

// 使用 reactive 方式來接值
const memberlist = reactive({ lists: []});

function memberAPI(){
   axios.get('https://randomuser.me/api/?results=5').then(res=>{
    memberlist.lists = res.data.results;
  })
}

reactive 的方式變成,需要宣告成物件的型態,然後裡面有一個 keyValue 為 lists, 值為空陣列
這麼一來,才不會造成改變 const 錯誤

html 部份的 v-for 也要稍微調整,最後再加上換下一筆資料的功能

<h3> 使用 reactive 方式 : </h3>
<ul>
    <li v-for="member in memberlist.lists" :key="member.id.value">
      {{ member.name.title }}.{{ member.name.first }} {{ member.name.last }}
    </li>
</ul>
<button @click="memberAPI">下一筆</button>

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

createApp({
  setup() {
  
    // 使用 reactive 方式來接值
    const memberlist = reactive({ lists: []});
    
    function memberAPI(){
       axios.get('https://randomuser.me/api/?results=5').then(res=>{
        memberlist.lists = res.data.results;
      })
    }
    
    onMounted(()=>{
     memberAPI()
    })
    
    return {
      memberlist,![/images/emoticon/emoticon01.gif](/images/emoticon/emoticon01.gif)
      memberAPI
    }
  }
}).mount('#app')

https://ithelp.ithome.com.tw/upload/images/20210824/20120722aX3HIe87Vt.jpg
最後終於也完成了同樣的功能
不過如果依照舊有的撰寫習慣,ref 的方式,我們一直強調要用 .value 來存取值
所以至少會記得,但是 reactive 可能跟我一樣,一開始會寫錯,需要再經調整
哈哈,可能撰寫習慣不同,有些人就不會犯這種錯誤
難怪有些人會推崇 一路使用 ref 到底 ,好像真的滿好用的呢 哈哈 /images/emoticon/emoticon01.gif
【Vue 3】 ref & reactive 小練習 演示範例


參考資料

六角學院 | Vue 3 Composition API 精髓掌握 | Youtube Vue3 新手夏令營活動
六角學院 | Composition API 共筆文件


上一篇
[前端暴龍機,Vue2.x 進化 Vue3 ] Day26. Vue3 Composition API 使用(二)
下一篇
[前端暴龍機,Vue2.x 進化 Vue3 ] Day28.Vue3 小補充 Magic ~
系列文
前端暴龍機,Vue2.x 進化 Vue330
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言