Vue 3 中的 setup

在这里插入图片描述

前言

随着vue 3的发布,新增和大改了很多的东西,像响应式的修改、option Api改为components Apisetup语法糖等等,vue 3的发布可以说是令人不得不爱❤️,相较于v2我是比较喜欢v3的。言归正传,本文的主人公不是别的,是v3中使用起来超nice的setup语法糖。

简介

setup 是在单文件组件 (SFC) 中使用组合式 API 的编译时的一个语法糖。当同时使用 SFC组合式 API 时该语法是默认推荐。

优势:

  • 更少的样板内容,更简洁的代码。
  • 能够使用纯TypeScript声明props和自定义事件。
  • 更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。
  • 更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。

使用

<script setup>
...
</script>

其实在v3刚出来的时候还并不能这样写,他需要像下面这样写。

<script>
export default {
    
    
    setup () {
    
    
        const name = ''
        return {
    
    
            name
        }
    }
}
</script>

3.2的版本开始后我们就可以像最开始那样在SFC但文件中写了。这样写真的超方便,我们不用在return出去我们的方法和变量,但需要注意的是setup这玩意中是没有this这种东西的,为啥呢?我们看一下vue的生命周期图。

image.png

我们从上面的图中可以发现,setuprenderer后就会执行,此时vue还没有进行init Options Api,也就是组件实例未被创建/解析前,所以是不存在this的。

相关拓展

Components 注册使用

在之前的版本我们需要引入组件并且注册后才可以在template模版中使用,但在setup中,我们无需注册,只需要引入就可以使用。但有个弊端就是,无法重命名组件;组件名需要以大驼峰的形式;如果想要重命名组件名字的话只能写两个script标签来实现。

<template>
    <div>
        <span>我是父组件</span>
        <br />
        <Child></Child>
    </div>
</template>

<script setup>
import Child from "./components/child.vue"

</script>

image.png

Props

props这一块和vue2的区别不是很大,父组件还是一样,只是子组件有些变化。我们在子组件中需要通过defineProps来声明我们父组件可以传递的props,然后我们在子组件中进行使用。

<template>
    <div>
        <span>我是子组件: {
    
    {
    
     message }}</span>
    </div>
</template>

<script setup>
import {
    
     defineProps } from 'vue';

const props = defineProps({
    
    
    message: {
    
    
        type: String,
        default: ''
    }
})

</script>

image.png

这里之所以要声明一个变量来接收defineProps,是因为template模版可以为我们自动解析,但script标签内并不会,如果我们需要在script内使用的话是用不到的。

console.log(message)

image.png

但我们如果通过接收defineProps的变量来获取是可以获取到的。这里需要注意的是跟v2一样,props里的值子组件不可更改。

console.log(props.message)

image.png

emit

emit事件注册。跟props一样,需要通过defineEmits来注册。emit + propsvue中常用的一种父子组件通信方式。

该方法接受一个事件名的数组,在调用时进行指定事件名和回调参数。

const emit = defineEmits(['init'])

setTimeout(() => {
    
    
    emit('init', 1222)
}, 2000);

父组件

<template>
    <div>
        <span>我是父组件</span>
        <br />
        <Child message="我是父组件传递的 msg 值" @init="init"></Child>
    </div>
</template>

<script setup>
import Child from "./components/child.vue"

const init = (event) => {
    
    
    console.log(event);
}

</script>

image.png

ref

ref非彼ref,这里指的是ref(引用)。别搞混了,各位客官。

通过ref引用我们可以很便捷的操作和获取子组件内的变量或者方法。我们需要像ref响应式一样声明,然后在子组件上挂载使用。

<template>
    <div>
        <span>我是父组件</span>
        <br />
        <Child ref="myChild" message="我是父组件传递的 msg 值" ></Child>
    </div>
</template>

<script setup>
import Child from "./components/child.vue"

const myChild = ref(null)

</script>

一起猜猜下面代码打印出来的内容是啥。

setTimeout(()=>{
    
    
    console.log(myChild.value.name);
}, 1000)

到了万众瞩目的时刻了,公布期待已久的结果,看看你有没有猜对。

答案是:undefined

image.png

为了让你们死心,给你看看子组件的内容,我是没改过的。

<template>
    <div>
        <span>我是子组件: {
    
    {
    
     message }}</span>
        <span>{
    
    {
    
     name }}</span>
    </div>
</template>

<script setup>
import {
    
     defineProps } from 'vue';

const props = defineProps({
    
    
    message: {
    
    
        type: String,
        default: ''
    }
})

const name = '我是子组件:张三'


</script>

这里我们就不得不谈到下面的defineExpose了,各位看官一起往下走起。

defineExpose

vue3中,我们子组件中的东西需要让父组件调用的话,都需要暴露出去,才可以让外部调用,否则就会向上面的那个例子一样。ei,这里需要插一嘴,暴露给template和外部不是同一个东西哦。

defineExpose({
    
    
    name
})

现在我们再来看看,他是否还是undefined了呢?

叮咚,公布啦!它不再是undefined了。

image.png

最后

下图是写本篇文章的一个环境列举。

  • vue3.2.45
  • vite4.0.2
  • @vitejs/plugin-vue4.0.0

以上就是vue3中的setup相关的一些描述,若有不足欢迎各位大佬/朋友指正、评论。

猜你喜欢

转载自blog.csdn.net/qq_44500360/article/details/128405532