vue3+ts实际开发中该如何优雅书写vue3语法

 更新时间:2022年10月29日 15:48:23   作者:double_Fly_  
近尝试上手 Vue3+TS+Vite,所以下面这篇文章主要给大家介绍了关于vue3+ts实际开发中该如何优雅书写vue3语法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

vue3语法的发展

  1. Vue3 在早期版本( 3.0.0-beta.21 之前)中对 composition api 的支持,只能在组件选项 setup 函数中使用。
  2. 在 3.0.0-beta.21 版本中增加了 <script setup> 的实验特性。如果你使用了,会提示你 <script setup> 还处在实验特性阶段。
  3. 在 3.2.0 版本中移除<script setup> 的实验状态,从此,宣告 <script setup> 正式转正使用,成为框架稳定的特性之一。

所以我们现在直接就开始使用3.2.0之后的写法

优势

与组件选项 setup 函数对比, <script setup> 的优点:

  1. 更少、更简洁的代码,不需要使用 return {} 暴露变量和方法了,使用组件时不需要主动注册了;
  2. 更好的 Typescript 支持,使用纯 Typescript 声明 props 和抛出事件,不会再像 option api 里那么蹩脚了;
  3. 更好的运行时性能;
  4. 当然, <script setup> 也是有自己的缺点的,比如需要学习额外的 API。

Composition Api类型约束

<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
 
type User = { 
  name: string
  age: number
}
 
// ref
const msg1 = ref('')  //  会默认约束成 string 类型,因为ts类型推导
const msg2 = ref<string>('')  //  可以通过范型约束类型
const user1 = ref<User>({ name: 'tang', age: 18 })  //  范型约束
const user2 = ref({} as User)  // 类型断言
 
// reactive
const obj = reactive({})
const user3 = reactive<User>({ name: 'tang', age: 18 })
const user4 = reactive({} as User)
 
// computed
const msg3 = computed(() => msg1.value)
const user5 = computed<User>(() => {
  return { name: 'tang', age: 18 }
})
</script>

编译器宏

编译器宏(compiler macros) 有:defineProps、defineEmits、withDefaults、defineExpose 等。

编译器宏只能在 <script setup> 块中使用,不需要被导入,并且会在处理 <script setup> 块时被一同编译掉。

编译器宏必须在 <script setup> 的顶层使用,不可以在 <script setup> 的局部变量中引用

defineProps

<script setup> 块中是没有组件配置项的,也就是说是没有 props 选项,需要使用 defineProps 来声明 props 相关信息。defineProps 接收的对象和组件选项 props 的值一样。

我这边引用了pug 如果需要安装一下就可以直接使用 <template lang="pug">

好处可以减少代码量 层次也清楚

npm install pug
// componentA.vue 组件
<template lang="pug">
div
    div {{`我的名字是${name},今年${age}`}}
    div(v-for="item in list",:key="item.name") {{`我的名字是${item.name},今年${item.age}`}}
</template>
<script setup lang="ts">
interface item {
    name: string,
    age: string
}
const props = defineProps<{
    name: string,
    age: string,
    list?: item[] // ?非必传参数
}>()
</script>
// home.vue 页面
<template lang="pug">
.mainBg
    componentA(:name="name",:age="age", :list="list")
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import componentA from '@/components/componentA.vue';
let name = ref('')
const age = ref('')
const list = ref(
    [
        {
            name: '张三',
            age: '20'
        },
        {
            name: '李四',
            age: 18
        },
        {
            name: '王五',
            age: 25
        },
    ]
)
<style lang="scss">
.mainBg {
    padding: 10px;
}
</style>

这时候是可以看到TS写法里面 name和age是没有定义默认值

页面效果

Vue3 为我们提供了 withDefaults 这个编译器宏,给 props 提供默认值

// componentA.vue 组件
<template lang="pug">
div
    div {{`我的名字是${name},今年${age}`}}
    div(v-for="item in list",:key="item.name") {{`我的名字是${item.name},今年${item.age}`}}
</template>
<script setup lang="ts">
interface item {
    name: string,
    age: string
}
interface Props {
    name: string,
    age: string,
    list?: item[]
}
const props = withDefaults(defineProps<Props>(),{
    name: "小cc",
    age: "18",
    list: ()=> []
})
</script>

这边给它定义默认值之后保存 看页面发现还是没有把默认值展示出来

这是因为我们在home页面给name和age用ref赋值的时候给了 ‘ ’ 所以他把空当成了默认值就没有展示withDefaults里面给的默认值 这时候我们把name和age写成
let name = ref() const age = ref()

还有一种情况 当不给props定义默认值的时候 传参也是为空时

defineEmits

一样的,在 <script setup> 块中也是没有组件配置项 emits 的,需要使用 defineEmits 编译器宏声明 emits 相关信息。

// componentA.vue 组件
<template lang="pug">
div
    div {{`我的名字是${name},今年${age}`}}
    //- div(v-for="item in list",:key="item.name") {{`我的名字是${item.name},今年${item.age}`}}
    el-button(type="primary",@click="setName") 向父组件发送 name
    el-button(type="primary",@click="setAge") 向父组件发送 age
