首页 > 其他分享 >Vue独立组件开发: prop event slot

Vue独立组件开发: prop event slot

时间:2023-04-20 15:06:46浏览次数:48  
标签:slot Vue 自定义 父级 prop 组件 click

本文是介绍独立组件开发的系列文章的第一篇。

Vuejs无疑是当下最火热的前端框架,而它最精髓的,正是它的组件与组件化。写一个 Vue 项目,就是在写一个个的组件,掌握了 Vue 组件的各种开发模式与技巧,再复杂的业务场景也可轻松拿捏。

组件的分类

Vue 组件分成三类:


页面组件

由 vue-router 产生的每个页面,它本质上也是一个组件(.vue),它承载当前页面的 HTML 结构,同时会有数据获取、数据整理等业务逻辑。

页面组件整个文件相对较大,但一般不会有 props 选项和 自定义事件,因为它作为路由的渲染,不会被复用,因此也不会对外提供接口。

在我们平时的项目开发中,写的大部分代码都是这类的组件。多人开发时,每人维护自己的页面,很少有交集。这类组件相对是最好写的,因为主要是还原设计稿,完成需求,不需要太多模块和架构设计上的考虑。


独立组件

它不包含业务,是独立、具体功能的组件,比如下拉框日期选择器等。

这类组件作为项目的基础控件,会被大量使用,因此组件的 API 进行过高强度的抽象,可以通过不同配置实现不同的功能。

大部分的互联网都有自己的组件使用规范或组件库,但是要开发和维护一套像 element uiant design 这样的组件库,投入的人力和精力还是很重的,所以出于成本考虑,很多项目都会使用已有的开源组件库。

独立组件的开发难度要远高于页面组件,因为它的侧重点是 API 的设计、兼容性、性能、以及复杂的功能。

这类组件对 JavaScript 的编程能力有比较高的要求,也包含非常多的技巧与经验。比如在不依赖 Vuex等第三方库(因为独立组件,无法依赖其它库)的情况下,各组件间的通信等等问题。


业务组件

它与独立组件的区别是,业务组件只在当前项目中会用到,不具有通用性,而且会包含一些业务,比如数据请求;而独立组件不含业务,在任何项目中都可以使用,功能单一,比如一个具有数据校验功能的输入框。

业务组件更像是介于第一类和第二类之间,在开发上也与独立组件类似,但依赖于项目,你可以使用项目中引入的第三方库,比如 Vuexaxioslodash 等,所以它的开发难度相对独立组件要容易点,但也有必要考虑组件的可维护性和复用性。

因此,独立组件的开发是最能体现一个前端开发者的Vue水平的,本文也将重点介绍独立组件的各种开发模式和技巧。


Vue组件的三个 API:prop、event、slot

一个再复杂的组件,都是由三部分组成的:prop、event、slot,它们构成了 Vue 组件的 API

如果你开发的是一个独立组件,那一定要事先设计好这三部分,因为组件一旦发布,后面再修改 API 就很困难了,使用者都不希望一个库的接口经常变换。

如果你阅读别人写的组件,也可以从这三个部分展开,它们可以帮助你快速了解一个组件的所有功能。


属性 prop

prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。

写独立组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的

比如我们封装一个按钮组件 <v-button>

<template>
  <button :class="'v-button-size' + size" :disabled="disabled"></button>
</template>
<script>
// 判断参数是否是其中之一
function oneOf(value, validList) {
  for (let i = 0; i < validList.length; i++) {
    if (value === validList[i]) {
      return true
    }
  }
  return false
}

export default {
  props: {
    size: {
      validator(value) {
        return oneOf(value, ['small', 'large', 'default'])
      },
      default: 'default'
    },
    disabled: {
      type: Boolean,
      default: false
    }
  }
}
</script>

使用组件:

<v-button size="large"></v-button>
<v-button disabled></v-button>

组件定义了两个属性:尺寸 size 和是否禁用 disabled

size 使用 validator 进行了值的自定义验证,也就是说,从父级传入的 size,它的值必须是指定的 small、large、default 中的一个,默认值是 default,如果传入这三个以外的值,都会抛出一条警告。

组件里定义的 props,都是单向数据流,只能通过父级修改,组件自己不能修改 props 的值,只能修改定义在 data 里的数据,非要修改,也是通过后面介绍的自定义事件通知父级,由父级来修改。

在使用组件时,也可以传入一些标准的 html 属性,比如 idclass

<v-button id="btn1" class="btn-submit"></v-button>

这样的 html 属性,在组件内的 <button> 元素上会继承,并不需要在 props 里再定义一遍。

这个特性是默认支持的,如果不期望开启,在组件选项里配置inheritAttrs: false就可以禁用了。


插槽 slot

如果要给上面的按钮组件 <v-button> 添加一些文字内容,就要用到组件的第二个 API:插槽 slot,它可以分发组件的内容:

<template>
  <button :class="'i-button-size' + size" :disabled="disabled">
    <slot></slot>
  </button>
</template>

这里的 <slot> 节点就是指定的一个插槽的位置,这样在组件内部就可以扩展内容了:

<v-button>按钮 1</v-button>
<v-button>
  <strong>按钮 2</strong>
</v-button>

当需要多个插槽时,会用到具名 slot,比如我们再增加一个 slot,用于设置另一个图标组件:

<template>
  <button :class="'i-button-size' + size" :disabled="disabled">
    <slot name="icon"></slot>
    <slot></slot>
  </button>
</template>
<v-button>
  <v-icon slot="icon" type="checkmark"></v-icon>
  按钮 1
