Vue3组件(五)封装一个更好用的url组件

简介: 官网有一个url组件的例子,但是比较简陋,基本不太好用,那么我们来完善一下。

官网有一个url组件的例子,但是比较简陋,基本不太好用,那么我们来完善一下。


image.png


官网还是很灵活的嘛,把三个部分都给分开演示了。那我们就把他们合并在一起把。


image.png


定义共用函数(改进版)



接收父组件的v-model的属性值,并且提交数据的代码抽象出来放在独立的js文件里面,这样各种组件就都可以拿来用了。


// controlManage.js
import { ref, watch } from 'vue'
/**
* 控件的赋值、提交的统一管理函数
** 属性:
* ** props: 组件的属性,获取modelValue,和meta
* ** context: 上下文获取emit,提交数据
** 返回:
* ** value:绑定到组件的值
* ** mySubmit:向父组件提交的事件
*/
const controlManage = (props, context) => {
  // 用于绑定控件的值。
  const value = ref(props.meta.defaultValue)
  // 获取父组件设置的属性
  const _value = props.modelValue
  // 设置控件值。如果有属性值(修改状态)则把属性值设置给控件值。
  if (!(_value === '' || _value === 0 || _value === null)) {
    value.value = _value
  }
  // 监听 modelValue 属性,给 value 赋值
  watch(() => props.modelValue, (v1, v2) => {
    // console.log('controlManage监听属性变化', v1)
    value.value = v1
  })
  // 向父组件提交事件
  const mySubmit = (val) => {
    context.emit('update:modelValue', val)
    context.emit('input', val)
  }
  return {
    /**
    * 用于绑定控件的值。
    ** 添加状态可以获取默认值。
    ** 修改状态可以设置 modelValue 值
    ** 监听 modelValue 属性,给value 赋值
    */
    value,
    /**
    * 向父组件提交事件
    ** 可以直接绑定到组件的事件,
    ** 也可以套个娃。
    */
    mySubmit
  }
}
export default controlManage
复制代码


注释与提示


这样写注释可以出现提示,便于调用的时候查看。


image.png


image.png


流程


  • 定义value用于绑定控件值。


  • 添加状态:把默认值设置给value;


  • 修改状态:把v-model设置给value;


  • 监听父组件的v-model,有变化就设置给value。


  • input事件或者其他事件的时候,提交给父组件。


定义url的管理类



我习惯把相关功能写在一个单独的类里面,setup能不写就尽量不写,这样看着清爽。


/**
 * 处理url的管理类
 * * 功能:
 * ** 提交拼接后的完整的url
 * ** 提供绑定控件值、事件
 * ** 修改时自动拆分属性
 * * 参数:
 * ** value: control类的value
 * ** mySubmit: control类的mySubmit,直接就提交了
 */
const urlManage = (value, mySubmit) => {
  // 把url分成三份处理
  const url = reactive({
    http: 'Https://',
    com: '.com',
    value: ''
  })
  // 域名后缀
  const comList = [
    { value: '.com' },
    { value: '.cn' },
    { value: '.net' },
    { value: '.com.cn' },
    { value: '.net.cn' },
    { value: '.org.cn' },
    { value: '.org' },
    { value: '.top' },
    { value: '.vip' },
    { value: '.中国' },
    { value: '.企业' },
    { value: '.公司' },
    { value: '.网络' }
  ]
  // 拆分属性,给url赋值
  watch(() => value.value, (v1, v2) => {
    const arrUrlAll = v1.toLowerCase().split('://')
    console.log('===============================================')
    console.log('父组件:', v1)
    // 判断 ://
    if (arrUrlAll.length === 1) { // 没有http://,直接算作url.value
      url.value = arrUrlAll[0]
    } else if (arrUrlAll.length === 2) {
      url.http = arrUrlAll[0] + '://'
      // 有http://,用 . 拆分后面的
      const arrUrl = arrUrlAll[1].split('.')
      const len = arrUrl.length
      let endPosition = 0
      switch (len) {
        case 1: // 只有一个,直接算作url.value
          url.value = arrUrl[0]
          break
        case 2: // 有两个,一个是url.value,一个是com
          url.value = arrUrl[0]
          url.com = '.' + arrUrl[1]
          break
        default: // 有两个以上,判断两个后缀的情况
          if (arrUrl[len - 1] === 'cn' && (arrUrl[len - 2] === 'com' || arrUrl[len - 2] === 'net' || arrUrl[len - 2] === 'org')) {
            endPosition = len - 2
            url.com = '.' + arrUrl[endPosition] + '.cn'
          } else {
            endPosition = len - 1
            url.com = '.' + arrUrl[endPosition]
          }
          url.value = arrUrl[0]
          for (let i = 1; i < endPosition; i++) {
            url.value += '.' + arrUrl[i]
          }
      }
    }
  })
  // com的查询事件
  const querySearch = (str, cb) => {
    const results = str
      ? comList.filter((item) =>
        item.value.indexOf(str.toLowerCase()) === 0)
      : comList
    // 调用 callback 返回建议列表的数据
    cb(results)
  }
  // url的三个change事件
  const urlSubmit = () => {
    mySubmit(url.http + url.value + url.com)
  }
  return {
    url,
    querySearch,
    urlSubmit
  }
}
复制代码


  • url


