Vue3的 setup 语法糖真香

535 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

Vue系列的知识体系都是相通的,因为项目的需要,需要快速上手Vue3,在简单看过文档和相关视频后,就开始进行开发;刚开始是使用defineComponent的方式,定义的变量和函数都需要return 出去才能在template里面使用,这样就给开发带来一些不便;setup语法糖就巧妙解决了变量,函数以及import引入内容的使用问题;

变量,函数

在中声明的变量,函数不需要return 暴露出去,可以直接在template中使用;

<template>
{{newMessage}}
<button @click="say">点击</button>
</template>

<script setup>
const newMessage = ref('hello world')
const say = () => {console.log('this is a song')}
</script>

怎么样,这样使用是不是特别的方便,快捷,写代码的速度就像加上了加速器,简直nice;

import 引入的内容

  • 通过import 导入的组件会自动注册,直接使用该组件即可,不需要在components中再一次注册;
<template>
<query-component></query-component>
</template>

<script setup>
import QueryComponent from './queryComponet.vue'
</script>
  • 引入的方法或者变量直接使用:
<template>
{{list}}
</template>

<script setup>
import {list } from './list.js'
</script>

// list.js
export const list = [{name: 'John'}]

组件通信

在defineComponet中组件通信使用是setup()函数里面props和context对象,而在setup语法糖中需要使用defineProps和defineEmits,这可以说是setup语法糖独特之处了;

父组件向子组件传值

  • 在父组件中传值的方式和vue2是一样的,使用属性绑定数据;
  • 在子组件中,就要使用defineProps接收数据:
// 接收的数据直接在template使用,直接使用defineProps
defineProps({
message: {typeString}
})

// 在函数中需要用到接收的数据,可以使用props对象接收defineProps的返回值
const props = defineProps({
message: {typeString}
})
console.log(props.message)
  • 如果向更深层次的组件传递数据,例如祖孙组件之间数据传递,可以在中间组件上定义v-bind="$attrs",然后子孙组件使用defineProps接收传过来的数据;

子组件向父组件传值

在defineComponent方式中,使用setup()函数的emits定义自定义事件(最好是驼峰式写法),最后一定要在emits选项中声明;[不声明的话,emit事件也能触发,但是会报警告]:

emits: ['OnSend'],
setup(_props, {emit}) {
const send = () => {
emit('onSend', 'this is a card')
}
}

在setup语法糖中,使用defineEmits定义emit事件:

// 声明emit事件
const emits = defineEmits(['onSend'])
// 触发自定义事件并传递参数
const send = () => {
emits('onSend', 'this is a card')
}
  • 在父组件中监听子组件中触发的事件,使用的方式和Vue2一样,感觉这里满满的熟悉感;

需要主动暴露组件属性:defineExpose

在defineComponet方式中,如果父组件想要获取或者给子组件的属性赋值,可以使用ref的方式:

<child ref="childRef"></child>

export default defineComponent({
setup(){
const childRef = ref(null)
// 给子组件属性赋值
childRef.value.showModal = true
return {
childRef
}
}
})

但是,在setup语法糖的方式中,因为setup是默认关闭的,简单来说,就是通过ref获取组件实例,但是无法进一步获取组件里面声明的属性和方法;如果想要进一步获取,需要使用defineExpose主动向外暴露:

  • 在使用动态组件的时候,需要在父组件中动态变换组件:
// 父组件
<common-dialog ref="commonDialogRef"></common-dialog>

<script setup>
import commonDialog from './commonDialog'

const commonDialogRef = ref(null)
const setDialog = () => {
commonDialogRef.value.component = commonDialogRef.value.childDialog
}
</script>
// commonDialog组件
<componet :is="component"></component>

<script setup>
import {defineExpose} from 'vue'
import childDialog from './childDialog.vue'
const component = ref(null)

// 主动向外暴露
defineExpose({
component,
// 向外暴露子组件
childDialog
})
</script>

在 setup 中使用路由

在Vue2中进行路由跳转可以使用this.$router.push('/admin');取出路由中的参数可以使用this.$route.query.id;但是在Vue3中取消了这两个API,新增了useRouter,useRoute;

  • 具体使用:
import {useRouter,useRoute} from 'vue-router

const router = useRouter()
const route = useRoute()

const click = () => {
router.push('/admin')
alert(route.query.id)
}

上面总结的内容就是项目中经常使用到的点,当然还有许多点需要总结,等以后用到再一次总结! 如果各位小伙伴觉得文章还行,希望多多点赞;也可以在评论区列出自己项目中用到的知识点,互相学习!