我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何使用vue3+TS实现简易组件库

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何使用vue3+TS实现简易组件库

这篇文章主要为大家展示了“如何使用vue3+TS实现简易组件库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用vue3+TS实现简易组件库”这篇文章吧。

    前置

    首先下载vue-cli,搭建我们的环境,vue-create-luckyUi,选择vue3和TypeScript 。在class="lazy" data-src目录下创建package作为组件目录。再安装bootstrap,用bootstrap里面的样式来完成我们的组件。

    组件编写

    dropdown

    首先查看boorstrap文档,是这样用的

    <div class="dropdown">  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-expanded="false">    Dropdown button  </button>  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">    <a class="dropdown-item" href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Action</a>    <a class="dropdown-item" href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Another action</a>    <a class="dropdown-item" href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Something else here</a>  </div></div>

    首先那个button按钮就是我们dropdown按钮的内容,将这部分作为属性传入,而dropdown-menu的内容是作为dropdown-item的,明显这里不能固定写三个,这里就用插槽占位,再封装一个dropdown-item组件。

    首先dropdown组件内容如下:

    <template>  <div class="dropdown" ref="dropdownRef">    <a      href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"       class="btn btn-outline-light my-2 dropdown-toggle"      @click.prevent="toggleOpen"    >      {{ title }}    </a>    <ul class="dropdown-menu" : v-if="isOpen">      <slot></slot>    </ul>  </div></template>

    dropdown-item的内容就是:

    <template>  <li    class="dropdown-option"    :class="{'is-disabled': disabled}"  >    <slot></slot>  </li></template><script lang="ts">import { defineComponent } from 'vue'export default defineComponent({  name: "DropdownItem",  props: {    disabled: {      type: Boolean,      default: false    }  }})</script><style>.dropdown-option.is-disabled * {  color: #6c757d;  pointer-events: none;  background-color: transparent;}</style>

    还要实现一个点击dropdown,dropdown-item会随之收起来的功能,这个比较简单,在dropdown上绑定一个点击事件来控制变量isOpen为true或者false,在加上v-if即可实现功能。接下来还要实现一个点击页面的其他地方也能实现dropdown-item收缩,这里有两个思路:

    • 首先在document上添加一个click事件,一旦触发就设置isOpen为false,给dropdown也添加一个点击事件,加上一个事件修饰符stop来阻止事件冒泡,这样除了点击dropdown意外的任何地方,document都会触发点击事件。

    • 第二个思路就是让事件冒泡到document,通过判断事件对象包不包括我们的目标对象,如果不包括说明点击的是页面的其他地方,就设置isOpen为false。这里用了到了组合式api,新建文件package/hooks/useClickOutside.ts,

    import { ref, onMounted, onUnmounted, Ref } from 'vue'const useClickOutside = (elementRef: Ref<null | HTMLElement>) => {  const isClickOutside = ref(false)  const handler = (e: MouseEvent) => {    if (elementRef.value) {      if (elementRef.value.contains(e.target as HTMLElement)) {        isClickOutside.value = false      } else {        isClickOutside.value = true      }    }  }  onMounted(() => {    document.addEventListener('click', handler)  })  onUnmounted(() => {    document.removeEventListener('click', handler)  })  return isClickOutside}export default useClickOutside

    然后直接导入即可使用定义的useClickOutside函数。这里监听isClickOutside的状态来更改isOpen的状态。

    import useClickOutside from "../hooks/useClickOutside";...const isClickOutside = useClickOutside(dropdownRef);watch(isClickOutside, () => {  if (isOpen.value && isClickOutside.value) {    isOpen.value = false;  }});

    form

    首先看下文档用法

    <form>  <div class="form-group">    <label for="exampleInputEmail1">Email address</label>    <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">    <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>  </div>  <div class="form-group">    <label for="exampleInputPassword1">Password</label>    <input type="password" class="form-control" id="exampleInputPassword1">  </div>  <div class="form-group form-check">    <input type="checkbox" class="form-check-input" id="exampleCheck1">    <label class="form-check-label" for="exampleCheck1">Check me out</label>  </div>  <button type="submit" class="btn btn-primary">Submit</button></form>

    首先编写ValidateForm组件:

    <template>  <form class="validate-form-container">    <slot name="default"></slot>    <div class="submit-area" @click.prevent="submitForm">      <slot name="submit">        <button type="submit" class="btn btn-primary">提交</button>      </slot>    </div>  </form></template><script lang="ts">import { defineComponent, onUnmounted } from 'vue'import mitt from 'mitt'type ValidateFunc = () => booleanexport const emitter = mitt()export default defineComponent({  emits: ['form-submit'],  setup(props, context) {    let funcArr: ValidateFunc[] = []    const submitForm = () => {      const result = funcArr.map(func => func()).every(result => result)      context.emit('form-submit', result)    }    const callback = (func?: ValidateFunc) => {      if (func) {        funcArr.push(func)      }    }    emitter.on('form-item-created', callback)    onUnmounted(() => {      emitter.off('form-item-created', callback)      funcArr = []    })    return {      submitForm    }  }})</script>

    接着编写ValidateInput.vue组件:

    <template>  <div class="validate-input-container pb-3">    <input      class="form-control"      :class="{'is-invalid': inputRef.error}"      @blur="validateInput"      v-model="inputRef.val"      v-bind="$attrs"    >    <span v-if="inputRef.error" class="invalid-feedback">{{inputRef.message}}</span>  </div></template><script lang="ts">import { defineComponent, reactive, PropType, onMounted, computed } from 'vue'import { emitter } from './ValidateForm.vue'const emailReg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/interface RuleProp {  type: 'required' | 'email' | 'custom';  message: string;  validator?: () => boolean;}export type RulesProp = RuleProp[]export type TagType = 'input'export default defineComponent({  props: {    rules: Array as PropType<RulesProp>,    modelValue: String,    tag: {      type: String as PropType<TagType>,      default: 'input'    }  },  inheritAttrs: false,  setup(props, context) {    const inputRef = reactive({      val: computed({        get: () => props.modelValue || '',        set: val => {          context.emit('update:modelValue', val)        }      }),      error: false,      message: ''    })    const validateInput = () => {      if (props.rules) {        const allPassed = props.rules.every(rule => {          let passed = true          inputRef.message = rule.message          switch (rule.type) {            case 'required':              passed = (inputRef.val.trim() !== '')              break            case 'email':              passed = emailReg.test(inputRef.val)              break            case 'custom':              passed = rule.validator ? rule.validator() : true              break            default:              break          }          return passed        })        inputRef.error = !allPassed        return allPassed      }      return true    }    onMounted(() => {      emitter.emit('form-item-created', validateInput)    })    return {      inputRef,      validateInput    }  }})</script>

    这里核心的地方有两点:

    • 自定义组件实现v-model,vue2中自定义组件实现v-mdel必须要绑定一个value属性和input事件,在input事件中将输入的值传递给value。在vue3中就需要绑定一个modelValue和update:modelValue事件

    • 还有就是父子组件之间的传值问题,因为有插槽,没办法使用常规的属性传值,这里使用的事件传值采用了一个第三方库mitt。在父组件中通过emitter.on('form-item-created', callback)来注册事件,在子组件中通过emitter.emit('form-item-created', validateInput)触发事件。

    验证

    新建文件package/index.ts

    import 'bootstrap/dist/css/bootstrap.min.css'//导入组件import Dropdown from "./Dropdown/Dropdown.vue";import DropdownItem from "./Dropdown/DropdownItem.vue";const components = [  Dropdown,  DropdownItem]const install = (Vue: any) => {  components.forEach((_: any) => {    Vue.component(_.name, _);  });};export default {  install};

    将写的组件依次导入,然后定义一个install函数,该函数有一个Vue实例的参数,在函数中依次遍历我们的导入组件数组,然后将组件挂载到vue实例上,导出install函数。

    在根目录下的main.ts上使用我们的新组件:

    import { createApp } from 'vue'import App from './App.vue'import luckyUi from './package/index';const app = createApp(App)app.use(luckyUi);app.mount('#app')

    在app.vue中进行测试:

    <template>  <div>    <div class="dropdown">      <!-- 测试dropdown -->      <dropdown :title="`你好啊`">        <dropdown-item><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >王大</a> </dropdown-item>        <dropdown-item>          <a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >王二</a>        </dropdown-item>        <dropdown-item disabled          ><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="dropdown-item">王三</a></dropdown-item        >        <dropdown-item          ><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="dropdown-item">王四</a></dropdown-item        >      </dropdown>    </div>  </div></template>

    最后使用vue自带的脚手架进行打包,详细可看文档。

    在package中配置打包命令:

    "lib": "vue-cli-service build --target lib --name lucky-ui ./class="lazy" data-src/package/index.ts"

    运行npm run lib即可在dist目录下查看。

    以上是“如何使用vue3+TS实现简易组件库”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    如何使用vue3+TS实现简易组件库

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    如何使用vue3+TS实现简易组件库

    这篇文章主要为大家展示了“如何使用vue3+TS实现简易组件库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用vue3+TS实现简易组件库”这篇文章吧。前置首先下载vue-cli,搭建我们
    2023-06-29

    如何使用Vue3+TS实现语音播放组件

    这篇文章主要介绍如何使用Vue3+TS实现语音播放组件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!该功能将使用vue3 + TS来实现语音播放组件,使用什么技术不重要,重要的是看懂了核心逻辑后,通过原生js、rea
    2023-06-29

    如何使用Vue3及Canvas实现简易的贪吃蛇游戏

    这篇“如何使用Vue3及Canvas实现简易的贪吃蛇游戏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用Vue3及Ca
    2023-07-06

    Vue3如何使用glup打包组件库并实现按需加载

    这篇文章主要介绍“Vue3如何使用glup打包组件库并实现按需加载”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue3如何使用glup打包组件库并实现按需加载”文章能帮助大家解决问题。使用 glu
    2023-07-06

    从0搭建Vue3组件库如何使用 glup 打包组件库并实现按需加载

    这篇文章主要介绍了从0搭建Vue3组件库如何使用 glup 打包组件库并实现按需加载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-23

    vue3 table组件如何使用

    今天小编给大家分享一下vue3 table组件如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。基础表格首先开发tabl
    2023-07-06

    从0搭建Vue3组件库之如何使用Vite打包组件库

    这篇文章主要介绍了从0搭建Vue3组件库之如何使用Vite打包组件库,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-07

    Vue3+hook如何实现弹窗组件

    本文小编为大家详细介绍“Vue3+hook如何实现弹窗组件”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue3+hook如何实现弹窗组件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。要封装什么如果是普通弹窗使
    2023-07-04

    怎么使用Vue3+Canvas实现简易的贪吃蛇游戏

    规则玩法:玩家使用方向键操控一条长长的蛇不断吞下豆子,同时蛇身随着吞下的豆子不断变长,当蛇头撞到蛇身或障壁时游戏结束。思路元素:边界、蛇头、蛇身、食物边界:输入行数x,列数y生成边界地图,用二维坐标标识每个点的位置;蛇头、蛇身:蛇头和蛇身分离,当吃到食物后,蛇身尾部加一食物:位置随机生成;流程图代码实现技术栈选择vue3、vite基础架构;视图选用canvas技术来实现,相比dom来说性能更好;基本变量定义import{ref,onMounted}from&#39;vue&#39
    2023-05-14

    vue3动态组件如何使用

    这篇“vue3动态组件如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue3动态组件如何使用”文章吧。问题:为什么v
    2023-07-05

    Vue3之Teleport组件如何使用

    这篇文章主要介绍了Vue3之Teleport组件如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3之Teleport组件如何使用文章都会有所收获,下面我们一起来看看吧。Teleport 组件解决的问
    2023-07-06

    如何使用Vue3设计实现一个Model组件浅析

    v-model在Vue里面是一个语法糖,数据的双向绑定,本质上还是通过自定义标签的attribute传递和接受,下面这篇文章主要给大家介绍了关于如何使用Vue3设计实现一个Model组件的相关资料,需要的朋友可以参考下
    2022-11-13

    Vue3异步组件Suspense如何使用

    这篇文章主要介绍了Vue3异步组件Suspense如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3异步组件Suspense如何使用文章都会有所收获,下面我们一起来看看吧。Suspense组件官网中
    2023-07-05

    如何使用session实现简易购物车功能

    这篇文章主要介绍“如何使用session实现简易购物车功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用session实现简易购物车功能”文章能帮助大家解决问题。整体思路:先写一个JSP用于
    2023-06-29

    vue3如何使用defineAsyncComponent与component标签实现动态渲染组件

    本篇内容介绍了“vue3如何使用defineAsyncComponent与component标签实现动态渲染组件”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅
    2023-07-06

    Vue3中如何使用defineCustomElement定义组件

    本篇内容主要讲解“Vue3中如何使用defineCustomElement定义组件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue3中如何使用defineCustomElement定义组件”
    2023-07-04

    Golang如何实现简易的rpc调用

    这篇文章主要介绍“Golang如何实现简易的rpc调用”,在日常操作中,相信很多人在Golang如何实现简易的rpc调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何实现简易的rpc调用”的疑
    2023-07-05

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录