vue 3.2

目录

新的单文件组件特性

 :is 动态组件

递归组件

命名空间组件

props中使用-----defineProps

运行时声明和类型声明

 props基本用法

  需要注意的点:

运行时声明和类型声明的比较

props的默认值------widthDefaults

自定义事件-----defineEmits

显示的暴露----defineExpose


新的单文件组件特性

  •     <script setup>
  •     更少的样板内容,简洁的代码
  •     可以用纯typeScript 声明props和定义自定义事件。
  •     更好的运行时性能
  •     更好的ide类型推断性能  减少语言服务从代码中抽离类型的工作
  •     <script> 只在组件被首次引入的时候仅执行一次不同
  •     <script setup> 中的代码会在每次组件实例被创建的时候执行。
  •     <script setup> 中的代码,例如初始化的赋值等在组件每次实例创建时都重新执行一次。
 :is 动态组件
  • 递归组件
    • 如果有命名的import导入和组件的推断名冲突了可以使用import别名导入
    • import { Foo as FooChild } from './components'
  • 命名空间组件
    • 可以使用带点的组件标记,例如<Foo.Bar>来引用嵌套在对象属性中的组件。这在需要从这个单个文件中导入多个组件的时候非常有用:
      Components/index.ts 用于导出组件
props中使用-----defineProps
运行时声明和类型声明
  • 运行时声明
    • 只有在运行的时候才可以检测,是否按照类型进行传递
  • 类型声明
    • 这里的类型声明指的是基于ts的类型检测,对props进行类型的约束,因此要使用类型声明,需要基于<script setup lang="ts">
 props基本用法

为了在<script setup>中声明props,必须使用defineProps API,这是一个宏命令,不需要导入可以直接在<script setup>中使用并且只能在它中使用,有两种方法可以使用这个宏命令声明props,运行时声明和类型声明,不同方式下使用这个宏命令后props将具备不同的类型推断。

// 运行时声明:
      // defineProps 运行时声明的基本用法,仅支持运行时校验
      <script setup lang="ts">
        const props = defineProps({
          foo: String,
          bar: {
            type: Number,
            required: true
          }
        })
      </script>
// 接到props直接可以在模板中直接使用,这与vue.x是一致的




// 类型声明
      <script setup lang="ts">
        const props = defineProps<{
          foo?: String,
          bar: number
        }>()
      </script>
  需要注意的点:
  1. 不能同事使用运行时声明和类型声明
    1. defineProps 只能是要么使用运行时声明,要么使用类型声明,同时使用两种声明方式会导致编译报错
  2. 使用类型声明时,静态分析(也就是约束的类型)会自动生成等效的运行时声明,以确保正确的运行时行为
    1. 类型字面量,如string, number,Boolean等
    2. 在同一文件中的interface或类型字面量的引用
      1. props的ts接口只能写在本文件中
      2. <script setup lang="ts">
        // 暂时不支持引入,因为setup 语法糖会将List 编译成一个变量,因此只能在文件内容
        import { List } from "./type"
          interface List {
            id: number,
            content: string,
            isDone: boolean,
          };
          const props = defineProps<{
            title: string,
            list: List[],
          }>();
        </script>
        
        // 现在还不支持复杂的类型和其他文件进行类型导入
        // ts会自动扫描项目中的types来自动导入类型,可以将interface通过namespace的方式来实现自动导入,这样就不需要在文件中引入,直接就可以使用了
        
        // types 文件夹下的list.ts文件
        
        declare namespace List {
          export interface Basic {
            id: number,
            content: string,
            isDone: boolean,
          }
        }
        // 这样是可以支持的
        const props = defineProps<{
          title: string,
          list: List.Basic[],
        }>();

  3. 运行时声明和类型声明的比较
    1. 运行时声明
      1. 优势
        1. 不使用ts的情况下能够对props进行一定的,运行时的类型校验
      2. 劣势
        1. 运行时校验
        2. 只能进行基本类型的校验
        3. 编码时无任何提示
    2. 类型声明
      1. 优势
        1. 完美的支持类型校验,包括props的完美类型约束,父组件在传props时的提示以及子组件在使用props的提示
      2. 劣势
        1. 目前ts的接口只能写在文件内,目前可通过ts自动扫描types来解决

强烈推荐使用类型声明的defineProps

props的默认值------widthDefaults

        defineProps 使用类型声明时的不足之处在于他没有可以给props提供默认值的方式。为了解决这个问题提供了widthDefaults宏命令。

基本用法:

<script setup lang='ts'>
  const props = widthDefaults(defineProps <{
    title?: string,
    list?: List.Basic[],
  }>(), {
    title: 'Hello widthDefaults',
    list: ()=>[{id: 3, content: '3',isDone: false}]
  })
</script>

widthDefaults 辅助函数提供了对默认值的类型检查,并确保返回的props的类型删除了已经声明默认值的属性的可选标志。

 注意点:
         widthDefaults是为了给defineProps使用类型声明时提供添加默认值的方法, 这仅仅适用于<script setup lang='ts'>且defineProps使用类型声明。

自定义事件-----defineEmits

        在<script setup>中声明emit  必须使用defineEmits API,这也是一个宏命令. 同样可采用运行时声明和类型声明式,在类型声明下emit将具备完美的类型推断。

运行时声明:

<script setup lang='ts'>
  const emit defineEmits(['handleClick', 'handleChange']);
  const handleClick = () => emit('handleClick', Date.now()+'');
  const handleChange = () => emit('handleChange', Date.now());
</script>

 类型声明式:

<script setup lang='ts'>
  interface Click {
    id: string,
    value: number,
  }
  // 完美的类型检查
  // List.Basic 是基于ts 自动扫描 types 文件夹以及delcare namespace 自动导入的

  const emit = defineEmits<{
    (e: 'handleClickWithTypeDeclaration', data: Click): void,
    (e: 'handleChangeWithTypeDeclaration', data: List.Basic): void
  }>();
  const handleClickWithTypeDeclaration = () => emit('handleClickWithTypeDeclaration, { id: '1', val: Date.now()});
  const handleChangeWithTypeDeclaration = ()=> emit('handleChangeWithTypeDeclaration', {
    id: 1,
    content: 'change',
    isDone: false
  })
</script>

跟 defineProps 一样,运行时声明和类型声明式同样不可同时使用,且类型声明只能用于在 ts 环境下。

显示的暴露----defineExpose
  1. <script setup>组件默认是关闭的,通过模板ref或$parent链获取的组件实例,并不会暴露任何在<script setup>中声明绑定的(变量,函数)
  2. 为了<script setup>组件中明确要暴露出去的属性,需要使用defineExpose 这个宏命令
<script setup>
  import { ref } from 'vue'
  const a = 1
  const b = ref(2)

  defineExpose({
    a,
    b
  })
</script>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值