4-1 使用組件細節(jié)點
1.is的使用
當我們寫循環(huán)組件的時候翩瓜,經常給
table中的tr
select中的option
ul中的li或者ol中的li
等等定義組件的時候酿联,我們經常用is來定義組件的名稱酥馍,為了讓瀏覽器成功的渲染正確的dom結構
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
<select name="" id="">
<option is="selectOption"></option>
<option is="selectOption"></option>
<option is="selectOption"></option>
</select>
<ul>
<li is="ulLi"></li>
<li is="ulLi"></li>
<li is="ulLi"></li>
</ul>
</div>
<script>
Vue.component('row', {
template: '<tr><td>this is a row</td></tr>'
});
Vue.component('selectOption',{
template: '<option>this is option</option>'
});
Vue.component('ulLi',{
template: '<li>this is li</li>'
});
var app = new Vue({
el: '#root',
data: {},
})
</script>
2.在子組件定義data的時候坦喘,必須是一個函數(shù),而不能是一個對象蛋济,返回一個對象是為了每個子組件都能擁有一個獨立的數(shù)據(jù)存儲渤早。這樣子組件之間的數(shù)據(jù)不會互相影響
而在根組件中,data可以是一個對象瘫俊。
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script>
Vue.component('row', {
data: function () {//返回的是一個函數(shù)
return {
content: 'this is row'
}
},
template: '<tr><td>{{content}}</td></tr>'
});
var app = new Vue({
el: '#root',
data: {}
})
</script>
3.有時候我們在開發(fā)過程中鹊杖,因為一些業(yè)務的需求悴灵,少不了對dom的操作,那么我們就可以借助ref來實現(xiàn)
//實例一
<div id="root">
<div ref="hello" @click="handleClick">hello world</div>
</div>
<script>
var app = new Vue({
el: '#root',
data: {},
methods: {
handleClick: function () {
console.log(this.$refs.hello.innerHTML);//通過refs屬性 獲取當前節(jié)點的文本
}
}
});
</script>
//案例二 counter求和
<div id="root">
<counter ref="one" @change="handleChange"></counter>
<counter ref="two" @change="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
Vue.component('counter', {
data: function () {
return {
number: 0
}
},
template: '<div @click="handleClick">{{number}}</div>',
methods: {
handleClick: function () {
this.number++;
this.$emit('change');//觸發(fā)一個監(jiān)聽器
}
}
});
var app = new Vue({
el: '#root',
data: {
total: 0
},
methods: {
handleChange: function () {
this.total = this.$refs.one.number + this.$refs.two.number //通過refs 來回去組件的值
}
}
});
</script>
4-2父子組件之間的數(shù)據(jù)傳遞
父組件向子組件傳值:是通過屬性的方式
子組件向父組件傳值:可以通過$emit
來觸發(fā)一個事件
vue數(shù)據(jù)傳遞遵循的是單向數(shù)據(jù)流骂蓖,
所以在下面的案例中我們并沒有對content數(shù)據(jù)直接進行數(shù)據(jù)的累加积瞒,而是把content數(shù)據(jù)賦值給了number,對number進行數(shù)據(jù)的累加操作登下。
<div id="root">
<counter :content="1" @inc="handleInc"></counter><!--父組件通過屬性向子組件傳值-->
<counter :content="3" @inc="handleInc"></counter>
<div>{{total}}</div>
</div>
<script>
Vue.component('counter', {
props: ['content'],
data: function () {
return {
number: this.content //遵循單向數(shù)據(jù)流
}
},
template: '<div @click="handleClick">{{number}}</div>',
methods: {
handleClick: function () {
this.number += 2;
//子組件通過方法向父組件傳值
this.$emit('inc', 2);
}
}
});
var app = new Vue({
el: '#root',
data: {
total: 4
},
methods: {
handleInc: function (step) {
this.total += step
}
}
})
</script>
4-3組件參數(shù)校驗和非props特性
1.組件的的參數(shù)校驗
<div id="root">
<child content="hello"></child>
</div>
<script>
Vue.component('child', {
props: {
content: {
type: String,
required: true,
default: 'default Value',
validator: function (value) {
return (value.length > 5)
}
}
},
template: '<div>{{content}}</div>'
});
var app = new Vue({
el: '#root',
})
</script>
2.props特性和非props特性的對比
props特性:
父組件傳遞屬性茫孔,子組件要接受該屬性
props屬性不會顯示在dom的標簽之中
非props特性:
父組件傳遞屬性,子組件沒有去接受被芳,而是直接調用
props屬性會顯示在dom的標簽之中
4-4給組件綁定原生事件
通過.native
屬性來綁定原生事件
<div id="root">
<child @click.native="handleClick"></child>
</div>
<script>
Vue.component('child', {
template: '<div>child</div>'
})
var app = new Vue({
el: '#root',
methods: {
handleClick: function () {
console.log('click');
}
}
})
</script>
4-5 非父子組件間的傳值
1.通過vuex
2.通過發(fā)布訂閱模式(Bus/總線/發(fā)布訂閱模式/觀察者模式/)
<div id="root">
<child content="sunny"></child>
<child content="fan"></child>
</div>
<script>
Vue.prototype.bus = new Vue();//定義bus
Vue.component('child', {
data: function () {
return {
newContent: this.content //保證單向數(shù)據(jù)流
}
},
props: {
content: String
},
template: '<div @click="handleClick">{{newContent}}</div>',
methods: {
handleClick: function () {
this.bus.$emit('change', this.newContent); //在bus上發(fā)布一個事件缰贝,并且傳值
}
},
mounted: function () {//通過這個鉤子,來監(jiān)聽change的變化畔濒,通過回調拿到相對應的的值
var that = this;
this.bus.$on('change', function (msg) {
console.log(msg)
that.newContent = msg//this 指向發(fā)生變更剩晴,所以上面要從新獲取一下this的指向
})
}
});
var app = new Vue({
el: '#root'
})
4-6 在vue中使用插槽
插槽只能有一個
而劇名插槽可以有多個
<div id="root">
<body-content>
<p slot="header">this is header</p>
<p slot="footer">this is footer</p>
</body-content>
</div>
<script>
Vue.component('body-content',{
template:
`<div>
<slot name="header">default header</slot> //設置默認值
<p>this is content</p>
<slot name="footer"></slot>
</div>`
})
var app = new Vue({
el:'#root'
})
</script>
4-7作用域插槽
父組件調用子組件的時候,給子組件傳了一個插槽侵状,這個插槽是一個作用域的插槽赞弥,這個插槽必須是一個<template slot-scope="props">{{props.item}}</template>
那什么時候使用作用插槽呢?
1.當子組件做循環(huán)
2.或者當子組件的dom結構由外部傳遞進來趣兄,或者有外部決定的時候
<div id="root">
<child>
<template slot-scope="props">
<li>{{props.item}}</li>
</template>
</child>
</div>
<script>
Vue.component('child', {
data: function () {
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<ul>
<slot v-for="item of list" :item=item></slot>
</ul>
</div>`
})
var app = new Vue({
el: '#root'
})
</script>
4-8 動態(tài)組件和v-once 指令
<div id="root">
<component :is="type"></component> <!--這就是動態(tài)組件-->
<child-one v-if="type==='child-one'"></child-one>
<child-two v-if="type==='child-two'"></child-two>
<button @click="hanleBtnClick">change</button>
</div>
<script>
Vue.component('child-one', {
template: '<div v-once>child-one</div>'
})
Vue.component('child-two', {
template: '<div v-once>child-two</div>'
})
var app = new Vue({
el: '#root',
data: {
type: 'child-one'
},
methods: {
hanleBtnClick: function () {
this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
}
}
})
</script>
更多
上一篇:第3章 Vue 基礎精講
下一篇:第5章 Vue 表單
全篇文章:Vue學習總結
所有章節(jié)目錄:Vue學習目錄