由於原來vue3中的setup Composition API 語法太過於冗長麻煩,官方又出了這么個語法糖,非常的好用了。
這里介紹一些常用的語法:
一、如何開始使用?
1、需要關閉vetur
插件,安裝Volar
插件
2、tsconfig.json / jsconfig.json
文件 ,在compilerOptions
里面加上 "strict": true,和 "moduleResolution": "node"
3、直接在script標簽加入setup 或者 setup lang="ts"
<script setup>
</script>
或者使用TypeScript
<script setup lang="ts">
</script>
script setup
里面的代碼會被編譯成組件setup()
函數的內容。這意味着與普通的 script
只在組件被首次引入的時候執行一次不同,script setup
中的代碼會在每次組件實例被創建的時候執行。
當使用 script setup 的時候,任何在script setup聲明的頂層的綁定 (包括變量,函數聲明,以及 import 引入的組件、方法等內容) 都能在模板中直接使用
import 導入的內容也會以同樣的方式暴露。意味着可以在模板表達式中直接使用導入的函數,並不需要通過 methods
script-setup
無法指定當前組件的名字,所以使用的時候以文件名為主
<template>
<div @click="test">{{ name}}</div>
<div>{{dateFomat('2022-02-18')}}</div>
<HomeComponent />
</template>
<script setup>
import { dateFomat} from './utils'
import HomeComponent from './MyComponent.vue'
import { ref , reactive } from 'vue'
// 簡單變量
const name= ref('Lilei!')
//復雜變量
const user =reacrive({
name:"韓梅梅",
age:18
})
// 函數
const test =() => {
console.log('hello')
}
</script>
二、prop父組件給子組件傳值
在 <script setup>
中必須使用 defineProps API 來聲明 props ,它們具備完整的類型推斷並且在 <script setup>
中是直接可用的:
父組件中給子組件傳值
<template>
<myson info="子組件prop接收" ></myson>
</template>
<script setup lang="ts">
import myson from './myson.vue'
</script>
子組件獲取prop
第一種方式:使用 JavaScript 原生構造函數進行類型規定。
<template>
<p>{{ info }}</p>
</template>
<script setup lang="ts">
import { defineProps } from 'vue'
// 子組件使用defineProps接收父組件prop參數,類型是大寫開頭
defineProps({
info: {
type: String,
required: false,
default: '我是prop傳值'
}
})
<script>
第二種方式:使用 TypeScript 的類型注解。
defineProps 也是可以使用尖括號 <> 來包裹類型定義,緊跟在 API 后面,另外,由於 defineProps 返回的是一個對象(因為 props 本身是一個對象),所以尖括號里面的類型還要用大括號包裹,通過 key: value 的鍵值對形式表示
defineProps<{ name: string }>();//這里是類型string是小寫的,而第一中方式是大寫的,注意一下
如果有多個 prop ,就跟寫 接口 interface 一樣,注意類型都是小寫開頭
defineProps<{
name: string;
phoneNumber: number;
userInfo: object;
tags?: string[]; //?號表示這個是可選的
}>();
注意這里的userInfo 類型也可以寫一個接口
interface UserInfo {
id: number;
age: number;
}
defineProps<{
name: string;
userInfo: UserInfo;
}>();
attrs 的接收父組件的傳值
attrs 和 props 很相似,也是基於父子通信的數據,如果父組件綁定下來的數據沒有被指定為 props ,那么就會被掛到 attrs 這邊來。
setup script 中使用 useAttrs 來獲取attrs
父組件中
<template>
<myson msg="hello world" ></myson>
</template>
<script setup lang="ts">
import myson from './myson.vue'
</script>
子組件沒有使用prop接收,就會到attr中
// 導入 useAttrs 組件
import { useAttrs } from 'vue'
// 獲取 attrs
const attrs = useAttrs()
// attrs是個對象,和 props 一樣,需要通過 key 來得到對應的單個 attr
console.log(attrs.msg);
三、子組件使用emits觸發父組件的方法
setup script
api中使用 defineEmits 來定義emit觸發父組件事件,用法如下:
子組件中
<template>
<button @click="triggerFatherAdd">點擊觸發父組件add</button>
</template>
<script setup lang="ts">
import { defineEmits } from 'vue'
// 子組件使用defineEmits向父組件拋出事件
const emits = defineEmits(['add', 'update'])//事件數組
// 觸發調用子組件時的自定義事件add
const triggerFatherAdd = () => {
emits('add', '新增數據')//后面是參數
}
</script>
父組件中使用子組件自定義事件@add=“父組件中的事件處理”
<template>
<myson @add="add" ></myson>
</template>
<script setup lang="ts">
import myson from './myson.vue'
const add = (msg:string) => {
console.log('add', msg)
}
</script>
四、ref獲取這個子組件對象
在之前的語法中,通過ref獲取子組件的數據都是默認隱式暴露給父組件的,而script setup
默認是不暴露子組件數據的,暴露數據需要 defineExpose api的支持
基本用法也很簡單,它本身是一個函數,可以接受一個對象參數。
在子組件里,把需要暴露出去的數據通過 key: value 的形式作為入參
子組件中的寫法:
<script setup lang="ts">
import { defineExpose } from 'vue'
// 定義一個想提供給父組件拿到的數據
const msg: string = 'Hello World!';
// 顯示暴露的數據,才可以在父組件拿到
defineExpose({
msg
});
</script>
父組件通過綁定ref拿到數據
<template>
<myson ref="son" ></myson>
</template>
<script setup lang="ts">
import { ref , onMounted } from 'vue'
//1、定義一個變量,變量的名字需要和上面ref的一致
const son=ref()
//2、通過 .value 獲取數據,但是需要頁面掛載后才能拿到ref數據,在此之前都是 undefined
console.log(son.value) //undefined
onMounted(() => {
const getsonMsg = son.value.msg
console.log(getsonMsg) //Hello World!
})
</script>
五、使用 provide 給子孫組件傳值和 inject 接收父組件的值
父組件中使用provide
<script setup lang="ts">
import { provide } from "vue";
const curUserId = 168 //可以是簡單類型,也可以是復雜類型
provide('curUserId', curUserId)
</script>
子孫組件中獲取
<script setup lang="ts">
import { inject } from "vue";
const curUserId= inject('curUserId')
</script>
六、style中使用v-bind
直接上代碼:
<template>
<span> 有開始循環了-開端 </span>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
color: 'red'
})
</script>
<style scoped>
span {
/* 使用v-bind綁定state中的變量 */
color: v-bind('state.color');
}
</style>
更新中。。。