Vue中如何更好地封装组件?

这篇具有很好参考价值的文章主要介绍了Vue中如何更好地封装组件?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 子组件接受父组件传递的事件

1.子组件使用@事件名="$emit('父组件中传递的事件名',想给父组件传递的参数(可选))"
@click="$emit('click')"
2.子组件使用
v-on="$listeners"

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

 父组件:

<template>
  <div id="app">
    <myComponents :msg="form.msg" @click="a"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data(){
    return {
      form:{
        msg: "10"
      }
    }
  },
  methods:{
    a(){
      console.log('哈哈哈')
    },
  }
}
</script>

<style>

</style>

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <!-- v-on="$listeners" 和 @click="$emit('click')" 效果一样  两者选一即可-->
    <h1 v-on="$listeners" @click="$emit('click')">{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  props: {
    msg: {
      type: String,
      default: "18"
    }
  },
  created() {
    console.log(this.$listeners)  //一个对象,里面包含父组件传递过来的所有事件
  },
  methods: {}
}
</script>
<style scoped>
</style>
  • 父组件传值给子组件

1.子组件使用props声明想要的属性,再将该属性动态绑定给子组件
props: {
  msg: {
    type: String,
    default: "18"
  },
},
     然后子组件中绑定数据即可
    父组件使用prop声明,就可以传递给子组件

:prop="msg"

 <Head1 :name="form.name"/>
2.子组件使用$attrs,这个组件包含了被传入,但没有声明的prop

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
//不声明msg
  // props: {
  //   msg: {
  //     type: String,
  //     default: "18"
  //   },
  // },
  created() {
    console.log(this.$attrs)   //一个对象,包含父组件中被传入,但没有声明的prop
  },
  methods: {}
}
</script>

<style scoped>
</style>

打印结果: 

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

 此时h1标签上就有msg属性:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

页面显示结果:

 Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

 需要注意的一点是:Vue会将被传入,但未声明的prop作为html属性,绑定到组件的根元素上:

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

可以设置属性 inheritattrs为false,将这些默认行为去掉,来解决这个问题。

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
}
</script>

<style scoped>
</style>

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

  • 对外暴露子组件插槽

1.直接向子组件转发插槽,使用父组件的 $slots 
该组件包含了传递给父组件的非作用域插槽
使用$scopeSlots可传递给父组件的作用域插槽,这个组件包含了组件接受的所有插槽

子组件:

<template>

<el-input>
v-model="innerVal"
v-bind="$attrs
@input="$emit('input", $event)"
v-on="$listeners"

//子组件中写两个插槽
<template #append>
<slot name="append"></slot></template>
<template #prepend>
<slot name="prepend"></slot></template>
</el-input>

</template>

 打印this.$slots

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

  • props validator

一般我们会用对象的形式声明prop,可以在对象中指定prop的默认值,也可以指定类型,对prop进行验证。
一个更灵活的的方式是,传入并编写一个验证函数,prop会作为参数传入该函数,函数返回fals时,会抛出控制台警告,这种方式特别适合验证枚举值,

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-on="$listeners" @click="$emit('click')" v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
  props:{
    numberIs:{
      default: '1',
      //当传入的prop值不是1,2,3时,控制台会抛出警告
      validator: prop => ['1', '2', '3'].includes(prop)
    }
  },
}
</script>
<style scoped>
</style>

 父组件:

<template>
  <div id="app">
    <!--  传入numberIs的值为4  -->
    <myComponents :msg="form.msg" @click="a" numberIs="4"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data() {
    return {
      form: {
        msg: "10"
      },
    }
  },
  methods: {
    a() {
      console.log('哈哈哈')
    },
  }
}
</script>

<style>

</style>

$refs用于父组件获取整个子组件实例,然后可以使用子组件的方法和属性(暴露子组件方法)

父组件:

<template>
  <div id="app">
    <!--  ref相当于给当前子组件设置了一个id,可以使用refs根据ref的值获取该组件  -->
    <myComponents :msg="form.msg" @click="a" numberIs="1" ref="bb"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data() {
    return {
      form: {
        msg: "10"
      },
    }
  },
  methods: {
    a() {
      //获取ref值为bb的子组件,并调用该子组件上的show方法
      this.$refs.bb.show()
    },
  }
}
</script>

<style>

</style>

