关键词:
- is 标签 解决 H5标签上的 bug
- 子组件里定义data,data值必须为一个函数
- ref这个引用的使用
(一)细节一 is标签解决模板标签上渲染时可能出现的小bug
1、出现需求:H5标签元素中如何正确使用子组件
<table><tbody><tr><td></td></tr></tbody></table>
<body>
<div id="root">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
//全局组件
Vue.component('row', {
template: '<tr><td>This is a woman</td></tr>'
})
var vm = new Vue({
el: "#root"
})
</script>
</body>
2、出现问题:查看后台审查元素,看看页面的渲染情况:发现<tr>与<table>处于平级,这是不合理的。因为 H5的规范中要求我们需要按以下的嵌套方式写表格标签的代码:
<table><tbody><tr><td> </td></tr></tbody></table>。类似还有<ul><ol><li></li></ol></ul>、<section><option></option></section>
但通过子组件row去解析<tr><td> </td></tr>这部分,则会出现问题
3、解决方法:使用is标签在H5标签中使用子组件
这样做,既保证tr使用了row这个子组件,又符合H5的编码规范
<body>
<div id="root">
<table>
<tbody>
<!-- 使用is标签在H5标签中使用子组件 -->
<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 woman</td></tr>'
})
var vm = new Vue({
el: "#root"
})
</script>
</body>
(二)细节二 子组件里定义data,值必须为一个函数(函数返回的值为一个对象)
1、出现需求:在子组件定义data时传递内容
<script>
//全局组件
Vue.component('row', {
data: {
content: 'this is a woman'
},
template: '<tr><td>{{content}}</td></tr>'
})
var vm = new Vue({
el: "#root"
})
</script>
2、出现错误:将子组件所显示的内容,通过data中的一个对象:content进行定义,错误提示data需要用一个函数方法去返回一个对象值
3、解决方法:子组件定义data时,值必须为一个函数(函数返回一个对象,对象要包含你所对应的数据)
<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: function() {
return {
content: 'this is a woman'
}
},
template: '<tr><td>{{content}}</td></tr>'
})
var vm = new Vue({
el: "#root"
})
</script>
</body>
在根组件里(最外层的Vue实例),如果定义data,定义data时,值直接用一个对象,并不会出现什么错误。但如在非根组件中(子组件)定义data时,就不能用一个对象,而是要求data后的值必须为一个函数(函数返回为一个对象)。
4、为什么子组件定义data时,值为一个函数?
这是因为子组件在调用时,不像根组件只调用一次,可能会在同一个地方调用多次。每一个子组件在调用时,都应该有自己的数据,而通过一个函数返回一个对象值的目的,就能让每一个子组件都拥有一个独立的数据存储,这样不会有多个子组件互相影响的情况出现。
(三)细节三 ref 引用的案例 (一般使用 this.$http://refs.xxx来引用组件里的内容)
一、在Vue中如何操作dom
1、出现需求:ref引用获取dom节点和dom内容 ?
2、解决方法:一般是如 this.$http://refs.xxx 获取dom节点,来进行dom操作,如
this.$refs.miya
this.$refs.miya.innerHTML
<body>
<div id="root">
<div ref='miya'
@click="handleClick"
>
hello world
</div>
</div>
<script>
var vm = new Vue({
el: "#root",
methods: {
handleClick: function(){
// console.log(this.$refs.miya) //指向的就是这个div的节点
alert(this.$refs.miya.innerHTML) //获取dom节点的内容,会弹出弹窗
}
}
})
</script>
</body>
二、动态获取组件内容
1、出现需求:制作一个计数器,并且能够点击数字就按顺序+1
2、解决方法:
<body>
<div id="root">
<!-- 父级的组件上直接使用这个子组件 -->
<counter></counter>
<counter></counter>
</div>
<script>
Vue.component('counter', {
template: '<div @click="handleClick">{{number}}</div>',
data: function(){
return {
number: 0
}
},
methods: {
handleClick: function(){
this.number ++ //每点击一次,number上的数字就会+1
}
}
})
var vm = new Vue({
el: "#root"
})
</script>
</body>
试一下吧!
1、出现需求:对两个 counter 组件进行求和
2、解决方法:实现一个发布订阅的功能
- 子组件向父组件发送数据:向外界触发事件(这里用 this.$emit="change" )用于告知,即在子组件定义 methods 使用 $emit
- 父组件中counter组件:用于监听该触发事件,即绑定一个事件监听方法(这里@change="xxx")
- Vue实例定义methods,使用这个绑定后的方法
试一下:看看页面的效果吧,分别点击两个counter组件的数字,都能弹出一个change的窗口
1、出现需求:这样一想,只需在change方法里做一个求和功能就可以实现求和
2、解决方法:使用 ref 引用形式
在子组件中分别在两个子组件下使用 ref ,在Vue实例中handleChange里计算两个子组件(this.$refs.one.number 和 this.$refs.two.number)的 和
代码如下:
<body>
<div id="root">
<!-- 父级的组件上直接使用这个子组件 -->
<counter ref="one" @change="handlechange"></counter>
<counter ref="two" @change="handlechange"></counter>
<div>{{total}}</div>
</div>
<script>
Vue.component('counter', {
template: '<div @click="handleClick">{{number}}</div>',
data: function(){
return {
number: 0
}
},
methods: {
handleClick: function(){
this.number ++ //每点击一次,number上的数字就会+1
this.$emit('change')
}
}
})
var vm = new Vue({
el: "#root",
data: {
total: 0
},
methods: {
handlechange: function(){
this.total = this.$refs.one.number + this.$refs.two.number
}
}
})
</script>
</body>