</v-button>

这样,父级内定义的内容就会出现在组件对应的 slot 里,没有写名字的,就是默认的 slot

在组件的 <slot> 里也可以写一些默认的内容,这样在父级没有写任何 slot 时,它就会出现:

<slot>提交</slot>

自定义事件 event

现在给组件 <v-button> 加一个点击事件,目前有两种写法,我们先看自定义事件 event:

<template>
  <button @click="handleClick">
    <slot></slot>
  </button>
</template>
<script>
  export default {
    methods: {
      handleClick (event) {
        this.$emit('on-click', event);
      }
    }
  }
</script>

通过 $emit,就可以触发自定义的事件 on-click ,在父级通过 @on-click 来监听:

<v-button @on-click="handleClick"></v-button>

上面的 click 事件,是在组件内部的 <button> 元素上声明的,这里还有另一种方法,直接在父级声明,但为了区分原生事件和自定义事件,要用到事件修饰符 .native,所以上面的示例也可以这样写:

<v-button @click.native="handleClick"></v-button>

如果不写 .native 修饰符,那上面的 @click 就是自定义事件 click,而非原生事件 click(原生事件是指在html标签上定义的click事件,在组件上定义的事件为自定义事件),但我们在组件内只触发了 on-click 事件,而不是 click,所以直接写 @click 会监听不到。


总结

本文复习了 Vue 组件的核心知识点prop、slot、evnet,虽然没有完全覆盖 Vue 的 API,但对于组件开发来说已经足够了。

prop定义了组件有哪些功能,开发组件首先需要明确prop,推荐使用对象的形式来写prop

slot分发组件的内容,让用户可以自定义展示内容,极大的扩展了组件的使用范围。

event组件内的数据改变,只能通过父级改变,保证数据的单向流动的。

在下一篇文章,我们将介绍独立组件之间的通信,看看它们在不依赖于第三库的情况下是如何通信的。

标签:slot,Vue,自定义,父级,prop,组件,click
From: https://blog.51cto.com/u_16078169/6209572

相关文章

  • Vue 独立组件开发:不一样的组件通信方式
    本文是介绍独立组件开发的系列文章的第二篇。组件的通信组件一般来说有以下几种关系:父子关系隔代关系兄弟关系组件间经常会通信,Vue内置的通信手段一般有两种:ref:给元素或组件注册引用信息;$parent / $children:访问父/子实例。这两种方式都是直接得到组件的实例,然后直接调用组件......
  • Vue3+TS+Node打造个人博客(后端架构)
    在使用Express搭建后端服务时,主要关注的几个点是:路由中间件和控制器SQL处理响应返回体数据结构错误码Web安全环境变量/配置路由和控制器路由基本上是按模块或功能去划分的。首先是按模块去划分一级路由,各个模块的子功能相当于是用二级路由处理。简单举个例子,/article......
  • vue全家桶进阶之路43:Vue3 Element Plus el-form表单组件
    在ElementPlus中,el-form是一个表单组件,用于创建表单以便用户填写和提交数据。它提供了许多内置的验证规则和验证方法,使表单验证更加容易。使用el-form组件,您可以将表单控件组织在一起,并对表单进行验证,以确保提交的数据符合预期的格式和要求。该组件具有以下特性:支持内置......
  • Props介绍
    Props声明​一个组件需要显式声明它所接受的props,这样Vue才能知道外部传入的哪些是props,哪些是透传attribute(关于透传attribute,我们会在专门的章节中讨论)。props需要使用 props 选项来定义:jsexportdefault{props:['foo'],created(){//props会......
  • vue3微信公众号商城项目实战系列(12)项目发布到服务器上
    本篇介绍如何将vue3项目打包发布到服务器上,然后在微信公众号上打开。vue3发布之前需要对项目进行编译,编译时会在项目根目录下创建dist文件夹,编译后的文件会存放在这里。 在编译之前,我们在public目录下建一个config.js的文件,里面放如下的代码:constconfig={baseUr......
  • Vue3 toRef与toRefs
    视频直接用ref是创建新的对象10.toRef作用:创建一个ref对象,其value值指向另一个对象中的某个属性。语法:constname=toRef(person,'name')应用:要将响应式对象中的某个属性单独提供给外部使用时。扩展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法......
  • Vue3 自定义hook
    视频9.自定义hook函数什么是hook?——本质是一个函数,把setup函数中使用的CompositionAPI进行了封装。类似于vue2.x中的mixin。自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。componentsDemo.vue<template> <h2>当前求和为:{{sum}}</h2> <button@clic......
  • vue国际化步骤
    vue国际化步骤Vue国际化的步骤如下所示:1.安装vue-i18n库npminstallvue-i18n--save2.创建i18n实例在项目中新建一个i18n.js文件,引入vue-i18n库,并创建一个i18n实例。importVuefrom'vue';importVueI18nfrom'vue-i18n';Vue.use(VueI18n);consti18n=......
  • vue2升vue3后部分异常解决
    element-ui升为element-plus首先建议参考element-plus官方站点:https://element-plus.org/zh-CN/部分组件标签直接变更如el-submenu变更为el-sub-menu浏览器提示ElementPlusError:[ElOnlyChild]novalidchildnodefound哪个页面有该提示就搜"slot=",然后到element......
  • npm i vuex-persistedstate安装失败怎么办
    在安装vuex的插件vuex-persistedstate来支持vuex的状态持久化时,出现如下报错: 在这里给大家提供一个解决方法,输入此行命令即可成功安装:npminstall--savevuex-persistedstate-f  ......