亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue3.2單文件組件setup的語(yǔ)法糖與新特性總結(jié)

 更新時(shí)間:2022年07月24日 10:50:33   作者:用戶體驗(yàn)官大龍  
ue3上線已經(jīng)很久了,許多小伙伴應(yīng)該都已經(jīng)使用過(guò)vue3了,下面這篇文章主要給大家介紹了關(guān)于Vue3.2單文件組件setup的語(yǔ)法糖與新特性總結(jié)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

滿滿的干貨,建議收藏慢慢看,可以當(dāng)作Vue3.0的學(xué)習(xí)資料。

在vue2.0時(shí)期,組件里定義的各類(lèi)變量、方法、計(jì)算屬性等是分別存放到data、methods、computed...選項(xiàng)里,這樣編寫(xiě)的代碼不便于后期的查閱(查找一個(gè)業(yè)務(wù)邏輯需要在各個(gè)選項(xiàng)來(lái)回切換)。setup函數(shù)的推出就是為了解決這個(gè)問(wèn)題,讓新手開(kāi)發(fā)者更容易上手...

setup語(yǔ)法糖

setup是Vue3.0后推出的語(yǔ)法糖,并且在Vue3.2版本進(jìn)行了大更新,像寫(xiě)普通JS一樣寫(xiě)vue組件,對(duì)于開(kāi)發(fā)者更加友好了;按需引入computed、watch、directive等選項(xiàng),一個(gè)業(yè)務(wù)邏輯可以集中編寫(xiě)在一起,讓代碼更加簡(jiǎn)潔便于瀏覽。

一、基本用法

只需在<script>里添加一個(gè)setup屬性,編譯時(shí)會(huì)把<script setup></script>里的代碼編譯成一個(gè)setup函數(shù)

<script setup>
console.log('hello script setup')
</script>

普通的<script>只會(huì)在組件被首次引入的時(shí)候執(zhí)行一次,<script setup>里的代碼會(huì)在每次組件實(shí)例被創(chuàng)建的時(shí)候執(zhí)行。

二、data和methods

<script setup>里聲明的變量和函數(shù),不需要return暴露出去,就可以直接在template使用

<script setup>
import { ref, reactive } from 'vue'    
// 普通變量
const msg = 'Hello!'
 
// 響應(yīng)式變量
let num = ref(1111)         // ref聲明基本類(lèi)型變量
const obj = reactive({        // reactive聲明對(duì)象類(lèi)型變量,如Object、Array、Date...
    key: 'this is a object'
})
 
// 函數(shù)
function log() {
    console.log(msg)          // Hello
    console.log(num.value)    // 1111(可根據(jù)input輸入值而改變)
    console.log(obj.key)      // this is a object
}
</script>
 
<template>
    <h1>{{ msg }}</h1>
    <p>{{obj.key}}</p>
    <input v-model="num" type="text" />
    <button @click="log">打印日志</button>
</template>

三、計(jì)算屬性computed

<script setup>
import { ref, computed } from 'vue'
 
let count = ref(0)
const countPlus = computed(()=>{
    return count.value+1
})
</script>
 
<template>
    <h1>計(jì)數(shù):{{ countPlus }}</h1>
</template>

四、監(jiān)聽(tīng)器watch、watchEffect

1、watch監(jiān)聽(tīng)器除了使用方式有區(qū)別之外,其他的與vue2.0沒(méi)啥變化

<script setup>
import { ref, reactive, watch } from 'vue'
 
// 監(jiān)聽(tīng)ref
let count = ref(0)
watch(count, (newVal, oldVal)=> {
    console.log('修改后', newVal)
    console.log('修改前', oldVal)
})
 
// 監(jiān)聽(tīng)reactive屬性
const obj = reactive({
    count: 0
})
watch(
    ()=> obj.count,     // 一個(gè)函數(shù),返回監(jiān)聽(tīng)屬性
    (newVal, oldVal)=> {
        console.log('修改后', newVal)
        console.log('修改前', oldVal)
    },
    {
        immediate: true,     // 立即執(zhí)行,默認(rèn)為false
        deep: true     // 深度監(jiān)聽(tīng),默認(rèn)為false
    }
)
 
