vue2.0 自定义组件的方法(vue组件的封装)


Posted in Javascript onJune 05, 2018

一、前言

之前的博客聊过 vue2.0和react的技术选型;聊过vue的axios封装和vuex使用。今天简单聊聊 vue 组件的封装。

vue 的ui框架现在是很多的,但是鉴于移动设备的复杂性,兼容性问题突出。像 Mint-UI 等说实话很不错了,但是坑也是不少,而且很多功能也是仅凭这些实现不了,这需要我们去封装自己的可复用组件

二、封装组件的步骤

1. 建立组件的模板,先把架子搭起来,写写样式,考虑你的组件的基本逻辑。

os:思考1小时,码码10分钟,程序猿的准则。

2. 准备组件的好数据输入。即分析好逻辑,定好 props 里面的数据、类型。(后面详解)

3.准备组件的好数据输出。即根据组件逻辑,做好要暴露出来的方法。(后面详解)

4.封装完毕了,直接调用即可。

os: 代码可以不看,结论在文章最后

接下来以一个很简单的例子具体说明一下

现在先看一下demo的效果图

 vue2.0 自定义组件的方法(vue组件的封装)

三、 demo代码

父组件:

<template>
 <section class="f-mainPage">
 <!--selectFunc 选择完成的回调 searchList 下拉列表的数据-->
 <search @selectFunc="selectFunc" :searchList="searchList" :selectValue="selectValue"></search>
 </section>
</template>

<script type="text/ecmascript-6">
 import Search from '../vuePlugin/search'
 export default {
 data() {
 return {
 searchList: ['草船借箭', '大富翁', '测试数据'],
 // 直接通过props传递对象 修改,挺便捷的,但是不规范
 selectValue: {
  data: '1'
 },
 // 通过emit修改,规范写法
 selectValue2: ''
 }
 },
 mounted() {},
 methods: {
 pageGo(path) {
 this.$router.push('/' + path)
 },
 selectFunc(value) {
 this.selectValue2 = value
 console.log(this.selectValue)
 console.log(this.selectValue2)
 }
 },
 components: {
 Search
 }
 }
</script>

<style lang="scss" scoped>
.f-mainPage{
 width: 100%;
 .g-banner{
 width: 100%;
 background-image: url(../../../static/main_bg.png);
 background-repeat: no-repeat;
 background-size: 100% 100%;
 position: relative;
 overflow: hidden;
 color: white;
 text-align: center;
 p:nth-child(1) {
 margin: 10px auto 0px auto;
 font-size: 1.3rem;
 }
 .f-banscri {
 margin: 15px auto 8px auto;
 font-size: 0.95rem;
 }
 .f-moneyMax{
 margin: 5px auto 0px auto;
 font-size: 2.4rem;
 }
 .f-returnCash{
 width: 120px;
 height: 35px;
 text-align: center;
 line-height: 35px;
 background-color: white;
 color: #169BD5;
 display: inline-block;
 border-radius: 5px;
 font-size: 1rem;
 margin-top: 35px;
 position: relative;
 .f-mmmbd{
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: transparent;
  top: 0;
  left: 0;
 }
 }
 }
 .g-cashInfor{
 width: 100%;
 text-align: center;
 display: flex;
 justify-content: space-between;
 div{
 width: 50%;
 height: 60px;
 line-height: 60px;
 box-sizing: border-box;
 }
 div:nth-child(1){
 border-bottom: 1px solid #878787;
 border-right: 1px solid #878787;
 }
 div:nth-child(2){
 border-bottom: 1px solid #878787;
 }
}
 .g-operate{
 width: 100%;
 height: auto;
 overflow: hidden;
 ul{
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 1.05rem;
  li{
  height: 60px;
  line-height: 60px;
  padding-left: 25px;
  position: relative;
  span{
   width: 20px;
   height: 20px;
   position: absolute;
   top: 20px;
   right: 20px; 
   background-image: url(../../../static/go.png);
   background-repeat: no-repeat;
   background-size: 100% 100%;
  }
  }
 }
 .f-goodNews{
  width: 340px;
  height: 144.5px;
  margin: 20px auto 30px auto;
  text-align: center;
  background-image: url(../../../static/banner.png);
  background-repeat: no-repeat;
  background-size: 100% 100%;
 }
 }
}
</style>

子组件:

<template>
 <div class="searchZJ">
 <div class="f-search">
  <div class="f-searchIn" v-bind:class="{searchInFous: this.fousFlag}">{{this.searchValue}}<span v-bind:class="{searchActive: this.searchFlag}" v-on:click="searchDown"></span></div>
  <div class="f-searchXl" v-if="this.dataHas" v-bind:style="{height:this.searchFous, border:this.searchBorder}">
  <div v-for="item in searchList" v-on:click="choseValue(item)">{{item}}</div>
  </div>
  <div class="f-searchXl" v-else >
  <div>暂无数据</div>
  </div>
 </div>
 </div>
