Vue使用组件的细节点

使用is标签解决标签渲染中的小bug

自定义一个组件,组件中有模板row,想在row中使用自定义组件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="root">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
Vue.component('row',{
template:'<tr><td>this is a row</td></tr>'
})
var vm=new Vue({
el:"#root"
})
</script>

结果遇到如下问题:代码不符合h5规范
在这里插入图片描述
tr里的内容出现在了tbody外面,这时需要使用vue中提供的is属性,表示虽然写的是tr标签,实际代表的是row组件

使用is标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script>
Vue.component('row',{
template:'<tr><td>this is a row</td></tr>'
})
var vm=new Vue({
el:'#root',
data:{
}
})
</script>
</body>

在这里插入图片描述

这样就不会有bug了,类似的还有 ul 和 li 、select和option标签等

子组件中的data必须定义为方法

尝试使用插值表达式显示数据,则将上述方法改写如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<body>
<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:{
content:'this is a row'
},
template:'<tr><td>{{content}}</td></tr>'
})
var vm=new Vue({
el:'#root',
data:{
}
})
</script>
</body>

出现错误:

在这里插入图片描述
而只需将自定义组件中的data变成方法即可正常显示

1
2
3
4
5
6
Vue.component('row',{
data: function(){
return {
content:'this is a row'
}
},

结论:在定义子组件时,子组件中的data必须定义为方法,因为不像根组件只会被调用一次,要避免和其他子组件的data重复

r e f 的使用

首先引入概念,Vue是不建议用来操纵DOM节点的,但对于一些复杂的项目仅靠Vue的数据绑定是不能实现的,故Vue引入了获取DOM节点的方法ref

对dom使用ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id="root">
<div @click="handle" ref="demo">HI Vue</div>
</div>
<script>
var vm=new Vue({
el:'#root',
methods:{
handle:function(){
//指整个Vue中所有引用里的demo引用
console.log(this.$refs.demo)
}
}
})
</script>
</body>

在这里插入图片描述
可打印出具体内容

1
console.log(this.$refs.demo.innerHTML)

以上是对dom节点使用ref,this.$refs.name获取到的是标签对应的DOM元素,而对于组件使用ref,使用this.$refs.name获取到的是子组件的引用

对组件使用ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<body>
<div id="root">
<div>
<counter ref="first" @change='handleChange'></counter>
<counter ref="second" @change='handleChange'></counter>
<div>{{total}}</div>
</div>
</div>
<script>
//创建子组件
Vue.component('counter',{
template:'<div @click="handle">{{number}}</div>',
data:function(){
return{
number:0
}
},
methods:{
handle:function(){
this.number++
//子组件向父组件传值,告诉父组件值发生变化了。
//当被点击时触发change事件,在父组件中监听事件@change并触发方法
this.$emit('change')
}
}
})
var vm=new Vue({
el:'#root',
data:{
total:0
},
methods:{
handleChange:function(){
console.log(this.$refs.first.number)
this.total=this.$refs.first.number+this.$refs.second.number
}
}
})
</script>
</body>

这样简单的计数功能就实现了

在这里插入图片描述

请我喝杯咖啡吧~

支付宝
微信