玩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项目又进了一步

Logo

前往低代码交流专区

更多推荐