</template>
<script setup lang="ts">
interface item {
    name: string,
    age: string
}
interface Props {
    name: string,
    age: string,
    list?: item[]
}
const props = withDefaults(defineProps<Props>(),{
    name: "小cc",
    age: "18",
    list: ()=> []
})
const emits = defineEmits<{
    (e: 'changeName', value: string) : void,
    (e: 'changeAge', value: string) : void,
}>()
const setName = () => {
    emits('changeName', '小橙子')
}
const setAge = () => {
    emits("changeAge", "28")
}
</script>
// home.vue
<template lang="pug">
.mainBg
    componentA(:name="name",:age="age", :list="list", @changeName="changeName",@changeAge="changeAge")
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import componentA from '@/components/componentA.vue';
let name = ref('')
const age = ref('')
const list = ref(
    [
        {
            name: '张三',
            age: '20'
        },
        {
            name: '李四',
            age: 18
        },
        {
            name: '王五',
            age: 25
        },
    ]
)
const changeName = (val: string) => {
    name.value = val
}
const changeAge = (val: string) => {
    age.value = val
}
<style lang="scss">
.mainBg {
    padding: 10px;
}
</style>

点击后

defineExpose

在 Vue3 中,默认不会暴露任何在 <script setup> 中声明的绑定,即不能通过模板 ref 获取到组件实例声明的绑定。

Vue3 提供了 defineExpose 编译器宏,可以显式地暴露需要暴露的组件中声明的变量和方法。

这个情况的场景父组件需要直接调用子组件内部的方法或者修改子组件里的值时,需要将方法或值通过defineExpose暴露才能操作

// componentB.vue
<template lang="pug">
div
    h1 组件B
    h1 {{msg}}
</template>
<script setup lang="ts">
import {ref} from 'vue'

const msg = ref('今天天气不怎么好')

const changeMsg = (v: string) => {
    msg.value = v
}

// 对外暴露的属性 需要用ref 调用子组件方法是需要把方法暴露出去
defineExpose({
  msg,
  changeMsg,
})
</script>
<template lang="pug">
.mainBg
    el-button(type="primary",@click="handleChangeMsg") 组件B
    componentB(ref="root")
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import componentB from '@/components/componentB.vue';
const root = ref<any>(null)
const handleChangeMsg = () => {
    root.value.changeMsg("果然 下雨了")
}
</script>


<style lang="scss">
.mainBg {
    padding: 10px;
}
</style>

如果把defineExpose注释掉

由于没有把这个方法暴露出来 导致找不到这个方法 changeMsg is not a function

总结

到此这篇关于vue3+ts实际开发中该如何优雅书写vue3语法的文章就介绍到这了,更多相关vue3+ts 书写vue3语法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue源码探究之状态初始化

    Vue源码探究之状态初始化

    这篇文章主要介绍了Vue源码探究之状态初始化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • vue3封装一个带动画的关闭按钮示例详解

    vue3封装一个带动画的关闭按钮示例详解

    这篇文章主要为大家介绍了vue3封装一个带动画的关闭按钮示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 解决Antd输入框卡顿问题以及Pubsub.js的使用方式

    解决Antd输入框卡顿问题以及Pubsub.js的使用方式

    这篇文章主要介绍了解决Antd输入框卡顿问题以及Pubsub.js的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • vue3 学习笔记之axios的使用变化总结

    vue3 学习笔记之axios的使用变化总结

    本篇文章主要旨在帮助正在学vue3或者准备学vue3的同学了解网络请求axios该如何使用,防止接触了一点点vue3的同学会有个疑问。有兴趣的小伙伴可以关注一下
    2021-11-11
  • vue3与elementui封装一个便捷Loading

    vue3与elementui封装一个便捷Loading

    这篇文章主要介绍了vue3与elementui封装一个便捷Loading,,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Vue实战之vue登录验证的实现代码

    Vue实战之vue登录验证的实现代码

    本篇文章主要介绍了Vue实战之vue登录的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • vue 数据双向绑定的实现方法

    vue 数据双向绑定的实现方法

    这篇文章主要介绍了vue 数据双向绑定的实现方法,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-03-03
  • vue单元格多列合并的实现

    vue单元格多列合并的实现

    这篇文章主要介绍了vue单元格多列合并的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • vue3.0+ts引入详细步骤以及语法校验报错问题解决办法

    vue3.0+ts引入详细步骤以及语法校验报错问题解决办法

    Vue 3.0是一个非常流行的JavaScript框架,不仅易于学习和使用,而且可以与许多UI框架集成,下面这篇文章主要给大家介绍了关于vue3.0+ts引入详细步骤以及语法校验报错问题的解决办法,需要的朋友可以参考下
    2024-01-01
  • 让axios发送表单请求形式的键值对post数据的实例

    让axios发送表单请求形式的键值对post数据的实例

    今天小编就为大家分享一篇让axios发送表单请求形式的键值对post数据的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08

最新评论