const onChange = function(){
    count.value++
    obj.count++
}
</script>
 
<template>
    <button @click="onChange">改變count</button>
</template>

2、watchEffect

watchEffect是Vue3.0新增的一個(gè)監(jiān)聽(tīng)屬性的方法,它與watch的區(qū)別在于watchEffect不需要指定監(jiān)聽(tīng)對(duì)象,回調(diào)函數(shù)里可直接獲取到修改后的屬性的值

<script setup>
import { ref, reactive, watchEffect } from 'vue'
 
let count = ref(0)
const obj = reactive({
    count: 0
})
setTimeout(()=>{
    count.value++
    obj.count++
}, 1000)
 
watchEffect(()=> {
    console.log('修改后的count', count.value)
    console.log('修改前的obj', obj.value)
})
</script>

五、自定義指令directive

以 vNameOfDirective 的形式來(lái)命名本地自定義指令,可以直接在模板中使用

<script setup>
// 導(dǎo)入指令可重命名
// import { myDirective as vMyDirective } from './MyDirective.js'
 
// 自定義指令
const vMyDirective = {
  beforeMount: (el) => {
    // 在元素上做些操作
  }
}
</script>
<template>
  <h1 v-my-directive>This is a Heading</h1>
</template>

六、import導(dǎo)入的內(nèi)容可直接使用

 1、導(dǎo)入的模塊內(nèi)容,不需要通過(guò) methods 來(lái)暴露它

// utils.js 
export const onShow = function(name) {
    return 'my name is ' + name
}
// Show.vue
<script setup>
    import { onShow } from './utils.js'
</script>
<template>
    <div>{{ onShow('jack') }}</div>
</template>

 2、導(dǎo)入外部組件,不需要通過(guò)components注冊(cè)使用

// Child.vue
<template>
    <div>I am a child</div>
</template>
// Parent.vue
<script setup>
    import Child from './Child.vue'
</script>
<template>
    <child></child>
</template>

七、聲明props和emits 

在 <script setup> 中必須使用 defineProps 和 defineEmits API 來(lái)聲明 props 和 emits ,它們具備完整的類(lèi)型推斷并且在 <script setup> 中是直接可用的

// Child.vue
<script setup>
 
// 聲明props
const props = defineProps({
    info: {
        type: String,
        default: ''
    }
})
 
// 聲明emits
const $emit = defineEmits(['change'])
 
const onChange = function() {
    $emit('change', 'child返回值')
}
</script>
 
<template>
    <h1>信息:{{ info }}</h1>
    <button @click="onChange">點(diǎn)擊我</button>
</template>
// Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
 
const msg = ref('hello setup !')    // 響應(yīng)式變量
 
const onAction = function(event) {
    console.log(event)    // child返回值
}
</script>
 
<template>
    <child :info="msg" @change="onAction"></child>
</template>

如果使用了 Typescript,使用純類(lèi)型聲明來(lái)聲明 prop 和 emits 也是可以的。

八、父組件獲取子組件的數(shù)據(jù)

父組件要想通過(guò)ref獲取子組件的變量或函數(shù),子組件須使用defineExpose暴露出去

// Child.vue
<script setup>
import { ref, defineExpose } from 'vue'
 
const info = ref('I am child')
const onChange = function() {
    console.log('Function of child')
}
 
// 暴露屬性
defineExpose({
    info,
    onChange
})
</script>
 
<template>
    <h1>信息:{{ info }}</h1>
    <button @click="onChange">點(diǎn)擊我</button>
</template>
// Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
 
const childRef = ref()
const onAction = function() {
    console.log(childRef.value.info)    // I am child
    console.log(childRef.value.onChange())    // Function of child
}
</script>
 
<template>
    <child ref="childRef"></child>
    <button @click="onAction">獲取子值</button>
</template>

 九、provide和inject傳值

無(wú)論組件層次結(jié)構(gòu)有多深,父組件都可以通過(guò)provide 選項(xiàng)來(lái)其所有子組件提供數(shù)據(jù),子組件通過(guò)inject接收數(shù)據(jù)

