**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
生命周期控制台打印结果:![](https://img.kancloud.cn/2f/0a/2f0afbe3e8af67db63d84c18ae334f9b_291x158.png)
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>
```