1. 程式人生 > >Vue.js的全域性/區域性元件填坑記

Vue.js的全域性/區域性元件填坑記

玩Vue也有一段日子了,最近陷在元件坑裡差點出不來,還好有SegmentFault高人指點,特將細節分享出來一起學習提高。

起因:最早一直用的是標頭檔案引入Vue,即<script src="js/vue.min.js"></script>,這樣做的缺點是每次都需要建立新例項且並不符合專案工程化的需求。

解決方案:使用node.js+npm安裝Vue,再使用IDE(WebStorm)開啟專案實現熱載入。

問題:然後在使用全域性元件的時候碰到一個坑:

<template>
    <div id="app">
        <h1>This is a test file</h1>
        <span>{{ msg }}</span>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
    </div>
</template>

<script>
    Vue.component( 'simple-counter', {
        template: '<button v-on:click="counter += 1">{{ counter }}</button>',
        data () {
            return {
                counter: 0
            }
        }
    })

    new Vue({
        el: '#app',
        data () {
            return {
                msg: 'Hello, commander!'
            }
        }
    })
</script>


程式碼如上,之前標頭檔案引入vue.js能夠正常工作,如圖實現能夠分別計數的simple-counter元件


而現在卻報錯了

度娘無果之後只好去SegmentFault提問,高人回答直戳要害:

https://segmentfault.com/q/1010000009870708?_ea=2079052


確實如大神所說在main.js已經例項化了Vue,如果再在單檔案元件中建立例項會報錯。

之後參照建議將全域性元件放入main.js中,更新了程式碼:

App.vue:

<template>
    <div id="app">
        <h1>This is a test file</h1>
        <span>{{ msg }}</span>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
    </div>
</template>

<script>
    export default({
        data () {
            return {
                msg: 'Hello, commander!'
            }
        }
    })
</script>
main.js:
import Vue from 'vue'
import App from './App_1.vue'

//全域性元件
Vue.component( 'simple-counter', {
    template: '<button v-on:click="counter += 1">{{ counter }}</button>',
    data () {
        return {
            counter: 0
        }
    }
})

new Vue({
  el: '#app',
  render: h => h(App)

})



如圖,果然能正常工作了!

同理,區域性元件也是一樣的寫法:

<script>
    var Child = {
        template: '<button v-on:click="counter += 1">{{ counter }}</button>',
        data () {
            return {
                counter: 0
            }
        }
    }

    export default({
        data () {
            return {
                msg: 'Hello, commander!'
            }
        },
        components: {
            'simple-conter': Child
        }
    })
</script>


與此同時我還發現了一個有趣的現象:當全域性元件與區域性元件同時存在的時候,全域性元件會被區域性元件覆蓋!

進一步思考,如果專案元件部分過於龐大,使用單檔案元件可能導致後期維護困難,所以可以考慮解耦:

將元件部分分離到另一個頁面,使用的時候再import

App.vue:

<template>
    <div id="app">
        <h1>This is a test file</h1>
        <span>{{ msg }}</span>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
        <simple-counter></simple-counter>
    </div>
</template>

<!--外部匯入區域性元件-->
<script>
    //引入
    import simple_counter from './component/simple-counter.vue';
    //註冊
    export default {
        data () {
            return {
                msg: 'Hello commander!'
            }
        },
        components: {
             'simple-counter': simple_counter
        }
    }
</script>

simple-counter.vue:
<template>
    <div id="app">
        <button v-on:click="counter += 1">{{ counter }}</button>
    </div>
</template>

<script type="text/javascript">
    export default {
        data () {
            return {
                counter: 0
            }
        }
    }
</script>


解耦後的元件方便修改且易於查詢,如此距離工程化的Vue專案又進了一步