// Parent.vue
<script setup>
import { ref, provide } from 'vue'
import Child from './Child.vue'
 
const msg = ref('Hello, my son')
const onShow = function() {
    console.log('I am your parent')
}
 
provide('myProvide', {
    msg,
    onShow
})
</script>
 
<template>
    <child></child>
</template>
// Child.vue
<script setup>
import { inject } from 'vue'
 
const provideState = inject('myProvide')    // 接收參數(shù)
 
const getData = function() {
    console.log(provideState.msg)    // Hello, my son
    console.log(provideState.onShow())    // I am your parent
}
</script>
 
<template>
    <button @click="getData">獲取父值</button>
</template>

十、路由useRoute和useRouter

<script setup>
import { useRoute, useRouter } from 'vue-router'
 
const $route = useRoute()
const $router = userRouter()
 
// 路由信息
console.log($route.query)
 
// 路由跳轉(zhuǎn)
$router.push('/login')
</script>

十一、對(duì)await異步的支持

<script setup> 中可以使用頂層 await。結(jié)果代碼會(huì)被編譯成 async setup()

<script setup>
    const post = await fetch(`/api/post/1`).then(r => r.json())
</script>

十二、nextTick

// 方式一
<script setup>
import { nextTick } from 'vue'
 
nextTick(()=>{
    console.log('Dom已更新!')
})
</script>
// 方式二
<script setup>
import { nextTick } from 'vue'
 
await nextTick()    // nextTick是一個(gè)異步函數(shù),返回一個(gè)Promise實(shí)例
// console.log('Dom已更新!')
</script>

十三、全局屬性globalProperties

// main.js里定義
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
 
// 定義一個(gè)全局屬性$global 
app.config.globalProperties.$global = 'This is a global property.' 
 
app.mount('#app')
// 組件內(nèi)使用
<script setup>
import { getCurrentInstance } from 'vue'
 
// 獲取vue實(shí)例
const { proxy } = getCurrentInstance()
// 輸出
console.log(proxy.$global)    // This is a global property.
</script>

十四、生命周期

setup()里訪問(wèn)組件的生命周期需要在生命周期鉤子前加上“on”,并且沒(méi)有beforeCreate和created生命周期鉤子

因?yàn)?nbsp;setup 是圍繞 beforeCreate 和 created 生命周期鉤子運(yùn)行的,所以不需要顯式地定義它們。換句話說(shuō),在這些鉤子中編寫(xiě)的任何代碼都應(yīng)該直接在 setup 函數(shù)中編寫(xiě)。

// 使用方式
<script setup>
import { onMounted } from 'vue'
 
onMounted(()=> {
    console.log('onMounted')
})
</script>

十五、與普通的script標(biāo)簽一起使用

<script setup> 可以和普通的 <script> 一起使用。普通的 <script> 在有這些需要的情況下或許會(huì)被使用到:

  • 無(wú)法在 <script setup> 聲明的選項(xiàng),例如 inheritAttrs 或通過(guò)插件啟用的自定義的選項(xiàng);
  • 聲明命名導(dǎo)出,<script setup>定義的組件默認(rèn)以組件文件的名稱(chēng)作為組件名;
  • 運(yùn)行副作用或者創(chuàng)建只需要執(zhí)行一次的對(duì)象。
<script>
// 普通 <script>, 在模塊范圍下執(zhí)行(只執(zhí)行一次)
runSideEffectOnce()
 
// 聲明額外的選項(xiàng)
export default {
  name: 'ComponentName',    // 組件重命名
  inheritAttrs: false,
  customOptions: {}
}
</script>
 
<script setup>
// 在 setup() 作用域中執(zhí)行 (對(duì)每個(gè)實(shí)例皆如此)
</script>

十六、v-memo新指令

該指令與v-once類(lèi)似,v-once是只渲染一次之后的更新不再渲染,而v-memo是根據(jù)條件來(lái)渲染。該指令接收一個(gè)固定長(zhǎng)度的數(shù)組作為依賴(lài)值進(jìn)行記憶比對(duì),如果數(shù)組中的每個(gè)值都和上次渲染的時(shí)候相同,則該元素(含子元素)不刷新。

