setup 语法糖
setup 是 Vue3 中的最重要特性之一,是在组件创建之前, props 被解析之后执行,是组合式 API 的入口。
目前 setup sugar 已经进行了定稿,vue3 + setup sugar + TS 的写法看起来很香,要求版本在 Vue3.2 以上
setup 和 setup 语法糖的区别
起初 Vue3.0 暴露变量必须 return 出来,template 中才能使用; 现在只需在 script 标签中添加 setup,组件只需引入不用注册,属性和方法也不用返回, 也不用写 setup 函数,也不用写 export default,甚至是自定义指令也可以在我们的 template 中自动获得。
<template>
<my-component :num="num" @click="addNum" />
</template>
<script setup>
import { ref } from 'vue';
/*
在script setup中,引入的组件可以直接使用,无需再通过components进行注册,
并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写name属性了
*/
import MyComponent from './MyComponent .vue';
/*
像在平常的setup中一样的写,但是不需要返回任何变量
在此处定义的num可以直接使用
*/
const num = ref(0);
// 函数也可以直接引用,不用在return中返回
const addNum = () => {
num.value++;
};
</script>
使用 setup 语法糖后新增 api
在没有使用语法糖时,我们的 props、emit 可以预先定义,然后在 setup 的入参中获取
//子组件
<template>
<button class="child" @click="foo"></button>
</template>
<script>
props:{
msg:{
type:String,
required:true
}
},
setup(props, context) {
const{emit} = context
const foo = () => {
emit("myevent", 123);
printMsg()
};
const printMsg = ()=>{
console.log(props.msg)
}
return {
foo,
};
},
</script>
//父组件
<template>
<Child @myevent="chuanCan" :msg="msg" />
</template>
<script>
setup() {
const msg = 'i am msg'
const chuanCan = (a: number) => {
console.log(a);
};
return {
chuanCan,
msg
};
},
</script>
在使用语法糖后,要怎么获取到 emit 和 props?
这时候 我们就要用到 Vue 为了使用 setup 语法糖出的新 Api
defineProps
用来接收父组件传来的 props。
示例: 父组件代码
<template>
<div class="die">
<h3>我是父组件</h3>
<yyx-hello :name="name"></yyx-hello>
</div>
</template>
<script setup>
import yyxHello from './yyxHello';
import { ref } from 'vue';
let name = ref('小杨');
</script>
子组件代码
<template>
<div>我是子组件{{name}} //小杨</div>
</template>
<script setup>
import { defineProps } from 'vue';
defineProps({
name: {
type: String,
default: '我是默认值',
},
});
</script>
defineEmit
子组件向父组件事件传递。示例:
//子组件
<template>
<div>我是子组件{name}}<button @click="ziupdata">按钮</button></div>
</template>
<script setup>
import { defineEmits } from 'vue';
//自定义函数,父组件可以触发
const em = defineEmits(['updata']);
const ziupdata = () => {
em('updata', '我是子组件的值');
};
</script>
//父组件
<template>
<div class="die">
<h3>我是父组件</h3>
<zi-hello @updata="updata"></zi-hello>
</div>
</template>
<script setup>
import ziHello from './ziHello'
const updata = (data) => {
console.log(data); /我是子组件的值
}
</script>
defineExpose
//子组件
<template>
<div>我是子组件</div>
</template>
<script setup>
import { defineExpose, reactive, ref } from 'vue';
let ziage = ref(18);
let ziname = reactive({
name: '小杨',
});
//暴露出去的变量
defineExpose({
ziage,
ziname,
});
</script>
父组件
<template>
<div class="die">
<h3 @click="isclick">我是父组件</h3>
<zi-hello ref="zihello"></zi-hello>
</div>
</template>
<script setup>
import ziHello from './ziHello';
import { ref } from 'vue';
const zihello = ref();
//父组件拿到的结果
const isclick = () => {
console.log('接收ref暴漏出来的值', zihello.value.ziage);
console.log('接收reactive暴漏出来的值', zihello.value.ziname.name);
};
</script>
defineExpose 不是唯一获取子组件数据的方法,也可以用 ref 实现
父组件
<script setup>
import { ref } from 'vue';
import Comp from './Comp.vue';
const showComp = ref(null); //这个时候获取了子组件Comp
const childShow = () => {
showComp.value.show(); //调用子组件的show方法
};
</script>
<template>
<button @click="childShow">点击调用子组件方法</button>
<Comp ref="showComp"></Comp>
</template>
子组件Comp.vue
<script setup>
import { ref } from 'vue';
const show = () => {
alert('我是子组件,我的show方法被调用了');
};
// 主动暴露childMethod方法
defineExpose({ show });
</script>
<template>
<div>我是子组件</div>
</template>