Vue学习笔记之深入理解Vue组件一
组件基础
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
组件是可复用的 Vue 实例,且带有一个名字。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="components-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项
使用组件的细节点
1.组件中使用is解决标签规范
例子:
<div id="app">
<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: '#app'
})
</script>
打开浏览器:出现三行row 显示似乎没有问题,可以当我们查看查看器时
发现三行rows显示在了table外面!这是因为html5的规范里tbody里面必须放的是tr,而我们放的是row,所以它是不能正常解析的。这时候我们可以使用Vue提供的is来解决类似问题i,我们把代码修改为:
<table>
<tbody>
<tr is='row'></tr>
<tr is='row'></tr>
<tr is='row'></tr>
</tbody>
</table>
类似的ol,ul都可以使用is来解决标签规范造成的bug。
2.非根组件中data必须是函数
继续上面的例子我们把代码修改为
Vue.component('row', {
data: {
content: 'this is a row'
}
template: '<tr><td>{{content}}</td></tr>'
})
这样是会报错的,如果是一个根组件,用上面的方法是没问题的,可当我们在非根组件的子组件中定义data时,data必须是function而不是对象,而且这个函数需要返回一个对象,对象里包含你的数据。
Vue.component('row', {
data: function () {
return {
content: 'this is a content'
}
},
template: '<tr><td>{{content}}</td></tr>'
})
这么设计是因为,一个子组件不像根组件,只会被调用一次,它可能被调用很多次,我们希望每一个子组件不和其它子组件数据相冲突,每个子组件不互相影响。
3.操作dom
Vue是不建议我们在代码中操作dom的,可是有时候在处理一些复杂的动画效果时候,有时候我们还真需要操作dom。
ref
我们可以通过像标签添加ref属性的方法获取dom节点,通过this.$refs.xxx取得该dom节点
<div id="root">
<div
ref='hello'
@click='handleClick'
>
hello world
</div>
</div>
<script type="text/javascript">
var vm =new Vue({
el: '#root',
methods: {
handleClick: function ( ) {
console.log(this.$refs.hello);
}
}
})
</script>
我们点击后查看控制台,可以看到得到了这个div
那么组件中使用ref属性的情况呢?
<div id="root1">
<counter
@change="handleChange"
ref="one"
></counter>
<counter
@change="handleChange"
ref="two"
></counter>
<div>
{{total}}
</div>
</div>
<script type="text/javascript">
Vue.component('counter',{
template: "<div @click='handleClick'>{{number}}</div>",
data () {
return {
number: 0
}
},
methods: {
handleClick: function () {
this.number++;
this.$emit('change')
}
}
})
var vm =new Vue({
el: '#root1',
data: {
total:''
},
methods: {
handleChange: function ( ) {
this.total=this.$refs.one.number+this.$refs.two.number
}
}
})
</script>
通过运行这段代码,可以看出this.$refs.xxx取得的是子组件的引用。