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>

打开浏览器:Vue学习笔记之深入理解Vue组件一出现三行row 显示似乎没有问题,可以当我们查看查看器时
Vue学习笔记之深入理解Vue组件一
发现三行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
Vue学习笔记之深入理解Vue组件一
那么组件中使用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取得的是子组件的引用。