1、應(yīng)用于普通元素或組件;

<template>
<-- 普通元素 -->
<div v-memo="[valueA, valueB]">
  ... 
</div>
 
<-- 組件 -->
<component v-memo="[valueA, valueB]"></component>
</template>
 
<script setup>
import component from "../compoents/component.vue"
</script>

當(dāng)組件重新渲染的時(shí)候,如果 valueA 與 valueB 都維持不變,那么對(duì)這個(gè) <div> 以及它的所有子節(jié)點(diǎn)的更新都將被跳過(guò)。

2、結(jié)合v-for使用

v-memo 僅供性能敏感場(chǎng)景的針對(duì)性?xún)?yōu)化,會(huì)用到的場(chǎng)景應(yīng)該很少。渲染 v-for 長(zhǎng)列表 (長(zhǎng)度大于 1000) 可能是它最有用的場(chǎng)景:

<template>
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
  <p>...more child nodes</p>
</div>
</template>

當(dāng)selected發(fā)生變化時(shí),只有item.id===selected的該項(xiàng)重新渲染,其余不刷新。

style新特性

Vue3.2版本對(duì)單文件組件的style樣式進(jìn)行了很多升級(jí),如局部樣式、css變量以及樣式暴露給模板使用等。

一、局部樣式

當(dāng) <style> 標(biāo)簽帶有 scoped attribute 的時(shí)候,它的 CSS 只會(huì)應(yīng)用到當(dāng)前組件的元素上:

<template>
  <div class="example">hi</div>
</template>
 
<style scoped>
.example {
  color: red;
}
</style>

二、深度選擇器

處于 scoped 樣式中的選擇器如果想要做更“深度”的選擇,也即:影響到子組件,可以使用 :deep() 這個(gè)偽類(lèi):

<style scoped>
.a :deep(.b) {
  /* ... */
}
</style>

通過(guò) v-html 創(chuàng)建的 DOM 內(nèi)容不會(huì)被作用域樣式影響,但你仍然可以使用深度選擇器來(lái)設(shè)置其樣式。

三、插槽選擇器

默認(rèn)情況下,作用域樣式不會(huì)影響到 <slot/> 渲染出來(lái)的內(nèi)容,因?yàn)樗鼈儽徽J(rèn)為是父組件所持有并傳遞進(jìn)來(lái)的。使用 :slotted 偽類(lèi)以確切地將插槽內(nèi)容作為選擇器的目標(biāo):

<style scoped>
:slotted(div) {
  color: red;
}
</style>

四、全局選擇器

如果想讓其中一個(gè)樣式規(guī)則應(yīng)用到全局,比起另外創(chuàng)建一個(gè) <style>,可以使用 :global 偽類(lèi)來(lái)實(shí)現(xiàn):

<style scoped>
:global(.red) {
  color: red;
}
</style>

五、混合使用局部與全局樣式

你也可以在同一個(gè)組件中同時(shí)包含作用域樣式和非作用域樣式:

<style>
/* global styles */
</style>
 
<style scoped>
/* local styles */
</style>

六、支持CSS Modules

<style module> 標(biāo)簽會(huì)被編譯為 CSS Modules 并且將生成的 CSS 類(lèi)鍵暴露給組件:

1、 默認(rèn)以$style 對(duì)象暴露給組件;

<template>
  <p :class="$style.red">
    This should be red
  </p>
</template>
 
<style module>
.red {
  color: red;
}
</style>

2、可以自定義注入module名稱(chēng)

<template>
  <p :class="classes.red">red</p>
</template>
 
<style module="classes">
.red {
  color: red;
}
</style>

七、與setup一同使用

注入的類(lèi)可以通過(guò) useCssModule API 在 setup() 和 <script setup> 中使用:

<script setup>
import { useCssModule } from 'vue'
 
// 默認(rèn), 返回 <style module> 中的類(lèi)
const defaultStyle = useCssModule()
 
// 命名, 返回 <style module="classes"> 中的類(lèi)
const classesStyle = useCssModule('classes')
</script>

八、動(dòng)態(tài) CSS

