一、v-model的深入理解
v-model:就是v-on:和v-bind:的簡(jiǎn)寫
<div id="app">
<p>姓名:<input type="text" v-model='name'>{{name}}</p>
<!-- v-model: 其實(shí)就是v-on:和v-bind:的簡(jiǎn)寫 -->
<p>年齡:<input type="text" v-model='age'>{{age}}</p>
<hr>
<ul class="list">
<li>{{yf.label}}--{{yf.count}}</li>
<li>{{kz.label}}--{{kz.count}}</li>
</ul>
<b-counter :label='yf.label' :value='yf.count' @input='yf.count=$event'></b-counter>
<b-counter :label='kz.label' v-model='kz.count'></b-counter>
</div>
<script src='https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js'></script>
<script>
Vue.component('b-counter', {
template: `
<div class="counter">
<div class="label">{{label}}</div>
<div class="btn">
<button @click='myCount--' :disabled='myCount===minCount'>-</button>
<input readonly class="txt" type="text" :value='myCount'>
<button @click='myCount++' :disabled='myCount===maxCount'>+</button>
</div>
</div>`,
//props選項(xiàng)种吸,用于定義組件的屬性死陆,有兩種方式肴焊,1.定義數(shù)組 2.定義對(duì)象 注意:props是只讀的吃型,不能修改
// props:['label','count']
props: {
//類別
label: {
type: String,
//可以為空
required: false,
},
//數(shù)量
value: {
type: Number,
//非空
required: true
},
//最大值
maxCount: {
type: Number,
//數(shù)量
default: 999
},
//最小值
minCount: {
type: Number,
default: 1
}
},
//定義數(shù)據(jù)
data() {
return {
//將props接收到的value证鸥,中轉(zhuǎn)給mycount
myCount: this.value
}
},
//監(jiān)聽器
watch: {
myCount(val) {
//觸發(fā)一個(gè)自定義事件,事件名稱是input,將count的最新值作為事件對(duì)象傳出去。
//注意:自定義事件名稱不能使用大寫
this.$emit('input', val)
}
}
})
new Vue({
el: '#app',
data: {
name: '張三',
age: 34,
yf:{
label: '衣服:',
count: 5
},
kz:{
label: '褲子:',
count: 5
},
}
})
</script>
二敌土、sync修飾符
綁定屬性時(shí)镜硕,采用:xx.sync修飾符运翼,可以省略u(píng)pdate:xx對(duì)應(yīng)的事件綁定返干。注意:屬性綁定必須是:xx.sync。自定義事件必須是update:xx血淌。
<div id="app">
<div>衣服--{{yf}} 褲子--{{kz}} 鞋子--{{xz}}</div>
<hr>
<!-- 綁定屬性時(shí)矩欠,采用:xx.sync修飾符,可以省略u(píng)pdate:xx對(duì)應(yīng)的事件綁定 -->
<!-- 約定1:屬性綁定必須是:xx.sync -->
<b-counter :yf.sync='yf' @updata:yf='yf=$event' :kz.sync='kz' @updata:kz='kz=$event' :xz.sync='xz' @updata:xz='xz=$event'></b-counter>
</div>
<script src='https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js'></script>
<script>
Vue.config.productionTip = false
Vue.component('b-counter',{
template: `
<div>
<div class="counter">
<div class="label">衣服:</div>
<div class="btn">
<button @click='yfCount--'>-</button>
<input readonly class="txt" type="text" :value='yfCount'>
<button @click='yfCount++'>+</button>
</div>
</div>
<div class="counter">
<div class="label">褲子:</div>
<div class="btn">
<button @click='kzCount--'>-</button>
<input readonly class="txt" type="text" :value='kzCount'>
<button @click='kzCount++'>+</button>
</div>
</div>
<div class="counter">
<div class="label">鞋子:</div>
<div class="btn">
<button @click='xzCount--'>-</button>
<input readonly class="txt" type="text" :value='xzCount'>
<button @click='xzCount++'>+</button>
</div>
</div>
</div>
`,
props:['yf','kz','xz'],
data(){
return {
yfCount:this.yf,
kzCount:this.kz,
xzCount:this.xz
}
},
watch:{
yfCount(val){
/* 約定2,:自定義事件必須是update:xx */
this.$emit('update:yf',val)
},
kzCount(val){
this.$emit('update:kz',val)
},
xzCount(val){
this.$emit('update:xz',val)
}
}
})
new Vue({
el:'#app',
data:{
//衣服數(shù)量
yf:5,
//褲子數(shù)量
kz:5,
//鞋子數(shù)量
xz:5
}
})
</script>
三悠夯、具名插槽
在template組件中采用v-slot:插槽名稱的方式癌淮,指定使用哪個(gè)插槽。
#是v-slot:的簡(jiǎn)寫
<div id="app">
<b-box>
<!-- 在template組件中采用v-slot:插槽名稱的方式沦补,指定使用哪個(gè)插槽 -->
<!-- #是v-slot:的簡(jiǎn)寫 -->
<template #house>
<div>有5套房子</div>
</template>
<template v-slot:car>
<div>有3輛汽車</div>
</template>
<template v-slot:money>
<div>有100萬存款</div>
</template>
</b-box>
</div>
<script src='https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js'></script>
<script>
Vue.config.productionTip = false
Vue.component('b-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='money'></slot>
</div>
</div>
`
})
new Vue({
el: '#app',
})
</script>
四乳蓄、作用域插槽
作用域插槽必須是具名插槽,在作用域插槽上夕膀,可以通過v-bind:綁定屬性虚倒,綁定的屬性,通過指定的作用域變量去接收产舞。
<div id="app">
<!-- 作用域插槽必須是具名插槽魂奥,在作用域插槽上,可以通過v-bind:綁定屬性,綁定的屬性易猫,通過指定的作用域變量去接收耻煤。 -->
<b-box>
<template #list='scope'>
<button @click='scope.list.splice(scope.index,1)'>刪除</button>
<button @click='priceUp(scope.list,scope.index)'>加價(jià)</button>
<button @click='priceDown(scope.list,scope.index)'>降價(jià)</button>
</template>
</b-box>
</div>
<script src='https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js'></script>
<script>
Vue.component('b-box', {
template: `
<div>
<ul>
<li v-for='(item,index) in list' :key='index'>
<span>{{item.id}}--{{item.name}}--{{item.price}}</span>
<slot name='list' v-bind:index='index' v-bind:list='list'></slot>
</li>
</ul>
</div>
`,
data() {
return {
list: [
{
id: 1001,
name: '小米手機(jī)',
price: 2999
},
{
id: 1002,
name: '華為手機(jī)',
price: 4999
},
{
id: 1003,
name: '蘋果手機(jī)',
price: 6999
},
{
id: 1004,
name: '紅米手機(jī)',
price: 1999
},
]
}
}
})
new Vue({
el: '#app',
methods: {
priceUp(list,index){
list[index].price+=1000
},
priceDown(list,index){
list[index].price-=1000
}
},
})
</script>
五、混入
使用Vue.mixin()給所有的Vue實(shí)例混入統(tǒng)一的成員准颓。里面可以寫數(shù)據(jù)哈蝇,計(jì)算屬性,方法攘已,監(jiān)聽器炮赦。
在Vue自己實(shí)例中寫的數(shù)據(jù)不能在所有成員中使用,只能自己調(diào)用贯被。
<div id="app1">
<p>姓名:<input type="text" v-model='name'></p>
<p>年齡:<input type="text" v-model='age'><button @click='age++'>++</button></p>
<p>性別:<input type="text" v-model='sex'></p>
<p>
稅前薪資:<input type="text" v-model='salary'>
稅后薪資:<input type="text" :value='salary2'>
</p>
<p><button @click='jieshao'>介紹</button></p>
<div>汽車信息:{{car}}</div>
<button @click='getSubjects'>請(qǐng)求課程信息</button>
<div>
{{subjects}}
</div>
</div>
<hr>
<div id="app2">
<p>姓名:<input type="text" v-model='name'></p>
<p>年齡:<input type="text" v-model='age'><button @click='age++'>++</button></p>
<p>性別:<input type="text" v-model='sex'></p>
<p>
稅前薪資:<input type="text" v-model='salary'>
稅后薪資:<input type="text" :value='salary2'>
</p>
<p><button @click='jieshao'>介紹</button></p>
<div>飛機(jī)信息:{{plane}}</div>
</div>
<script src='https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js'></script>
<script src='https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js'></script>
<script>
Vue.config.productionTip = false
/* 給所有的vue實(shí)例混入統(tǒng)一的成員 */
Vue.mixin({
data() {
return {
name: '',
age: 0,
sex: '男',
salary: 1000
}
},
computed: {
salary2() {
return this.salary * 0.8
}
},
methods: {
jieshao() {
alert(`大家好眼五!我叫${this.name},性別是${this.sex},今天是${this.age}歲了。`)
},
//get請(qǐng)求
async $get(url,params){
let {data} = await axios.get(url,{params})
return data
},
//post請(qǐng)求
async $post(url,params){
let {data} = await axios.post(url,params)
return data
}
},
watch: {
age(val) {
if (val > 100) {
alert('年齡不能大于100M睢?从住!')
this.age = 100
}
}
},
mounted() {
console.log('mixin:組件掛載完成')
},
})
new Vue({
el: '#app1',
/* 注意:先執(zhí)行混入的生命周期幌陕,再執(zhí)行自己的生命周期 */
mounted() {
console.log('app1,組件掛載完成诵姜。');
},
data(){
return{
car:{
name:'企鵝汽車',
price:300
},
//課程信息
subjects:[]
}
},
methods: {
async getSubjects(){
let {data} = await this.$get('http://www.bingjs.com:81/Subject/GetSubjectsConditionPages')
this.subjects = data
}
},
})
new Vue({
el: '#app2',
mounted() {
console.log('app2,組件掛載完成。');
},
data(){
return{
plane:{
name:'豬豬飛機(jī)',
price:1000
}
}
}
})
</script>