1. 組件開發(fā)
在vue中蚌讼,組件是最重要的組合部分芯义,官方中定義組件為可復用的vue實例趁舀,分為全局組件和局部組件嵌洼。
1.1 全局組件
使用全局組件的步驟如下:
- 調用vue.extend()創(chuàng)建一個組件構造器案疲,該構造器中有一個選項對象的template屬性可以用來定義組件要渲染的HTML
- 使用vue.component()注冊組件,需要提供2個參數(shù):組件的標簽和組件構造器咱台。vue.component()內部會調用組件構造器络拌,創(chuàng)建一個組件實例
- 將組建掛載到某個vue實例下
因為組件是可復用的vue實例,所以它們也能接收data回溺、computed春贸、watch、methods以及生命周期鉤子等選項
<div id="demo">
<haha></haha>
</div>
<script type="text/javascript">
var red = Vue.extend({
template: "<span style='color: red;'>全局組件</span>"
});
Vue.component('haha',red);
var demo = new Vue({
el: "#demo"
})
</script>
1.2 局部組件
調用Vue.component()注冊組件時遗遵,組件的注冊是全局的萍恕,這意味著該組件可以在任意Vue示例下使用。 如果不需要全局注冊车要,或者是讓組件使用在其它組件內允粤,可以用選項對象的components屬性實現(xiàn)局部注冊。
<div id="demo">
<haha></haha>
</div>
<script type="text/javascript">
var red = Vue.extend({
template: "<span style='color: red;'>局部組件</span>"
});
var demo = new Vue({
el: "#demo",
components:{
haha:red
}
})
</script>
雖然上面的組件是在某個具體的vue實例下注冊的翼岁,但是組件構造器還是全局的类垫,這個并不是完全意義上的局部組件,下面這種組件才是真正意義上的局部組件琅坡。
<div id="demo">
<haha></haha>
</div>
<script type="text/javascript">
var demo = new Vue({
el: "#demo",
components:{
haha:{
template:'<span style="color: red;">局部組件</span>'
}
}
})
</script>
1.3 組件模板
可以通過<template>標記聲明組件悉患,再通過全局或局部注冊組件來使用。
組件中data不是屬性榆俺,是方法售躁,需要將數(shù)據(jù)通過返回值進行返回
<div id="demo">
<haha></haha>
</div>
<template id="abc">
<div @click="test1" style="cursor: pointer;">{{message}}</div>
</template>
<script type="text/javascript">
var demo = new Vue({
el: "#demo",
components:{
haha:{
data(){
return {
message: 'init info'
}
},
methods:{
test1(){
if(this.message == 'init info'){
this.message = 'click info'
}else{
this.message = 'init info'
}
}
},
template:"#abc"
}
}
})
</script>
2. 組件通信
2.1 父子組件
當繼續(xù)在組件中寫組件坞淮,形成組件嵌套的時候,就是所謂的父子組件陪捷。
<div id="demo">
<haha></haha>
</div>
<template id="haha">
<div>
<h2>{{message}}</h2>
<xixi></xixi>
</div>
</template>
<template id="xixi">
<div>
<h3>{{info}}</h3>
</div>
</template>
<script type="text/javascript">
var demo = new Vue({
el: "#demo",
components:{
haha:{
data(){
return {
message: '父組件'
}
},
template:"#haha",
components:{
xixi:{
data(){
return {
info:'子組件'
}
},
template: "#xixi"
}
}
}
}
})
</script>
2.2 子組件獲取父組件的數(shù)據(jù)
在vue中回窘,組件實例的作用域是孤立的,默認情況下市袖,父子組件的數(shù)據(jù)是不能共享的啡直,也就是說,子組件是不能直接訪問父組件的數(shù)據(jù)的凌盯。為此付枫,vue給我們提供了一個數(shù)據(jù)傳遞的選項prop,用來將父組件的數(shù)據(jù)傳遞給子組件驰怎。
- 父組件template中阐滩,調用子組件位置通過
:msg="message"
表示將父組件中的data:message傳遞給子組件,名字為msg - 子組件components中通過props聲明['msg']表示接收父組件推送的數(shù)據(jù)县忌,子組件template直接{{msg}}進行調用
<div id="demo">
<haha></haha>
</div>
<template id="haha">
<div>
<h2>{{message}}</h2>
<xixi :msg="message"></xixi>
</div>
</template>
<template id="xixi">
<div>
<h3>{{info}} -> {{msg}}</h3>
</div>
</template>
<script type="text/javascript">
var demo = new Vue({
el: "#demo",
components:{
haha:{
data(){
return {
message: '父組件'
}
},
template:"#haha",
components:{
xixi:{
data(){
return {
info:'子組件'
}
},
props:['msg'],
template: "#xixi"
}
}
}
}
})
</script>
2.3 父組件獲取子組件的數(shù)據(jù)
父組件獲取子組件需要子組件事件驅動掂榔,通過觸發(fā)一個事件將自身的數(shù)據(jù)發(fā)送給父組件。
步驟:
1.在子組件的methods中編寫send方法症杏,其中通過emit函數(shù)將需要傳遞的數(shù)據(jù)綁定一個名字“child-msg”
2.在父組件的template中調用子組件的標記處装获,通過@child-msg指向父組件的綁定函數(shù)"getMsg"
3.在父組件的methods中編寫getMsg函數(shù),通過方法參數(shù)接收傳遞過來的數(shù)據(jù)厉颤,并將其賦值給某個data(cmsg)
4.通過使用cmsg來使用子組件的數(shù)據(jù)穴豫。
<div id="demo">
<haha></haha>
</div>
<template id="haha">
<div>
<h2>{{message}}</h2>
<xixi :msg="message" @child-msg="getMsg"></xixi>
<div>{{cmsg}}</div>
</div>
</template>
<template id="xixi">
<div @click="send">
<h3>{{info}} -> {{msg}}</h3>
</div>
</template>
<script type="text/javascript">
var demo = new Vue({
el: "#demo",
components:{
haha:{
data(){
return {
message: '父組件',
cmsg:''
}
},
methods:{
getMsg(msg){
this.cmsg = msg;
}
},
template:"#haha",
components:{
xixi:{
data(){
return {
info:'子組件數(shù)據(jù)'
}
},
props:['msg'],
template: "#xixi",
methods:{
send(){
this.$emit('child-msg',this.info);
}
}
}
}
}
}
})
</script>
需要強調的是,父子組件數(shù)據(jù)時單向更新的
- 當父組件數(shù)據(jù)變化時逼友,子組件中的顯示會實時更新精肃。
- 當子組件數(shù)據(jù)變化時,需要觸發(fā)事件來驅動父組件數(shù)據(jù)更新帜乞。
2.4 $children和$ref
當一個父組件中存在多個子組件時司抱,可以通過$children來訪問其下所有子組件,它會返回一個包含所有子組件的數(shù)組
<div id="count">
<button @click="showmsg">
顯示兩個組件的信息
</button>
<child1></child1>
<child2></child2>
</div>
<template id="child1">
<div>
{{ msg }}
</div>
</template>
<template id="child2">
<div>
{{ msg }}
</div>
</template>
<script>
Vue.component('child1', {
template: '#child1',
data () {
return {
msg: '這是子組件1的信息'
}
}
})
Vue.component('child2', {
template: '#child2',
data () {
return {
msg: '這是子組件2的信息'
}
}
})
new Vue({
el: '#count',
data: {
},
methods: {
showmsg () {
for(var i = 0; i < this.$children.length; i++) {
alert(this.$children[i].msg)
}
}
}
})
</script>
有時候組件過多的話黎烈,就很記清各個組件的順序與位置习柠,所以通過給子組件一個索引ID來進行快速定位
<div id="count">
<button @click="showmsg">
顯示兩個組件的信息
</button>
<child1 ref='c1'></child1>
<child2 ref='c2'></child2>
</div>
<template id="child1">
<div>
{{ msg }}
</div>
</template>
<template id="child2">
<div>
{{ msg }}
</div>
</template>
<script>
Vue.component('child1', {
template: '#child1',
data () {
return {
msg: '這是子組件1的信息'
}
}
})
Vue.component('child2', {
template: '#child2',
data () {
return {
msg: '這是子組件2的信息'
}
}
})
new Vue({
el: '#count',
data: {
},
methods: {
showmsg () {
alert(this.$refs.c1.msg)
alert(this.$refs.c2.msg)
}
}
})
</script>
2.5 $parent和$root
子組件通過訪問$parent獲得其父組件的實例對象
<div id="count">
父組件中的msg: {{ msg }}
<child1 ref='c1'></child1>
<child2 ref='c2'></child2>
</div>
<template id="child1">
<div>
{{ msg }}
<button @click="showpmsg">
顯示父組件msg
</button>
</div>
</template>
<template id="child2">
<div>
{{ msg }}
</div>
</template>
<script>
Vue.component('child1', {
template: '#child1',
data () {
return {
msg: '這是子組件1的信息'
}
},
methods: {
showpmsg () {
alert(this.$parent.msg)
}
}
})
Vue.component('child2', {
template: '#child2',
data () {
return {
msg: '這是子組件2的信息'
}
}
})
new Vue({
el: '#count',
data: {
msg: 'hello parent'
}
})
</script>
子組件訪問根組件 $root 當前組件樹的根 Vue 實例。如果當前實例沒有父實例照棋,此實例將會是其自已资溃。
<div id="count">
父組件中的msg: {{ msg }}
<child1 ref='c1'></child1>
<child2 ref='c2'></child2>
</div>
<template id="child1">
<div>
{{ msg }}
<cchild></cchild>
</div>
</template>
<template id="child2">
<div>
{{ msg }}
</div>
</template>
<template id="cchild">
<div>
<button @click="showroot">
showrootmsg
</button>
</div>
</template>
<script>
Vue.component('child1', {
template: '#child1',
data () {
return {
msg: '這是子組件1的信息'
}
},
methods: {
showpmsg () {
alert(this.$parent.msg)
}
}
})
Vue.component('child2', {
template: '#child2',
data () {
return {
msg: '這是子組件2的信息'
}
}
})
Vue.component('cchild', {
template: '#cchild',
data () {
return {
msg: '這是子組件1的信息'
}
},
methods: {
showroot () {
alert(this.$root.msg)
}
}
})
new Vue({
el: '#count',
data: {
msg: 'hello root'
}
})
</script>