單文件組件的 <style> 標(biāo)簽可以通過(guò) v-bind 這一 CSS 函數(shù)將 CSS 的值關(guān)聯(lián)到動(dòng)態(tài)的組件狀態(tài)上:

<script setup>
const theme = {
  color: 'red'
}
</script>
 
<template>
  <p>hello</p>
</template>
 
<style scoped>
p {
  color: v-bind('theme.color');
}
</style>

參考文獻(xiàn):

SFC 語(yǔ)法規(guī)范 | Vue.js

Vue3.2 setup語(yǔ)法糖、Composition API、狀態(tài)庫(kù)Pinia歸納總監(jiān)

總結(jié)

到此這篇關(guān)于Vue3.2單文件組件setup的語(yǔ)法糖與新特性的文章就介紹到這了,更多相關(guān)Vue3.2單文件組件setup語(yǔ)法糖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue中的?ref,props,mixin屬性

    Vue中的?ref,props,mixin屬性

    這篇文章主要介紹了Vue中的ref,props,mixin屬性,文章圍繞主題ref,props,mixin展開(kāi)詳細(xì)內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • 一文詳解如何在Vue3中使用jsx/tsx

    一文詳解如何在Vue3中使用jsx/tsx

    本篇文章旨在帶領(lǐng)大家快速了解和使用?Vue?中的?JSX?語(yǔ)法,好讓大家在?Vue?中遇到或使用?JSX?的時(shí)候能很快入手,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • vue + axios get下載文件功能

    vue + axios get下載文件功能

    這篇文章主要為大家詳細(xì)介紹了vue + axios get下載文件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • vue.js移動(dòng)端app實(shí)戰(zhàn)1:初始配置詳解

    vue.js移動(dòng)端app實(shí)戰(zhàn)1:初始配置詳解

    這篇文章主要介紹了vue.js移動(dòng)端app實(shí)戰(zhàn)1:初始配置詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • vue中 router.beforeEach() 的用法示例代碼

    vue中 router.beforeEach() 的用法示例代碼

    導(dǎo)航守衛(wèi)主要是通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航,本文通過(guò)示例代碼講解vue中 router.beforeEach() 的用法,感興趣的朋友跟隨小編一起看看吧
    2023-12-12
  • Vue2響應(yīng)式系統(tǒng)介紹

    Vue2響應(yīng)式系統(tǒng)介紹

    這篇文章主要介紹了Vue2響應(yīng)式系統(tǒng),響應(yīng)式系統(tǒng)主要實(shí)現(xiàn)某個(gè)依賴(lài)了數(shù)據(jù)的函數(shù),當(dāng)所依賴(lài)的數(shù)據(jù)改變的時(shí)候,該函數(shù)要重新執(zhí)行,下文更多相關(guān)介紹需要的小伙伴可以參考一下
    2022-04-04
  • vue打開(kāi)新窗口并實(shí)現(xiàn)傳參的圖文實(shí)例

    vue打開(kāi)新窗口并實(shí)現(xiàn)傳參的圖文實(shí)例

    這篇文章主要給大家介紹了關(guān)于vue打開(kāi)新窗口并實(shí)現(xiàn)傳參的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • vue 圖片裁剪上傳組件的實(shí)現(xiàn)

    vue 圖片裁剪上傳組件的實(shí)現(xiàn)

    這篇文章主要介紹了vue 圖片裁剪上傳組件的實(shí)現(xiàn),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-11-11
  • vue實(shí)現(xiàn)通過(guò)手機(jī)號(hào)發(fā)送短信驗(yàn)證碼登錄的示例代碼

    vue實(shí)現(xiàn)通過(guò)手機(jī)號(hào)發(fā)送短信驗(yàn)證碼登錄的示例代碼

    本文主要介紹了vue實(shí)現(xiàn)通過(guò)手機(jī)號(hào)發(fā)送短信驗(yàn)證碼登錄的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • vue3中如何使用iframe嵌入vue2頁(yè)面

    vue3中如何使用iframe嵌入vue2頁(yè)面

    這篇文章主要介紹了vue3中如何使用iframe嵌入vue2頁(yè)面問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評(píng)論