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取得的是子組件的引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章