</template>
<script type="text/ecmascript-6">
 export default {
 data() {
 return {
 data: [],
 dataHas: true,
 searchFlag: false,
 searchFous: '0',
 fousFlag: false,
 searchValue: '',
 searchBorder: 'none'
 }
 },
 props: {
 searchList: Array,
 selectValue: Object
 },
 mounted() {
 this.data = this.searchList
 },
 methods: {
 searchDown() {
 this.searchFlag === false ? this.searchFlag = true : this.searchFlag = false
 this.searchFous === '0' ? this.searchFous = 'auto' : this.searchFous = '0'
 this.searchBorder === 'none' ? this.searchBorder = '1px solid #D9D9D9' : this.searchBorder = 'none'
 this.fousFlag === false ? this.fousFlag = true : this.fousFlag = false
 },
 choseValue(value) {
 this.searchValue = value
 this.searchDown()
 this.selectValue.data = '我被修改了'
 this.$emit('selectFunc', value)
 }
 }
 }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
 .f-search{
 width: 250px;
 height: auto;
 position: relative;
 margin-left: 20px;
 box-sizing: border-box;
 }
 .f-searchIn{
 width: 250px;
 height: 35px;
 line-height: 35px;
 font-size: 0.95rem;
 border-radius: 5px;
 overflow: hidden;
 position: relative;
 background-color: white;
 box-shadow: none;
 box-sizing: border-box;
 color: #000000;
 padding-left: 10px;
 border: 1px solid #A3A3A3;
 }
 .searchInFous{
 border: 1px solid #57C4F6;
 box-shadow: 0px 0px 5px #57C4F6;
 }
 .f-searchIn > span{
 display: block;
 width: 28px;
 height: 28px;
 background-image: url(../../../static/upDown.png);
 background-size: 100% 100%;
 background-repeat: no-repeat;
 background-position: 0px -13px;
 position: absolute;
 top: 10px;
 right: 5px;
 }
 .f-searchIn .searchActive{
 background-position: 0px 12px;
 top: -2px;
 }
 .f-search .f-searchXl{
 position: absolute;
 width: 100%;
 height: auto;
 max-height: 220px;
 top: 41px;
 left: -1px;
 border-radius: 5px;
 /*border: 1px solid #D9D9D9;*/
 background-color: white;
 overflow-x: hidden;
 overflow-y: scroll;
 }
 .f-search .f-searchXl > div{
 height: 35px;
 line-height: 38px;
 color: #000000;
 padding-left: 25px;
 font-size: 0.92rem;
 }
 .f-search .f-searchXl > div:hover{
 background-color: #D5F1FD;
 }
</style>

四、代码详解

1. 先说一下 props

我们在父组件中需要将子组件需要的数据导入,用法如下:

<search @selectFunc="selectFunc" :searchList="searchList" :selectValue="selectValue"></search>

:searchList ="searchList"  就是我们的数据,这个可以写多个。这里我传输了2个参数过去,主要是做数据修改的说明。大家可以先忽略。

在子组件中,我们的接收和使用方法如下:

props: {
 searchList: Array,
 selectValue: Object
 },
mounted() {
 this.data = this.searchList
 },

我们在 props 中接收数据,注意props对象里面 键值 是对改数据的 数据类型 的规定。做了规范,使用者就只能传输指定类型的数据,否则报警告

二props对象中的数据,我们可以直接在当前组件中使用   this.searchList,可以直接使用。至于原理嘛,不懂的可以取脑补一下 js的原型 。os:这些基础,在这就不做详述了

以上就是props传递过来的数据的使用了。

2. emit的使用(如何暴露组件方法)

我们已经会使用 父组件向子组件传数据了,那如子组件如何来修改父组件的数据呢?

这里提供 2 种实现方法,但是 第一种不推荐,强烈不推荐

方式一:

 selectValue: {
  data: '1'
 },


。。。。。。。。。。。。。。。
 this.selectValue.data = '我被修改了'

即,父组件将 对象 数据传递给子组件,子组件直接修改props过来的对象的值

可以实现,感觉是一个比较快捷的方式。但是不推荐,这种方式写多了,容易出错,特别是多层组件嵌套的时候。这种修改对代码的迭代和错误的捕捉都不友好,所以建议大家别这样写。

他的实现原理简单提一下: 这个对象、数组啦,是引用数据类型,说白了,就是存储单元的信息是指针,真正数据在别的地方,通过指针查询的数据,所以这样写,对浏览器来说仅仅是传递了一个指针,数据还是同一份数据。所以你能修改。

方式二:

正儿八经的通过 $emit 方法去掉父组件的方法,在父组件中修改data的数据。(根正苗红的方法,规范写法)

