对比Vue2.0,Vue3最不一样的就是data()变成了setup()
setup是Vue3中一个新的配置项,值为一个函数
组件中所用的:数据、方法等均要配置在setup中
setup函数的两种返回值:
1、若要返回一个对象,则对象中的属性、方法、在模版中均可以直接使用
2、若返回一个渲染函数:则可以自定义渲染内容(只做一个了解)
<template>
<h1>学生信息</h1>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<button @click="sayHello">点我</button>
</template>
<script>
// import { h } from "vue";
export default {
name: "App",
//此处只是测试一下setup,暂时不考虑响应式的问题
setup() {
//数据
let name = "章三";
let age = 10;
//方法
function sayHello() {
alert(`我是${name},今年${age}岁了,你好啊!`);
}
//返回一个对象(常用)
return {
name,
age,
sayHello,
};
//返回一个函数(渲染函数)
// return () => h("h1", "尚硅谷");
},
};
</script>
注意点:
1、尽量不要与Vue2配置混用
- vue2配置中可以访问到setup中的方法、属性
- 但在setup中不能访问到vue2配置(data、method、computed。。)
- 如果有重名,setup优先
2、setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模版看不到return对象中的属性
但是后期也可以返回一个promise实例,但是需要Supense和异步组件的配合
App组件:
<template> <div class="app"> <h3>我是App组件</h3> <Suspense> <template v-slot:default> <Child /> </template> <template v-slot:fallback> <h3>加载中....</h3> </template> </Suspense> </div> </template> <script> import Child from "./components/Child.vue"; export default { name: "App", components: { Child }, }; </script>
child组件
async setup() { let sum = ref(0) let p = new Promise((resolve,reject)=>{ setTimeout(() => { resolve({sum}) }, 3000); }) return await p }
Vue3接受到的参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
props是用Proxy包裹的一个响应式数据,当传入新的props时,它将被更新
需要注意的是:因为props是响应式的,不能使用Es6结构,因为结构会消除props的响应式。如果需要结构props,可以在setup函 数中使用toRef函数来完成此操作
context:是一个普通的js对象,也就是说,它不是响应式的,可以使用ES6进行解构
export default { setup(props,{attrs,slots,emit}) {} }
App组件:
<template>
<Demo @hello="showHelloMag" msg="你好啊" school="尚硅谷">
<template v-slot:qwe>
<span>尚硅谷</span>
</template>
<template v-slot:asd>
<span>尚硅谷</span>
</template>
</Demo>
</template>
<script>
import Demo from "./components/demo.vue";
export default {
name: "App",
components: { Demo },
setup() {
function showHelloMag(value){
alert(`你好啊,你触发了hello事件,我收到的参数是:${value}`)
}
return {showHelloMag}
}
};
</script>
<style>
</style>
demo.vue组件
<template>
<h1>一个人的信息</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="test">测试触发一个Demo组件的Hello事件</button>
<hr />
<h2>{{ msg }}</h2>
<h2>{{ school }}</h2>
</template>
<script>
import { reactive } from "vue";
export default {
name: "Demo",
props: ["msg", "school"],
emits: ["hello"],
setup(props, context) {
// console.log("我是props", props);
// console.log("我是context", context);
// console.log("---setup---", context.attrs); //相当与Vue2中的$attrs
// console.log('---setup---',context.emit) //触发自定义事件的。
// console.log("---setup---", context.slots); //插槽
let person = reactive({
name: "张三",
age: 18,
});
function test() {
context.emit("hello", 666);
}
return {
person,
test,
};
},
};
</script>
<style>
</style>
总结:
- setup函数中没有this,因为setup函数在beforeCreated之前就执行了,this指向的就是undefined
- setup其本身不可以为异步函数
- setup内可以执行await方法处理异步问题
- setup函数接受两个参数,props和context(context包含3个参数attrs,slots,emit),而context是可以被解构的