Vue3 | 实现精美的待办 | 02.输入框组件封装【附完整项目源码】

22 篇文章 3 订阅

  你好,我是波吉。

  这里是 《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 暴露可供父组件调用的方法
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然,我可以为您提供一个使用 Vite + Vue 3 创建项目,并使用 OpenLayers 封装一个 `MapView` 组件实现高德地图的加载的示例代码。 首先,确保您已经安装了最新版本的 Node.js。然后,按照以下步骤创建项目: 1. 打开终端并创建一个新的项目文件夹: ``` mkdir vite-vue3-openlayers cd vite-vue3-openlayers ``` 2. 初始化一个新的 npm 项目: ``` npm init -y ``` 3. 使用以下命令安装 Vite: ``` npm install create-vite@latest -g ``` 4. 使用 Vite 创建一个新的 Vue 3 项目: ``` create-vite ``` 在提示中选择 `vue-ts` 作为项目模板,并输入项目名称。 5. 进入项目文件夹: ``` cd your-project-name ``` 6. 安装 OpenLayers: ``` npm install ol --save ``` 7. 在 `src/components` 文件夹中创建一个名为 `MapView.vue` 的组件文件,并添加以下代码: ```vue <template> <div ref="mapContainer" class="map-container"></div> </template> <script> import { ref, onMounted } from 'vue' import { Map, View } from 'ol' import { Tile as TileLayer } from 'ol/layer' import { XYZ as XYZSource } from 'ol/source' export default { name: 'MapView', setup() { const mapContainer = ref(null) onMounted(() => { const map = new Map({ target: mapContainer.value, layers: [ new TileLayer({ source: new XYZSource({ url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}' }) }) ], view: new View({ center: [0, 0], zoom: 2 }) }) }) return { mapContainer } } } </script> <style scoped> .map-container { width: 100%; height: 100%; } </style> ``` 8. 在 `src/App.vue` 文件中引入并使用 `MapView` 组件: ```vue <template> <div id="app"> <h1>Hello Vite + Vue 3</h1> <MapView /> </div> </template> <script> import MapView from './components/MapView.vue' export default { components: { MapView } } </script> <style> #app { text-align: center; } </style> ``` 9. 启动开发服务器: ``` npm run dev ``` 现在,您可以在浏览器中访问 `http://localhost:3000` 查看使用 OpenLayers 封装的 `MapView` 组件加载高德地图的 Vue 3 应用程序。 请注意,这只是一个简单的示例,您可以根据自己的需求进一步调整地图的样式和行为。 祝您使用 Vite + Vue 3 和 OpenLayers 进行开发成功!如有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值