自定義組件 v-model的深入使用
<z-counter :label="yf.label" :value="yf.count" @input="yf.count=$event"></z-counter>
<z-counter :label="kz.label" v-model="kz.count"></z-counter>
比如在普通的input
的標(biāo)簽中庆尘,我們可以用v-model
來實(shí)現(xiàn)數(shù)據(jù)的雙向綁定剃诅,在自定義組件中,我們也可以使用v-model
的雙向綁定驶忌。
首先我們把屬性名改成value
,自定義的方法名為input
,這個(gè)時(shí)候我們的格式很像v-model
的實(shí)現(xiàn)原理矛辕,這個(gè)時(shí)候我們就可以縮寫成v-model
來實(shí)現(xiàn)數(shù)據(jù)的雙向綁定
在多個(gè)數(shù)據(jù)需要傳回頁面的時(shí)候,這個(gè)方法不能夠使用位岔。
Vue.component("z-counter", {
template:
`
<div class="counter">
<div class="label">{{label}}</div>
<div class="btns">
<button @click="mydata--" :disabled="mydata===mincount">-</button>
<input type="text" v-model="mydata" class="text" readonly>
<button @click="mydata++" :disabled="mydata===maxcount">+</button>
</div>
</div>
`,
// props 是只讀的不能修改
//prop 也可以是數(shù)組[屬性名]
props: {
label: {
type: String,
//允許為空
required: false,
},
value: {
type: Number,
//不可為空
required: true
},
maxcount: {
type: Number,
default: 999
},
mincount: {
type: Number,
default: 1
}
},
data() {
return {
mydata: this.value
}
},
watch: {
mydata(val) {
this.$emit('input', val)
}
},
})
new Vue({
el: '#app',
data() {
return {
yf:{
label:'衣服',
count:3
},
kz:{
label:'褲子',
count:3
}
}
},
methods: {
}
})
.sync
修飾符
這三種方法都可以實(shí)現(xiàn)
<div id="app">
<p>{{yf}}</p>
<p>{{kz}}</p>
<p>{{xz}}</p>
<z-counter :yf.sync="yf" :kz.sync="kz" :xz.sync="xz"></z-counter>
<hr>
<z-counter :yf="yf" :kz="kz" :xz="xz" @update:yf="yf=$event" @update:kz="kz=$event" @update:xz="xz=$event"></z-counter>
<hr>
<z-counter :yf.sync="yf" :kz.sync="kz" :xz.sync="xz" @update:yf="yf=$event" @update:kz="kz=$event" @update:xz="xz=$event"></z-counter>
如果在組件中有多個(gè)數(shù)據(jù)需要回傳如筛,這個(gè)時(shí)候我們可以使用.sync
修飾符 ,可以簡化我們的調(diào)用過程抒抬。
我們的自定義回傳方法yfcount(val){ this.$emit('update:yf', val) },
加上update:
的時(shí)候,我們可以在屬性的后面加上.sync
修飾符晤柄,這個(gè)時(shí)候擦剑,我們的回傳方法可以省略
this.$emit('update:yf', val) update: 后面連接的是父類傳過來的值的名稱 ,需要保持一致
Vue.component("z-counter", {
//模板
template:`
<div>
<div class="counter">
<div class="label">衣服:</div>
<div class="btns">
<button @click="yfcount--" >-</button>
<input type="text" v-model="yfcount" class="text" readonly>
<button @click="yfcount++" >+</button>
</div>
</div>
<div class="counter">
<div class="label">褲子:</div>
<div class="btns">
<button @click="kzcount--" >-</button>
<input type="text" v-model="kzcount" class="text" readonly>
<button @click="kzcount++" >+</button>
</div>
</div>
<div class="counter">
<div class="label">鞋子:</div>
<div class="btns">
<button @click="xzcount--" >-</button>
<input type="text" v-model="xzcount" class="text" readonly>
<button @click="xzcount++">+</button>
</div>
</div>
</div> `,
//自定義屬性
props: ['yf','kz','xz'],
data() {
return {
//將自定義屬性值進(jìn)行重新賦值給新的變量芥颈, 因?yàn)樽远x屬性不能夠改變默認(rèn)值
yfcount:this.yf,
kzcount:this.kz,
xzcount:this.xz,
}
},
watch: {
//監(jiān)聽事件惠勒,將新值傳回給頁面
yfcount(val){
this.$emit('update:yf', val)
},
kzcount(val){
this.$emit('update:kz', val)
},
xzcount(val){
this.$emit('update:xz', val)
}
},
})
new Vue({
el: '#app',
data() {
return {
yf:3,
kz:3,
xz:2
}
},
methods: {
}
})
如果觸發(fā)的事件名稱是update:屬性名,那么就可以使用..sync修飾符簡化調(diào)用的過程爬坑。
總結(jié):如果組件只回傳一份數(shù)據(jù)纠屋,用v-model。如果組件回傳多份數(shù)據(jù)盾计,用.sync修飾符售担。
具名插槽
當(dāng)我們的自定義組件中有多個(gè)插槽,這個(gè)時(shí)候我們需要把信息插入到對應(yīng)的插槽署辉,這個(gè)時(shí)候我們需要使用到具名插槽族铆。
我們給插槽添加添加一個(gè)name
屬性,這個(gè)就是插槽的名稱哭尝。
使用方法:
我們在自定義組件中用<template ></template >
把插入的標(biāo)簽放入到里面 用v-slot:插槽名
來插入固定插槽中
v-slot
可以用#
來代替 v-slot必須是在
<template>上使用
slot` 可以直接寫在標(biāo)簽上 如
<span slot="first"><span>
<div id="app">
<z-box>
<template v-slot:house>
<p>4套房子</p>
</template>
<template #car>
<p>三輛車</p>
</template>
<template v-slot:monyse>
<p>1000萬存款</p>
</template>
</z-box>
</div>
Vue.config.productionTip = false
Vue.component('z-box', {
template:`
<div class="box">
<div class="item">
<h2>房產(chǎn)信息</h2>
<slot name="house"></slot>
</div>
<div class="item">
<h2>車輛信息</h2>
<slot name="car"></slot>
</div>
<div class="item">
<h2>存款信息</h2>
<slot name="monyse"></slot>
</div>
</div>
`,
})
new Vue({
el: '#app'
})
作用域插槽
像可以在slot
標(biāo)簽上綁定屬性哥攘,這樣外面在使用該插槽時(shí),就可以獲取到上面綁定的數(shù)據(jù)材鹦。 這樣的插槽逝淹,我們稱之為:作用域插槽。
我們在自定義組件時(shí)桶唐,我們可以在<slot>
的插槽中綁定屬性 綁定的格式是v-bind:
跟普通綁定的屬性是相同的栅葡,v-bind
可以省略。
在使用時(shí)莽红,我們在template
的標(biāo)簽上用 v-slot:插槽名="變量名"
妥畏,通常我們的變量名用scope
來當(dāng)作變量名
<div id="app">
<z-food>
<template v-slot:list="scope">
<button @click="scope.list.splice(scope.index,1)">刪除</button>
<button @click="scope.list[scope.index].price+=100">加價(jià)</button>
<button @click="scope.list[scope.index].price-=100">降價(jià)</button>
</template>
</z-food>
</div>
Vue.config.productionTip = false
Vue.component("z-food", {
template:`
<div>
<ul>
<li v-for="(item, index) in list" :key="index">{{item.id}}--{{item.name}}--{{item.price}}
<slot name="list" v-bind:index="index" v-bind:list="list"></slot>
</li>
</ul>
</div>
`,
data() {
return {
list:[
{
id:1001,
name:'蛋糕',
price:20
},
{
id:1002,
name:'蛋撻',
price:30
},
{
id:1003,
name:'雞腿',
price:40
},
{
id:1004,
name:'黑巧',
price:50
},
]
}
},
})
new Vue({
el:"#app"
})
混入
全局混入 -- 注意:必須要先執(zhí)行
mixin()方法的參數(shù)是配置對象诀诊,Vue實(shí)例可以配置的東西,它都可以配置芹壕。
比如:數(shù)據(jù)盒蟆,方法,生命周期鉤子函數(shù)网棍,計(jì)算屬性黔龟,偵聽器,過濾器滥玷,等等...
在mixin()方法中氏身,是先執(zhí)行的
在全局混入的內(nèi)容,之后創(chuàng)建的所有Vue實(shí)例包括組件實(shí)例都將擁有惑畴。
在創(chuàng)建Vue實(shí)例時(shí)蛋欣,會將mixin里面的成員跟Vue實(shí)例自身的成員進(jìn)行合并,如果沖突了如贷,最終采用Vue實(shí)例身上的成員陷虎。
特別注意:生命周期鉤子不是合并,是疊加執(zhí)行杠袱,是先執(zhí)行mixin里面的生命周期鉤子尚猿,再執(zhí)行Vue實(shí)例里面的生命周期鉤子。
Vue.mixin({
data() {
return {
name: '',
age: 22,
sex: '男',
salary: 10000
}
},
computed: {
tosalary() {
return this.salary * 0.86
}
},
methods: {
jian() {
this.age++
if (this.age > 100) {
alert('年齡不能超過100');
this.age = 100
}
}
}
})
混入ajax的基本操作
我們可以在Vue.mixin()
可以寫個(gè)ajax
的封裝方法楣富,這樣我們在實(shí)例中可以直接調(diào)用封裝過的ajax
Vue.mixin({
methods: {
// get方法
async $get(url,params){
let {data} = await axios.get(this.base_url+url,{params})
return data
},
// post方法
async $post(url,params){
let {data} = await axios.post(this.base_url+url,params)
return data
}
},
})