你好,我是波吉。

  这里是 《Vue3 | 实现精美的待办》 系列文章,波吉 会带大家学一下Vue3。通过做一个小的待办项目,把 Vue3 中常用到的知识点串联起来,为避免篇幅过长,我将分成多期进行讲解~若无特殊说明,后续示例均使用 script setup 语法糖来编写,如果你现在不知道这句话的含义,跟着我的代码走,你慢慢就会理解的!

  我会把项目最终成果的源码放在 https://gitee.com/Jokerlsss/vue3-ts-todo 上,包括 完整的前后端代码及数据库 文件,需要自用的同学,下载下来运行就可以了~ 也希望你花几秒钟的时间帮我点个 star~ ❤这将是我持续创作的动力!


  话不多说,来看下今天需要实现的输入框组件~

在这里插入图片描述
  非常简单!只是对输入框的二次封装,功能如下:

  • 输入内容
  • 按下回车后,将输入内容抛出(后续会将输入内容保存到数据库)
  • 抛出内容后,清空输入框

1. 设计思路

这一部分会带你思考,为了实现这一组件,我们需要用到哪些知识点?与Vue2的实现有何不同?

  1. 双向绑定

  为了实现输入框的双向绑定,我们知道需要用到 v-model。不同的是,在 Vue2 中,只要你将数据声明在 data 配置项中,该数据就是响应式的。在 Vue3 中,这行不通了,一般来说:

  • ref 这个属性,来手动声明一个响应式数据,一般用于声明 值类型,如字符串、数字、布尔等,示例如 let a = ref('')
  • reactive 来手动声明一个响应式数据,一般用于声明 引用类型,如对象、数组等,示例如 let obj = reactive([])

  1. 数据抛出

  为了实现在按下回车后,将输入内容抛出到父组件,在 Vue2 中,我们通常会用到 $emit。而在 Vue3 中,以 script setup 语法糖举例,其写法改为 defineEmits


  1. 暴露方法供父组件调用

  为了实现抛出内容后,将输入框清空,我们封装一个方法 clearInput(),同时为了扩展性,将该方法暴露给父组件,供父组件在合适的时机可以随时调用该方法清空输入框。

  在 Vue2 中,父组件调用子组件方法,只需通过 refs 来调用即可,如 this.$refs.child.method()。而在 Vue3 中,需要你将方法主动暴露,才能在父组件中调用到。暴露的代码为 defineExpose


  1. Props

  为了样式的扩展性,我们在该组件中声明了一个自定义样式的 prop,供父组件调用组件时,可以调整其样式。在 Vue2 中通过 props 配置项来声明,而 Vue3 则是通过 defineProps 来声明。


2. 代码实现

因为我们要学的是 Vue3,因此我对样式代码省略方便阅读,需要完整代码的可以前往项目的 gitee 下载~

<!-- 
  @description: 通用输入框
-->
<template>
  <input
    type="text"
    v-model="inputValue"
    @keyup.enter="submit"
    :style="customStyle"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
let inputValue = ref('')

defineProps({
  // 自定义样式
  customStyle: {
    type: Object,
    default: {}
  }
})

const emit = defineEmits<{
  (e: 'submit', value: string): void
}>()

const submit = () => {
  emit('submit', inputValue.value)
}

const clearInput = () => {
  inputValue.value = ''
}

defineExpose({
  clearInput
})
</script>

<style scoped lang="less">
/* ...省略 */
</style>


3. 代码解读

  1. ref 声明的数据,在 script 中读取和修改时应用 xxx.value 来获取或修改值;而在 template 中读取时,无需 xxx.value

  2. defineEmits 有两种写法,如下

// 第一种写法
const emit = defineEmits<{
  (e: 'submit', value: string): void
}>()
// 第二种写法
const emit = defineEmits(['submit'])

4. 总结

  • refreactive 手动声明响应式数据;获取 ref 声明的值时需调用 xxx.value
  • defineProps 声明组件对外暴露的属性
  • defineEmits 声明子组件调用父组件的方法
  • defineExpose 暴露可供父组件调用的方法

更多推荐