细节点一、 组件定义的标签名与html规范的冲突
vue 想给table 标签中的 tr 标签定义为一个组件,但下面这样写会不对:
<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>
哪里不对呢?渲染的dom tr 与table 的顺序变了。
这是因为 html5 规定, table 中得有 tbody, tbody 中必须有 tr. 而模版中标签为row , 因此会出现这种问题。
解决:使用Vue 提供的 is 属性
<div id="root">
<table>
<tbody>
<tr is="row"></row>
<tr is="row"></row>
<tr is="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>
同理,ul , ol, select .
细节点二、 子组件的data 与 根组件的data 是不同的
子组件data,想向根组件,属性定义一样,如下,是不行的。
<div id="root">
<table>
<tbody>
<tr is="row"></row>
<tr is="row"></row>
<tr is="row"></row>
</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"
})
</script>
在根组件中,data 才可以以对象方式定义。在非根组件中,data 只能以function 方式定义,且这个函数返回一个对象,该对象包含想要定义的数据,如下。
<div id="root">
<table>
<tbody>
<tr is="row"></row>
<tr is="row"></row>
<tr is="row"></row>
</tbody>
</table>
</div>
<script>
// 全局组件
Vue.component("row",{
data: function(){
return {
content: "this is content"
}
},
template: "<tr><td>{{content}}</td></tr>"
})
var vm = new Vue({
el: "#root"
})
</script>
这样设计的原因是,子组件不像根组件,子组件会被多次调用,因此不希望,多次调用的时候数据产生冲突。因此,每个子组件的数据,都是分开的,并不共享。每个子组件都有独立的数据存储。
细节点三、 vue 获取dom 节点 ref
vue 不推荐操作dom,但必要的时候,需要操作获取dom,可以使用ref
当在一个html 标签中使用 ref 时,获得的是这个dom 元素,可在控制台打印出来看一下。
<div id="root">
<div ref="hhi" @click="handleClick">hello</div>
</div>
<script>
// 全局组件
Vue.component("row",{
data: function(){
return {
content: "this is content"
}
},
template: "<tr><td>{{content}}</td></tr>"
})
var vm = new Vue({
el: "#root",
methods: {
handleClick: function(){
console.log(this.$refs.hhi);
console.log(this.$refs.hhi.innerHTML);
}
}
})
</script>
细节点四、 子组件向父组件传值
在组件中使用 ref 获得的将是该组件的引用,可以在控制台打印出来看一下。
<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,
nnn: 2
}
},
methods: {
handleClick: function(){
this.number ++ ;
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>