Vue 如何使用props、emit實現(xiàn)自定義雙向綁定的實現(xiàn)
下面我將使用Vue自帶的屬性實現(xiàn)簡單的雙向綁定。
下面的例子就是利用了父組件傳給子組件(在子組件定義props屬性,在父組件的子組件上綁定屬性),子組件傳給父組件(在子組件使用$emit()屬性定義一個觸發(fā)方法,在父組件上的子組件監(jiān)聽這個事件)。
import Vue from 'vueEsm'
var Com = {
name:'Com',
props:['val'],
template:`<input type='text' @input='handleInput'/>`,
methods: {
handleInput(e){
this.$emit("input",e.target.value);
}
},
}
new Vue({
el:'#app',
data() {
return {
value:''
}
},
components:{
Com
},
template:`
<div>
<Com @input='post' :val='value'></Com>
</div>
`,
methods:{
post(data){
this.value=data;
}
}
})
上面這個例子,在input標簽上每次輸入時觸發(fā)原生事件input,在這個事件上綁定了一個handleInput方法,事件每次觸發(fā)都會執(zhí)行方法里的$emit屬性。該屬性里面第一個參數(shù)可以定義一個事件名,第二個參數(shù)可以傳一個參數(shù)。這里我們把每次輸入的值e.target.value傳進去。在父組件的子組件上監(jiān)聽這個事件,定義一個post方法,方法的參數(shù)就是傳入的數(shù)據(jù)。然后我們在父組件的data屬性里定義一個存儲值的變量value。將剛才傳入的參數(shù)賦給這個變量value。最后在父組件的子組件上綁定一個自定義屬性,比如val。將value傳給val。在子組件定義一個props屬性接受這個val。
這個例子對于理解父組件與子組件傳值特別重要。
下方舉例說明了我的一個自定義mySelect的實現(xiàn)過程:
<template>
<div class="select">
<div class="input" @click="collapse=!collapse">
<span v-if="currentValue">{{currentLabel||currentValue}}</span>
<span v-else class="placeholder">{{placeholder}}</span>
<span :class="collapse?'arrow-down':'arrow-up'"></span>
</div>
<div class="option-list" v-show="!collapse">
<div class="option-item" v-for="item in data" :key="item.id" @click="chooseItem(item)">{{item[itemLabel?itemLabel:'name']}}</div>
</div>
</div>
</template>
<script>
export default {
name: "mySelect",
props: [
'value',
'placeholder',
'data',
'itemLabel',
'itemValue'
],
data() {
return {
collapse: true,
currentValue: '',
currentLabel: '',
}
},
watch: {
value: {
immediate: true,
handler(value) {
this.currentValue = value;
this.$emit('input', value);
this.data.forEach(item => {
if (item[this.itemValue ? this.itemValue : 'id'] == value) {
return this.currentLabel = item[this.itemLabel ? this.itemLabel : 'name'];
}
});
}
},
data:{
immediate: true,
handler(arr) {
if(this.value||!this.currentLabel){
arr.forEach(item=>{
if(item[this.itemValue ? this.itemValue : 'id'] == this.value){
this.currentLabel = item[this.itemLabel ? this.itemLabel : 'name'];
return;
}
})
}
}
}
},
methods: {
chooseItem(item) {
if (this.currentValue !== item[this.itemValue ? this.itemValue : 'id']) {
this.$emit('change',item[this.itemValue ? this.itemValue : 'id']);
}
this.currentValue = item[this.itemValue ? this.itemValue : 'id'];
this.currentLabel = item[this.itemLabel ? this.itemLabel : 'name'];
this.$emit('input', this.currentValue);
this.collapse = true;
}
}
}
</script>
<style lang="scss" scoped>
.select {
position: relative;
.input {
width: 100%;
height: 30px;
line-height: 30px;
background-color: #fff;
border: 1px solid #02b4fe;
border-radius: 0 3px 3px 0;
padding-left: 10px;
color: #666;
position: relative;
.placeholder {
color: #aaa;
}
}
.arrow-down {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 8px solid #02b4fe;
position: absolute;
right: 5px;
top: 10px;
}
.arrow-up {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 8px solid #02b4fe;
position: absolute;
right: 5px;
top: 10px;
}
.option-list {
max-height: 200px;
overflow-y: scroll;
position: absolute;
top: 2rem;
left: 0;
z-index: 5;
width: 100%;
padding: 0 5px;
font-size: 10px;
color: #aaa;
background-color: #fff;
text-align: left;
box-shadow: 0 0 5px rgba(0, 0, 0, .1);
border: 1px solid rgb(79, 192, 232);
.option-item {
text-align: center;
line-height: 1.5rem;
}
}
}
</style>
如上所示,當聲明了mySelect組件之后,在項目中實際使用時,就可以如下所示直接使用:
<template>
<mySelect v-model="testValue" placeholder="請選擇" :data="testArr" item-label="id"
item-value="name"></mySelect>
</template>
<script>
import mySelect from './mySelect'
export default{
components:{
mySelect
},
data(){
return {
testValue:'',
testArr:[]
}
},
mounted(){
//預(yù)置select的下拉選擇基礎(chǔ)數(shù)據(jù),數(shù)據(jù)為對象數(shù)組,包含id和name屬性
}
}
</script>
以上就是一個簡單的自定義雙向綁定組件的實現(xiàn),包括簡單的使用過程。在vue中的自定義組件,關(guān)于props的聲明時,還是盡量使用官方建議的對象方式,可以聲明屬性的默認值和數(shù)據(jù)類型。我這邊偷懶了用的是props的字符串數(shù)組簡寫方式,但是這樣的話對使用組件時的錯誤調(diào)試不利。所以,盡量不要學(xué)我偷懶噢,親~~~
到此這篇關(guān)于Vue 如何使用props、emit實現(xiàn)自定義雙向綁定的實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue props、emit實現(xiàn)自定義雙向綁定內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue使用element-resize-detector監(jiān)聽元素寬度變化方式
這篇文章主要介紹了vue使用element-resize-detector監(jiān)聽元素寬度變化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Vue一個動態(tài)添加background-image的實現(xiàn)
這篇文章主要介紹了Vue一個動態(tài)添加background-image的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
vue element實現(xiàn)表格合并行數(shù)據(jù)
這篇文章主要為大家詳細介紹了vue element實現(xiàn)表格合并行數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-11-11
vue3中update:modelValue的使用與不生效問題解決
現(xiàn)在vue3的使用越來越普遍了,vue3這方面的學(xué)習我們要趕上,下面這篇文章主要給大家介紹了關(guān)于vue3中update:modelValue的使用與不生效問題的解決方法,需要的朋友可以參考下2022-03-03
Vue OptionsAPI與CompositionAPI的區(qū)別與使用介紹
OptionsAPI和CompositionAPI是Vue.js框架中兩種不同的組件編寫方式,OptionsAPI通過對象字面量定義組件,以屬性分隔不同功能,響應(yīng)式數(shù)據(jù)通過data屬性定義,本文給大家介紹Vue OptionsAPI與CompositionAPI的區(qū)別,感興趣的朋友一起看看吧2024-10-10