// 子组件
this.$emit('selectFunc', value)
// 父组件
<search @selectFunc="selectFunc" :searchList="searchList" :selectValue="selectValue"></search>
selectFunc(value) {
 this.selectValue2 = value
 console.log(this.selectValue)
 console.log(this.selectValue2)
 }

将父组件的方法注入子组件   @selectFunc ="selectFunc" ,然后在子组件中通过 $emit 调用他,并传递参数。达到修改的目的。

五、 总结

这里主要是总结一下vue组件封装的思路,帮大家梳理一下。很简单,和jQuery插件、react组件一样,所有组件都是一个套路,就是 函数思想。

组件就是做烤肠台机器,我放进去猪肉,再按一下各种开关,然后你给我烤肠。

1. 定义好 你需要使用者传入的数据

2. 定义好 你提供给使用者的方法

3. 写好组件的内部逻辑

这就OK了,一个完美的,可复用的组件就完成了。    os: 在此吐槽一下,那些自认为是优秀的组件,其实,别人拿着没法用的代码。

以上所述是小编给大家介绍的vue2.0 自定义组件的方法(vue组件的封装),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript面向对象编程代码
Dec 19 Javascript
jquery如何判断某元素是否具备指定的样式
Nov 05 Javascript
js与css实现弹出层覆盖整个页面的方法
Dec 13 Javascript
js插件YprogressBar实现漂亮的进度条效果
Apr 20 Javascript
jquery实现LED广告牌旋转系统图片切换效果代码分享
Aug 26 Javascript
node.js微信公众平台开发教程
Mar 04 Javascript
javascript中this关键字详解
Dec 12 Javascript
十大 Node.js 的 Web 框架(快速提升工作效率)
Jun 30 Javascript
解决ie img标签内存泄漏的问题
Oct 13 Javascript
浅谈Node.js 中间件模式
Jun 12 Javascript
jQuery操作元素的内容和样式完整实例分析
Jan 10 jQuery
vue前端工程的搭建
Mar 31 Vue.js
vue使用技巧及vue项目中遇到的问题
Jun 04 #Javascript
jQuery实现的滑块滑动导航效果示例
Jun 04 #jQuery
jQuery实现常见的隐藏与展示列表效果示例
Jun 04 #jQuery
js如何找出字符串中的最长回文串
Jun 04 #Javascript
详解Webpack + ES6 最新环境搭建与配置
Jun 04 #Javascript
jQuery实现的简单获取索引功能示例
Jun 04 #jQuery
JS实现统计字符串中字符出现个数及最大个数功能示例
Jun 04 #Javascript
You might like
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
PHP使用观察者模式处理异常信息的方法详解
2019/09/24 PHP
php 中的信号处理操作实例详解
2020/03/04 PHP
22点关于jquery性能优化的建议
2014/05/28 Javascript
Google官方支持的NodeJS访问API,提供后台登录授权
2014/07/29 NodeJs
jQuery插件pagewalkthrough实现引导页效果
2015/07/05 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
jQuery解析Json实例详解
2015/11/24 Javascript
全面解析Bootstrap手风琴效果
2020/04/17 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
深入浅析search 搜索框的写法
2016/08/02 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
Bootstrap栅格系统使用方法及页面调整变形的解决方法
2017/03/10 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
js实现移动端编辑添加地址【模仿京东】
2017/04/28 Javascript
AngularJs 常用的过滤器
2017/05/15 Javascript
JS面试题大坑之隐式类型转换实例代码
2018/10/14 Javascript
vue favicon设置以及动态修改favicon的方法
2018/12/21 Javascript
koa大型web项目中使用路由装饰器的方法示例
2019/04/02 Javascript
VSCode搭建Vue项目的方法
2020/04/30 Javascript
pytyon 带有重复的全排列
2013/08/13 Python
Python里隐藏的“禅”
2014/06/16 Python
Python专用方法与迭代机制实例分析
2014/09/15 Python
如何在django里上传csv文件并进行入库处理的方法
2019/01/02 Python
Python+selenium点击网页上指定坐标的实例
2019/07/05 Python
python numpy之np.random的随机数函数使用介绍
2019/10/06 Python
python实现最速下降法
2020/03/24 Python
表达自我的市场:Society6
2018/08/01 全球购物
基督教卡片、励志礼品、家居装饰等:DaySpring
2018/10/12 全球购物
九州传奇上机题
2014/07/10 面试题
高中毕业自我鉴定
2013/12/16 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
税务干部个人整改措施思想汇报
2014/10/10 职场文书
优秀新员工事迹材料
2019/05/13 职场文书
虚拟机linux端mysql数据库无法远程访问的解决办法
2021/05/26 MySQL
Python操作CSV格式文件的方法大全
2021/07/15 Python