• 浅析setup sugar:使用与不使用 script setup 的繁杂性对比、具体如何使用 script setup、setup存在的限制(配置项缺失的处理)


    一、使用与不使用 script setup 的对比

    1、不使用 script setup 的繁杂性

      我们之前的组件可能是这样的:

    <template>
      <div>
        <Card>{{msg}}</Card>
      </div>
    </template>
    <script lang="ts">
    import { ref, defineComponent } from "vue";
    import Card from "./components/Card.vue";
    
    export default defineComponent({
      components: {
        Card,
      },
      setup() {
        const msg = ref("setup script");
        return { msg };
      }
    });
    </script>

      这里做了两件事,一个是导入并注册组件,一个是导出一个字符串给template使用。

      如果模板上要使用的这些变量,必须要在 setup 返回的对象中定义。暴露变量必须 return 出来,如果我们内容很多的话,那么这个 setup 就会返回很多值,动辄十几二十行,也是挺繁琐的。有没有更简单的办法,于是 script setup 语法出现。使用这个语法只需要在 script 标签上加上 setup 属性。

    2、script setup 使用:启用setup script之后是这样的

      vue3.2 将这个之前的实验功能变为正式功能,在单文件组件中引入了一种新的脚本类型:< script setup >

    <script lang="ts" setup>
    import { ref } from "vue";
    import Card from "./components/Card.vue";
    const msg = ref("setup script");
    </script>

      这里省去了组件的注册步骤,也没有显式的导出变量的动作。你只需要在script上配置setup即可。

    <script setup>
      import { ref } from 'vue'
      // 像在平常的setup中code,但是不需要返回任何变量
      const count = ref(0)//在此处定义的count可以直接在模板html中引用
      const inc = () => {//函数也可以直接引用,而不用返回
        count.value++
      }
    </script>
    <template>
      <Foo :count="count" @click="inc" />
    </template>

      当 <script> 标签具有 setup 属性时,组件在编译的过程中代码运行的上下是 setup() 函数中。所有ES模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。

      其实 script setup 就相当于在编译运行是把代码放到了 setup 函数中运行,然后把导出的变量定义到上下文中,并包含在返回的对象中。

    二、如何使用 script setup 语法

    1、导出变量和方法:在setup script里面定义的所有变量都会自动导出,非常方便。

    2、使用组件:所有的组件导入即可自动注册。

      需要注意一点的是:如何定义组件名 => name?

      在 script setup 中,引入的组件可以直接使用,无需再通过components进行注册,并且无法指定当前组件的名字,它会自动以文件名为主

      如果需要定义类似 name 的属性,可以再加个平级的 script 标签,在里面实现即可。

    3、使用 props - defineProps:使用 props 需要用到defineProps来定义,具体用法跟之前的 props 写法类似。

      通过 defineProps 指定当前 props 类型的同时,获得上下文的props对象

      在 script中 需要 props[key] 引用,而 template 中可直接调用 key。

    <script lang="ts" setup>
    import { defineProps } from "vue";
    const props = defineProps(['title', 'content']);
    </script>
    
    // 给props定义类型:
    const props = defineProps({
      title: String,
      content: {
          type: Stirng,
          required: true
      }
    });
    
    // 使用TS的注解的方式:
    defineProps<{
      title?: string
      content: string
    }>();

    4、使用 emits - defineEmit:使用defineEmit定义当前组件含有的事件,并通过返回的上下文去执行 emit

      使用 defineEmit 对组件里面使用到的事件进行验证和定义,具体用法跟之前一样。

    const emit = defineEmit(['onHeaderClick'])
    emit('onHeaderClick', 'params')
    
    // 还可以对事件进行验证
    const emit = defineEmit({
        onHeaderClick: ({title}) => {
            if(!title) {
                console.warn('Invalid title')
                return false
            }
            return true
        }
    })

    5、使用 context - useContext:使用 useContext 获取上下文。

      可以通过useContext从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrsuseSlots

    import { useContext } from 'vue'
    const { slots, attrs } = useContext()
    // 获取到的slots attrs跟之前的setup里面的是一样的。

    6、使用Slots和Attrs:需要useSlots, useAttrs

    <script setup>
    import { useSlots, useAttrs } from 'vue'
    const slots = useSlots()
    const attrs = useAttrs()
    </script>

    7、指令:指令跟组件一样,导入自定注册。

    <script setup>
      import {color as superColor} from './v-color'
    </script>
    
    <template>
      <div v-super-color />
    </template>
    // 导入的 color 重命名为 superColor,并自动映射为指令v-super-color

    8、defineExpose API

      传统的写法,我们可以在父组件中,通过 ref 实例的方式去访问子组件的内容,但在 script setup 中,该方法就不能用了,setup 相当于是一个闭包,除了内部的 template 模板,谁都不能访问内部的数据和方法。

      如果需要对外暴露 setup 中的数据和方法,需要使用 defineExpose API。示例:

    <script setup>
    import { defineExpose } from 'vue'
    const a = 1
    const b = 2
    defineExpose({
        a
    })  // 将 a 暴露出去
    </script>

    三、setup 目前存在的限制

    1、配置项的缺失:修改选项配置需要单开一个 script

      有时候我们需要更改组件选项,在 setup 中我们目前是无法做到的。我们需要在上方再引入一个 script,在上方写入对应的 export 即可。

    <script>
       export default {
           name: 'YourName',
           inheritAttrs: false,
           customOptions: {},
       } 
    </script>
    <script setup>
      // your code
    </script>

      注意:Vue 3 SFC 一般会自动从组件的文件名推断出组件的 name。在大多数情况下,不需要明确的 name 声明。唯一需要的情况是当你需要 <keep-alive> 包含或排除或直接检查组件的选项时,你需要这个名字。

  • 相关阅读:
    系统综合实践 第1次实践作业
    Linq 中按照多个值进行分组(GroupBy,Count)
    敏捷开发综述
    心率
    二维数组 子数组和的最大值
    电梯调度算法
    课堂测试用例。。。
    分析文本文件中各单词出现的频率,并把频率最高的十个词打印出来
    dwz tree组件 取得所选择的值
    SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误
  • 原文地址:https://www.cnblogs.com/goloving/p/15411476.html
Copyright © 2020-2023  润新知