1. 组件开发
在vue中,组件是最重要的组合部分,官方中定义组件为可复用的vue实例,分为全局组件和局部组件。
1.1 全局组件
使用全局组件的步骤如下:
- 调用vue.extend()创建一个组件构造器,该构造器中有一个选项对象的template属性可以用来定义组件要渲染的HTML
- 使用vue.component()注册组件,需要提供2个参数:组件的标签和组件构造器。vue.component()内部会调用组件构造器,创建一个组件实例
- 将组建挂载到某个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属性实现局部注册。
<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不是属性,是方法,需要将数据通过返回值进行返回
<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 父子组件
当继续在组件中写组件,形成组件嵌套的时候,就是所谓的父子组件。
<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 子组件获取父组件的数据
在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的,也就是说,子组件是不能直接访问父组件的数据的。为此,vue给我们提供了一个数据传递的选项prop,用来将父组件的数据传递给子组件。
- 父组件template中,调用子组件位置通过
:msg="message"
表示将父组件中的data:message传递给子组件,名字为msg - 子组件components中通过props声明['msg']表示接收父组件推送的数据,子组件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 父组件获取子组件的数据
父组件获取子组件需要子组件事件驱动,通过触发一个事件将自身的数据发送给父组件。
步骤:
1.在子组件的methods中编写send方法,其中通过emit函数将需要传递的数据绑定一个名字“child-msg”
2.在父组件的template中调用子组件的标记处,通过@child-msg指向父组件的绑定函数"getMsg"
3.在父组件的methods中编写getMsg函数,通过方法参数接收传递过来的数据,并将其赋值给某个data(cmsg)
4.通过使用cmsg来使用子组件的数据。
<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:'子组件数据'
}
},
props:['msg'],
template: "#xixi",
methods:{
send(){
this.$emit('child-msg',this.info);
}
}
}
}
}
}
})
</script>
需要强调的是,父子组件数据时单向更新的
- 当父组件数据变化时,子组件中的显示会实时更新。
- 当子组件数据变化时,需要触发事件来驱动父组件数据更新。
2.4 $children和$ref
当一个父组件中存在多个子组件时,可以通过$children来访问其下所有子组件,它会返回一个包含所有子组件的数组
<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>
网友评论