国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

從零開始封裝自己的自定義Vue組件

2019-11-19 12:45:06
字體:
供稿:網(wǎng)友

想要封裝好一個(gè)自己的vue組件,一定要熟練掌握這三個(gè)技能

父組件 ―> 子組件傳值(props)

子組件 ―> 父組件傳值($emit)

以及插槽(slot)

對于一個(gè)獨(dú)立的組件來說

props是用來為組件內(nèi)部注入核心的內(nèi)容;

$emit用來使這個(gè)獨(dú)立的組件通過一些邏輯來融入其他組件中。

舉個(gè)具體點(diǎn)的例子,假如你要做一輛車,車輪是要封裝的一個(gè)獨(dú)立組件,props指的就是根據(jù)整個(gè)車的外形你可以給輪子設(shè)置一些你想要的且符合車風(fēng)格的花紋,圖案等;

而$emit的作用則是讓這些輪子能夠和整輛車完美契合的運(yùn)作起來。差不多就是這個(gè)意思

下面來看代碼。

首先,我們先完成div的模擬代碼

<template><div class="selectWrap"> <div class="select-wrapper">  <div class="select" @click = "triggerOption">   <div class="select-content">{{selectContent.text}}</div>   <div class="triangle-wrapper">    <div id="triangle-down"></div>   </div>  </div>  <div class="option-wrapper" style="display: none;">   <div class="option-item" v-for = "(item,index) in subject" :key="index" @mouseout="out($event)" @mouseover="move($event)" @click = "choose(item)">{{item.text}}</div>  </div> </div></div></template><script> export default{  data(){   return{    selectContent:{value:0,text:"小張"}, //模擬select默認(rèn)選中的值    subject:[{value:0,text:"小張"},{value:1,text:"小李"}, //模擬option中的文本和value值         {value:2,text:"小王"},{value:4,text:"小明"}],    }  },  computed:{   optionWrapper(){    return document.querySelector(".option-wrapper");   },   selectCon(){    return document.querySelector(".select-content");   },   subjectList(){    return document.getElementsByClassName("option-item");   },  },  methods:{   move(event){ //模擬hover效果    for(var item of this.subjectList){     item.classList.remove("hover");    }    event.currentTarget.classList.add("hover");   },   out(event){    event.currentTarget.classList.remove("hover");   },   triggerOption(){ //控制option的展示,以及選中后的高亮效果    if (this.optionWrapper.style.display == "none") {     this.optionWrapper.style.display = "block";    }else{     this.optionWrapper.style.display = "none";    }    for(var item of this.subjectList){     if (item.innerHTML == this.selectContent.text) {      item.classList.add("hover");     }else{      item.classList.remove("hover");     }    }   },   choose(item){ //選中“option”    this.selectContent.text = item.text;    this.optionWrapper.style.display = "none";   }  }, }</script><style> .selectWrap{ /*select的寬度*/  width: 100px; } .select{  position: relative;  overflow: hidden;  padding-right: 10px;  min-width: 80px;  width: 100%;  height: 20px;  line-height: 20px;  border: 1px solid #000;  cursor: default;  font-size: 13px; } .select-content{  text-align: left; } .triangle-wrapper{  position: absolute;  right: 0;  top: 50%;  transform: translateY(-50%);  width: 18px;  height: 20px;  background-color: #fff;  cursor: default; } #triangle-down{  position: absolute;  right: 5px;  top: 50%;  transform: translateY(-50%);  width: 0;  height: 0;  border-left: 3px solid transparent;  border-right: 3px solid transparent;  border-top: 6px solid #000; } .option-wrapper{  position: relative;  overflow: hidden;  min-width: 80px;  width: 100%;  border-right: 1px solid #000;  border-bottom: 1px solid #000;  border-left: 1px solid #000; } .option-item{  min-width: 80px;  height: 20px;  line-height: 20px;  padding-right: 10px;  text-align: left;  cursor: default;  } .hover{  background-color: rgb(30,144,255);  color:#fff !important; }</style>  

事實(shí)上,當(dāng)你完成這段代碼時(shí),就已經(jīng)完成了這一個(gè)組件。放到平時(shí),我可能就直接把這段代碼放到業(yè)務(wù)代碼里直接用了。但既然是封裝組件,我們肯定要把它抽出來了。首先我們先要思考一下,如果我們需要把這個(gè)組件抽出來,有哪些值需要父組件提供給我們呢?

相信大家一眼就能看出來,subject和selectContent這兩個(gè)data是需要父組件通過props傳進(jìn)來的。但還有別的嗎?作為一個(gè)select,父組件如果只能控制內(nèi)容是不是管的有點(diǎn)太少了?可不可以讓父組件來管理select的寬度?高度?字體大小樣式等等?答案是肯定的。父組件傳的值越多,子組件的耦合就越低。下面,我們對代碼進(jìn)行微調(diào)

<template> ......</template><script> export default{  props:["subject","selectContet","selectWidth”],  mounted(){   document.querySelector(".selectWrap").style.width =    this.selectWidth+"px";  },  computed:{   optionWrapper(){    return document.querySelector(".option-wrapper");   },   selectCon(){    return document.querySelector(".select-content");   },   subjectList(){    return document.getElementsByClassName("option-item");   },  },  methods:{   ......   choose(item){    this.selectContent.text = item.text;    this.optionWrapper.style.display = "none";   }  }, }</script><style> /*.selectWrap{  width: 100px; }*/ ....... </style>
 

我們通過props將之前的subject和selectContent從父組件傳了進(jìn)來。同時(shí),我們還將select的寬度傳了進(jìn)來,并通過mounted來設(shè)置寬度。這樣,父組件就能控制子組件的內(nèi)容和一些簡單的樣式了。

當(dāng)然,作為一個(gè)完善的組件,我們還需要為組件設(shè)置默認(rèn)值,這樣就算父組件不傳值,我們的這個(gè)組件一樣可以使用

<template> ......</template><script> export default{  props:{   selectWidth:{    type:Number,    default:100,   },   subject:{    type:Array,    default:function(){     return []    }   },   selectContent:{    type:Object,    default:function(){     return {value:0,text:"請選擇"}    }   },  },  mounted(){   document.querySelector(".selectWrap").style.width = this.selectWidth+"px";  },  ......   methods:{   ......   choose(item){    this.selectContent.text = item.text;    this.optionWrapper.style.display = "none";   }  }, }</script><style> ......</style>

這回我們將props用對象的方式聲明,并設(shè)置了默認(rèn)值(default),假如父組件沒有設(shè)置子組件的寬度,那么我們可以使用默認(rèn)的100px。這樣,我們的組件更加的完善!當(dāng)然,我們的組件還有一個(gè)關(guān)鍵的功能沒有實(shí)現(xiàn),就是把選中的值傳回給父組件,不然的話這個(gè)組件就沒有意義了,我們來看choose這個(gè)函數(shù)

choose(item,value){  this.selectContent.text = item.text;  this.optionWrapper.style.display = "none";  this.$emit("changeSelect",this.selectContent.text,this.selectContent.value);}

 這樣,我們就可以把選到的文本和value值傳給父組件了。

當(dāng)然,這僅僅是一個(gè)開頭,字體大小等內(nèi)容我還沒有設(shè)置,不過這個(gè)組件現(xiàn)在已經(jīng)完全可以拿出去用了

以上是vue自定義組件封裝的簡單實(shí)例,大家可以研究下

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 光泽县| 岳西县| 曲阜市| 德阳市| 阿尔山市| 五原县| 隆化县| 淄博市| 三台县| 宿迁市| 嘉荫县| 安福县| 苏尼特右旗| 莒南县| 靖西县| 通许县| 无极县| 台北县| 怀安县| 自治县| 佛学| 邵武市| 白水县| 车险| 江华| 玉屏| 黎平县| 探索| 怀柔区| 濮阳市| 肇东市| 汽车| 光山县| 怀来县| 泸州市| 敦化市| 新乡市| 北安市| 读书| 固原市| 基隆市|