iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

分手前端菜雞之旅@非洲30天系列 第 8

一口氣看完 Vue composition API 語法-D08

  • 分享至 

  • xImage
  •  

一口氣看完 Vue composition API 語法

為什麼要用 Vue 3 Composition API?

對我來說最重要的有2點:

  1. 比Options API更好整理邏輯
  2. 可以重複使用
  3. 完全搭配Typescript

可以在官方文檔看更多:Why Composition Api

今天就來一次把Composition API的重點看完,

我這邊主要使用:Composition API + Typescript ,並以SFC(單文件主見)為主。

這一篇也變成我的筆記方便回來查找。

目前完成的有(隨時更新):

Data: Reactive & Ref
Method
Computed
Watch (WatchEffect待補)
Props
Emits
Styles
Lifecycle

下面有部分是自己用英文作的筆記,(來不及翻譯就抱歉啦)


環遊非洲第08天:非洲101 之Q

猜猜看如果你在肯亞使用塑膠袋會發生什麼事情?
A. 會有小孩跟你要塑膠袋
B. 會有人要跟你合照
C. 必須繳交罰款
D. 什麼事情都不會發生


Setup Hook & Template for SFC

官方推薦以<script setup>作為 Single-File Components (SFCs)的語法

範例:

<template>
  <button @click="log">{{ msg }}</button>
</template>

<script lang="ts" setup>
// variable
const msg = 'Hello!';

// functions
function log() {
  console.log(msg)
}

</script>

<style lang="scss" scoped>
.button
  background: black;

</style>

動態Data: Reactive & Ref

Composition API使用reactive 或是ref 來追蹤數據的變化

(如同Options API data的作用)

使用reactive追蹤物件和陣列變化,

ref可以用在各種類型

官方文檔: https://vuejs.org/guide/essentials/reactivity-fundamentals.html

表格快速看用法:

reactive() ref()
用法 Objects, arrays, and collection types such as Map and Set. ⚠️It cannot hold primitive types such as string, number or boolean. ⚠️ Reactive objects are JavaScript Proxies, which are not equal to the original object. Can hold any value type. When holding object types, ref automatically converts its .value with reactive()
語法 import {reactive} from 'vue' const state = reactive({count: 0}) import {ref} from 'vue' const state = ref(0)
取值 function increment() {state.count++ } Argument will be wrapped with .value property function increment() {count.value++}
Template裡面用法 {{ state.count }} 在template裡面value會自動被拆掉,所以不用表明.value {{ count }}

⚠️Reactive的Array裡面也都是Proxy,使用展開符號取得裡面的值(TODO: 驗證)

const myCountries = reactive([{name: 'Kenya'}, {name: 'South Africa'}])
console.log(myCountries) // [Proxy, Proxy]
console.log(...myCountries) // [{...},{...}]

Method / Function 用法

使用函式宣告式:

function iconURL(name: string): string {
return `/img/weather/${name}.png`;
}

Computed

//basic usage
const double = computed(() => {
  return something;
});

//declare return type
const double = computed<number>(() => {
  // type error if this doesn't return a number
});

Computed回傳的也是一個computed ref(Proxy),
需要使用.value來取得值
在Template也會被自動解析,不需要使用.value屬性

//Access inside the template

<template>
  <div>
    {{ double }}
  </div>
</template>
//Access computed value inside other functions with .value

function getValue(){
double.value + ...
}

Watch

import {ref,watch} from 'vue'

const x = ref(0)
const y = ref(0)

// watch a ref
watch(x, (newQuestion, oldQuestion) => {
  ...
})

//Watch a property of reactive object
const obj = reactive({ count: 0 })

//要觀察Object或Array的話,使用getter
//Use a getter
watch(() => obj.count,(count) => {
    console.log(`count is: ${count}`)
    }
)

Props

Use defineProps macro with object syntax inside

Two types of declaration:

  1. Run-time declartion
  2. 2.Type-based prop declaration

When using type declaration, the equivalent runtime declaration is automatically generated

See also: https://vuejs.org/guide/components/props.html
https://vuejs.org/guide/components/props.html

//no need to import defineProps

//1.Run-time declartion
const prop = defineProps({
  propA: {
    type: String,
    required: true
    default: ''
  },
})

//2.Type-based prop declaration
// https://vuejs.org/api/sfc-script-setup.html#default-props-values-when-using-type-declaration

export interface Props {
    msg: string
    labels?: string[]
}

const props = defineProps<Props>();

//with default value(實驗階段)
const props = withDefaults(defineProps<Props>(), {
msg: 'hello',
labels: () => ['one', 'two']
})
  
//Access props (same in templates & functions)

const props = defineProps({
  propA: Boolean
})

console.log(props.propA)

Emit

See also: https://vuejs.org/guide/components/events.html

//no need to import defineEmits
const emit = defineEmits(['searchCleared']);

//待補:emit型別宣告

//Use in functions

function buttonClick() {
emit('submit')
}

//Use in template

<template>
  <button @click="$emit('someEvent')">click me</button>
</template>

Lifecycle

Callbacks called when the stage is completed
Composition API: Lifecycle Hooks

import {onMounted, onUpdated, onUnmounted} from 'vue';

onMounted(() => {
   //
})

VueX

VueX Composition API

** 官方推薦使用Pinia,有機會會回來補充Pinia

import { useStore } from 'vuex'

export default {
setup () {
const store = useStore()
}
}

store.state.count
store.getters.double
store.commit('increment')
store.dispatch('asyncIncrement')

Styles

When trying to change child-component styles, you can use :deep(selector)

<style lang="sass" scoped>
.select-rows
  :deep(.v-field)
    font-size: 12px
</style>

環遊非洲第08天:非洲101 之A

C. 必須繳交罰款,可能高達上萬元,不然會被關起來喔!
因為肯亞是世界上禁塑膠袋最嚴格的國家之一。

據說海關也會檢查你的包包有沒有塑膠袋(很快就可以去肯亞幫大家證實一下了)
其實整個非洲大陸,是禁塑環保的前段班,
盧安達、模里西斯等國家也都禁止塑膠袋,而南非和其他國家,則禁止商家提供免費塑膠袋。
是不是和我們對非洲的印象很不一樣呢?

Planet Alert: Africa Leads The Way In Banning The Use Of Plastic
34 Plastic Bans in Africa | A Reality Check


以上!

之後就會來幫我們的Options API搬家囉!(順便更新一下UI...)


上一篇
為什麼 Vue 要使用Proxy -D07
下一篇
掰惹Mixin: Vue3-Composition API的複用-Composables-D09
系列文
分手前端菜雞之旅@非洲30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言