因为要把url拆分成三份,于是就定义了一个对象。


  • 域名的后缀


先来看看有多少种后缀。


image.png


新网的域名,是不是很多?而且还有四个特殊的,.com.cn、.net.cn、.gov.cn、.org.cn,别的都是一个点,这四位两个点。 实在太多,这里只把常用的放在列表里面,其他的可以自行填写。


  • 添加状态


这个比较简单,把三个分开的部分合并在一起,然后提交就可以了。


  • 修改状态


这个就有点麻烦,需要把完整的url拆分开分别赋值。 没想到更好的方法,先用本办法来实现,以后想到更好的再优化。


定义url组件



组件就简单了,引用两个js文件,一拼接就好。


<template>
  <el-input
    :placeholder="meta.placeholder"
    :maxlength="meta.maxlength"
    v-model="url.value"
    @input="urlSubmit"
  >
    <template #prepend><!--前面的选项-->
      <el-select style="width: 90px;"
        v-model="url.http"
        @change="urlSubmit"
        placeholder="请选择">
          <el-option label="Http://" value="Http://"></el-option>
          <el-option label="Https://" value="Https://"></el-option>
      </el-select>
    </template>
    <template #append><!--后面的域名后缀-->
      <el-autocomplete style="width: 100px;"
        class="inline-input"
        v-model="url.com"
        :fetch-suggestions="querySearch"
        placeholder="请输入内容"
        @select="urlSubmit"
        @change="urlSubmit"
      ></el-autocomplete>
    </template>
  </el-input>
</template>
复制代码


export default {
  name: 'nf-el-from-url',
  props: {
    modelValue: String,
    meta: metaInput
  },
  emits: ['input', 'change', 'blur', 'focus', 'clear'],
  setup (props, context) {
    const { value, mySubmit } = controlManage(props, context)
    // const { url, querySearch, urlSubmit } = urlManage(value, mySubmit)
    return {
      ...urlManage(value, mySubmit)
      // querySearch, // com的筛选的函数
      // url, // url 相关的值
      // urlSubmit // 触发事件
    }
  }
}
复制代码


  • 模板


基于element-plus提供的组件修改。


  • return


一般是在setup里面先把函数引用进来,获取内部对象,然后在返回。 那么如果没有其他操作的话,可以直接在return里面使用解构的方式直接返给模板。


好了,基本就是这样。简单测试通过。工程化的不方便做在线演示,所以先不做演示了。


效果



image.png


域名后缀可选可填,支持修改状态。只是不知道后面的背景色怎么调。


源码



github.com/naturefwvue…



相关文章
|
3月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
327 2
|
6月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
816 0
|
8月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1047 4
|
6月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
6月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
514 8
|
6月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
289 1
|
8月前
|
存储 JavaScript 前端开发
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
649 6
|
6月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
274 0
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
586 161
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
837 159