**1. setup函數**
1.理解:Vue3.0中一個新的額配置項,值為一個函數
2.setup是所有Composition API(組合api) “表演的舞臺”
3.組件中所用到的:數據、方法等等,均要配置在setup中
4.setup函數的兩種返回值:
若返回一個對象,則對象中的屬性、方法,在模板中均可以直接使用。(重點關注)
若返回一個渲染函數:則可以自定義渲染內容。
5.注意點:
盡量不要與Vue2.x配置混用
Vue2.x配置(data ,methos, computed…)中訪問到setup中的屬性,方法
但在setup中不能訪問到Vue2.x配置(data.methos,compued…)
如果有重名,setup優先
setup不能是一個async函數,因為返回值不能是return的對象,而是promise,模板看不到return對象中的屬性
```
import {h} from 'vue'
//向下兼容,可以寫入vue2中的data配置項
module default {
name: 'App',
setup(){
//數據
let name = '張三',
let age = 18,
//方法
function sayHello(){
console.log(name)
},
//f返回一個對象(常用)
return {
name,
age,
sayHello
}
//返回一個函數(渲染函數)
//return () => {return h('h1','學習')}
return () => h('h1','學習')
}
}
```
**2.ref 函數**
作用:定義一個響應式的數據
語法: const xxx = ref(initValue)
創建一個包含響應式數據引用對象(reference對象)
JS中操作數據:xxx.value
模板中讀取數據:不需要.value,直接:{{xxx}}
備注:
接收的數據可以是:基本類型、也可以是對象類型
基本類型的數據:響應式依然靠的是Object.defineProperty()的get和set完成的
對象類型的數據: 內部”求助“了Vue3.0中的一個新的函數——reactive函數
**3.reactive 函數**
作用:定義一個對象類型的響應式數據(基本類型別用他,用ref函數)
語法:const 代理對象 = reactive(被代理對象)接收一個對象(或數組),返回一個代理對象(proxy對象)
reactive定義的響應式數據是”深層次的“
內部基于ES6的Proxy實現,通過代理對象操作源對象內部數據進行操作
**4.reactive對比ref**
從定義數據角度對比:
ref用來定義: 基本數據類型
reactive用來定義: 對象(或數組)類型數據
備注: ref也可以用來定義對象(或數組)類型數據,它內部會自動通過reactive轉為代理對象
從原理角度對比:
ref通過Object.defineProperty()的get和set來實現響應式(數據劫持)
reactive通過Proxy來實現響應式(數據劫持),并通過Reflect操作源對象內部的數據
從使用角度對比:
ref定義數據:操作數據需要 .value ,讀取數據時模板中直接讀取不需要 .value
reactive 定義的數據: 操作數據和讀取數據均不需要 .value
**5.setup的兩個注意點**
setup執行的時機
在beforeCreate之前執行一次,this是undefined
生命周期控制臺打印結果:
setup的參數
props:值為對象,包含: 組件外部傳遞過來,且組件內部聲明接收了屬性
context:上下文對象
attrs: 值為對象,包含:組件外部傳遞過來,但沒有在props配置中聲明的屬性,相當于 this.$attrs
slots:收到插槽的內容,相當于$slots
emit: 分發自定義事件的函數,相當于this.$emit
```
//父組件
<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/test3.vue';
const hello = (val) =>{
console.log('傳遞的參數是:'+ val);
}
</script>
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="傳遞吧" @hello="hello">
<template v-slot:cacao>
<span>是插槽嗎</span>
</template>
<template v-slot:qwe>
<span>meiyou</span>
</template>
</HelloWorld>
</template>
```
```
//子組件
export default {
name: 'test3',
props: ['msg'],
emits:['hello'],
//這里setup接收兩個參數,一個是props,一個是上下文context
setup(props,context){
/**
* props就是父組件傳來的值,但是他是Porxy類型的對象
* >Proxy:{msg:'傳遞吧'}
* 可以當作我們自定義的reactive定義的數據
*/
/**
* context是一個對象 包含以下內容:
* 1.emit觸發自定義事件的
* 2.attrs 相當于vue2里面的 $attrs 包含:組件外部傳遞過來,但沒有在props配置中聲明的屬性
* 3.slots 相當于vue2里面的 $slots
* 3.expose 是一個回調函數
*/
console.log(context.slots);
let person = reactive({
name: '張三',
age: 17,
})
function changeInfo(){
context.emit('hello', 666)
}
//返回對象
return {
person,
changeInfo
}
//返回渲染函數(了解) 這個h是個函數
//return () => h('name','age')
}
}
</script>
```