子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-on="$listeners"  v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
  props:{
    numberIs:{
      default: '1',
      //当传入的prop值不是1,2,3时,控制台会抛出警告
      validator: prop => ['1', '2', '3'].includes(prop)
    }
  },
  created() {
  },
  methods: {
    show(){
      console.log('1111')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
打印 this.$refs 显示为:

 Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

 点击之后,控制台输出:

Vue中如何更好地封装组件?,vue.js,javascript,前端,前端框架

但在封装子组件后,如果不对子组件的方法进行暴露,调用时,我们往往需要通过ref先获取父组件实例,再获取子组件实例,这种方式导致组件代码难以维护:

//获取父组件bb之后,再获取子组件aa,最后使用aa中的show方法
this.$refs.bb.$refs.aa.show()

我们可以再父组件中提供与子组件同名的方法, 对外暴露,让使用者只通过父组件就可以进行调用:

子组件中:

methods:{
    show() {
        this.$refs.aa.show()
    }
}

父组件中:

methos: {
    show() {
        this.$refs.bb.show()
    }
}

总结:

1. $attrs 简化多层组件之间props传值;
2. $listeners 简化多层组件之间事件传递;
3. $Slots 更多拓展自定义组件传值,包括自定义html元素,及对象;
4. props validator 增强组件传值稳健性,可自定义业务代码效验参数;
5. $refs 对外提供API 增强组件灵活度和可控性; 文章来源地址https://www.toymoban.com/news/detail-647382.html

到了这里,关于Vue中如何更好地封装组件?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何封装Vue组件并上传到npm

    1.注册npm账号:npm | Home (npmjs.com) 2.保证当前环境安装了vue、webpack、node,以下工作将在该环境下进行(没有的小伙伴自行百度安装哈~) 3.一下用到的环境版本 webpack:v5.1.4 node:v12.10.0 vue:v2.6.14 4.创建一个基于webpack的vue项目,这个项目将会是我们的组件项目了。 在我们日常开

    2024年04月25日
    浏览(16)
  • 基于VUE3+Layui从头搭建通用后台管理系统(前端篇)十一:通用表单组件封装实现

      本章实现通用表单组件,根据实体配置识别实体属性,并自动生成编辑组件,实现对应数据填充、校验及保存等逻辑。 1. 详细课程地址: https://edu.csdn.net/course/detail/38183 2. 源码下载地址: 点击下载

    2024年02月10日
    浏览(22)
  • 基于VUE3+Layui从头搭建通用后台管理系统(前端篇)八:自定义组件封装上

      本章实现一些自定义组件的封装,包括数据字典组件的封装、下拉列表组件封装、复选框单选框组件封装、单选框组件封装、文件上传组件封装、级联选择组件封装、富文本组件封装等。 1. 详细课程地址: https://edu.csdn.net/course/detail/38183 2. 源码下载地址: 点击下载

    2024年02月12日
    浏览(22)
  • 前端vue elementUI upload上传组件封装&多文件上传&进度条,后端servlet request.getPart()接收文件信息

    选中多个文件上传 通过 axios请求 onUploadProgress 方法监听 on-progress on-success 用这两个钩子函数实现进度条 下面有对应的函数。 本文是每个文件一个请求上传 也可以用一个请求上传多个文件,需要将文件遍历添加到 form 表单中,后端用 request.getParts(); 获取集合,有需要的可以改

    2024年02月11日
    浏览(23)
  • 前端歌谣-第伍拾陆课-vue2-element组件封装el-button-groups(续)

    我是歌谣 今天继续给大家带来el-button-groups(项目的讲解

    2024年02月03日
    浏览(20)
  • Taro + vue3 + js + nutUI 框架中自定义tabbar的组件封装以及页面跳转的逻辑

    1.需求:   在H5 中需要封装一个自定义的tabbar 菜单跳转 通过nut-ui 进行二次封装 2. 注意点   H5 中原生的tabbar 在ios 中会出现问题 所以进行 封装tabbar 3. 代码操作 首先全部的代码  4.解析 tabList: 菜单的内容数组  根据自己菜单的数量 来决定 const tabList = reactivemenu[]([     {    

    2024年04月17日
    浏览(19)
  • 前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十一章 基础界面开发 (组件封装和使用)

    Vue 是前端开发中非常常见的一种框架,它的易用性和灵活性使得它成为了很多开发者的首选。而在 Vue2 版本中,组件的开发也变得非常简单,但随着 Vue3 版本的发布,组件开发有了更多的特性和优化,为我们的业务开发带来了更多便利。本文将介绍如何使用 Vue3 开发业务组件

    2024年02月19日
    浏览(29)
  • Vue.js 中的异步组件是什么?如何使用异步组件?

    在 Vue.js 中,异步组件是一种延迟加载组件的方式,可以大大提高应用程序的性能和加载速度。本文将介绍 Vue.js 中异步组件的概念、优势以及如何使用异步组件。 在传统的 Vue.js 开发中,组件是在应用程序启动时就立即加载的。这种方式虽然简单,但是会导致应用程序的初始

    2024年02月12日
    浏览(16)
  • Vue 组件中如何引入外部的js文件

    在Vue中,通常我们引入一个js插件都是使用 npm  方式下载然后 import 使用的。但是我现在本地有了js文件或者是一个远程js文件链接,我不想使用 npm install xxx  的方式,有什么办法吗? 简单粗暴,直接在Vue项目的 index.html  中使用全局的方式引入,比如: 缺点: 不使用该js插

    2024年02月08日
    浏览(39)
  • Vue 组件中如何引入外部的js文件 的10种方法

    在Vue组件的 script 标签中使用 import 语句引入外部的JavaScript文件,适用于单个组件需要使用外部JavaScript文件的情况。这种方法可以在编译时静态地引入外部文件,并且可以通过 import 语句的路径指定具体的文件位置。 在Vue组件的 script 标签中使用 require 方法引入外部的JavaScr

    2024年02月10日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包