如何使用is
标签解决渲染中可能会出现的小bug
<div id="root">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>;
Vue.component("row", {
template: "<tr><td>this is a row</td></tr>",
});
let vm = new Vue({ el: "#root" });
正常渲染一个组件这样写没有啥问题,但是在table
中会有点小bug
,如下图
正常来说3
个tr
应该在tbody
里面,而现在和table
同级了,这是怎么回事呢?
在HTML5
规范中,tbody
里面必须是tr
标签,否则会出错。该怎么解决呢?看下面代码
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>;
Vue.component("row", {
template: "<tr><td>this is a row</td></tr>",
});
let vm = new Vue({ el: "#root" });
这里的意思是tbody
里面我要用一个组件,但我不能直接使用组件,所以我就写了一个tr
,我用is
表示,虽然这里写的是tr
,但实际上它是名为row
的组件。这样写,既能保证tr
里面显示的使我们的组件,又能保证它符合HTML5
的规范,程序就不会有bug
了。如下图所示:
用is
属性就变成了我们想要展示的效果了。is
属性还可以用在ul
、ol
、select
标签中。
在根组件里面,data
可以直接定义成对象,而非根组件,data
必须定义成函数,且返回一个对象。
因为根组件只会被调用一次,而非根组件可以被调用很多次,但我们是希望每个组件的数据是独享的。
data(){
return {
content: 'this is content'
}
}
<div id="root">
<div ref="hello" @click="handleClick" ></div>
</div>
<script>
let vm = new Vue({
el: '#root',
methods: {
handleClick(){
console.log(this.refs.hello) // 获取到 hello 节点
}
}
})
</script>
点击时,可以获取到hello
节点。
那要是ref
写在组件上,获取到的应该是什么呢?
<div id="root">
<counter ref="one" @change="handleChange" ></counter>
<counter ref="two" @change="handleChange" ></counter>
<div>{{total}}</div>
</div>
Vue.component('counter', {
template: '<div @click="handleClick">{{number}}</div>',
data() {
return { number: 0 }
},
methods: {
handleClick(){
this.number ++
this.$emit('change')
}
}
})
let vm = new Vue({
el: '#root',
data:{ total: 0 },
methods: {
handleChange() {
this.total = this.$refs.one.number + this.$refs.two.number
}
}
})
通过this.$refs.名字
可以获取到标签对应的DOM
元素,而当你在一个组件上去写ref
然后通过this.$refs.名字
时获取到的是对应子组件的引用。
向组件传递的属性时,在组件内没有声明,会被自动挂载到组件的根结点中。
v-model
是双向绑定的语法糖,在自定义组件中Vue
也提供了v-model
指令。
<template>
<input v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
</template>
<script>
export default {
name: "base-checked",
model: {
prop: "checked",
event: "change"
},
props: {
checked: Boolean
}
}
</script>
// app.vue
<template>
<div id="app">
<BaseChecked type="checkbox" v-model="lovingVue"/>
</div>
</template>
<script>
import BaseChecked from './components/BaseChecked.vue'
export default {
name: 'App',
components: {
BaseChecked
},
data() {
return {
lovingVue: true
}
}
}
</script>
v-model
只支持一个属性,如果需要支持多个双向绑定的属性,可以使用修饰符.sync