欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3.2單文件組件setup的語法糖與新特性總結

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

前言

滿滿的干貨,建議收藏慢慢看,可以當作Vue3.0的學習資料。

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

setup語法糖

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

一、基本用法

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

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

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

二、data和methods

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

<script setup>
import { ref, reactive } from 'vue'    
// 普通變量
const msg = 'Hello!'
 
// 響應式變量
let num = ref(1111)         // ref聲明基本類型變量
const obj = reactive({        // reactive聲明對象類型變量,如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>

三、計算屬性computed

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

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

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

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

2、watchEffect

watchEffect是Vue3.0新增的一個監(jiān)聽屬性的方法,它與watch的區(qū)別在于watchEffect不需要指定監(jiān)聽對象,回調(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 的形式來命名本地自定義指令,可以直接在模板中使用

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

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

 1、導入的模塊內(nèi)容,不需要通過 methods 來暴露它

// 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、導入外部組件,不需要通過components注冊使用

// 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 來聲明 props 和 emits ,它們具備完整的類型推斷并且在 <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">點擊我</button>
</template>
// Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
 
const msg = ref('hello setup !')    // 響應式變量
 
const onAction = function(event) {
    console.log(event)    // child返回值
}
</script>
 
<template>
    <child :info="msg" @change="onAction"></child>
</template>

如果使用了 Typescript,使用純類型聲明來聲明 prop 和 emits 也是可以的。

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

父組件要想通過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">點擊我</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傳值

無論組件層次結構有多深,父組件都可以通過provide 選項來其所有子組件提供數(shù)據(jù),子組件通過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)
 
// 路由跳轉
$router.push('/login')
</script>

十一、對await異步的支持

<script setup> 中可以使用頂層 await。結果代碼會被編譯成 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是一個異步函數(shù),返回一個Promise實例
// console.log('Dom已更新!')
</script>

十三、全局屬性globalProperties

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

十四、生命周期

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

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

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

十五、與普通的script標簽一起使用

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

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

十六、v-memo新指令

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

1、應用于普通元素或組件;

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

當組件重新渲染的時候,如果 valueA 與 valueB 都維持不變,那么對這個 <div> 以及它的所有子節(jié)點的更新都將被跳過。

2、結合v-for使用

v-memo 僅供性能敏感場景的針對性優(yōu)化,會用到的場景應該很少。渲染 v-for 長列表 (長度大于 1000) 可能是它最有用的場景:

<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>

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

style新特性

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

一、局部樣式

當 <style> 標簽帶有 scoped attribute 的時候,它的 CSS 只會應用到當前組件的元素上:

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

二、深度選擇器

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

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

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

三、插槽選擇器

默認情況下,作用域樣式不會影響到 <slot/> 渲染出來的內(nèi)容,因為它們被認為是父組件所持有并傳遞進來的。使用 :slotted 偽類以確切地將插槽內(nèi)容作為選擇器的目標:

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

四、全局選擇器

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

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

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

你也可以在同一個組件中同時包含作用域樣式和非作用域樣式:

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

六、支持CSS Modules

<style module> 標簽會被編譯為 CSS Modules 并且將生成的 CSS 類鍵暴露給組件:

1、 默認以$style 對象暴露給組件;

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

2、可以自定義注入module名稱

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

七、與setup一同使用

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

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

八、動態(tài) CSS

單文件組件的 <style> 標簽可以通過 v-bind 這一 CSS 函數(shù)將 CSS 的值關聯(lián)到動態(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>

參考文獻:

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

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

總結

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

相關文章

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

    Vue中的?ref,props,mixin屬性

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

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

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

    vue + axios get下載文件功能

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

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

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

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

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

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

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

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

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

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

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

    vue實現(xiàn)通過手機號發(fā)送短信驗證碼登錄的示例代碼

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

    vue3中如何使用iframe嵌入vue2頁面

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

最新評論