欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue组件(全局注册、局部注册、prop传值)

程序员文章站 2022-05-26 11:11:50
...

vue组件使用

1、认识组件
(1) 创建组件的写法
写法: Vue.component("组件名",{ //xx }); //这里是全局注册组件的写法
Vue.component()函数的第一个参数就是组件名
比如Vue.component(“my-comname”,{ //xx}}); 那么my-comname就是新建组件的名称;

(2)注意:

  • 为了能在模板中使用,这些组件必须先注册以便 Vue能够识别;
  • 当直接在DOM中使用一个组件(而不是在字符串模板或单文件组件)的时候,建议遵循W3C规范中的自定义组件名(字母全部小写且必须包含一个连字符),避免和当前以及以后的HTML元素相冲突。
  • 有两种组件的注册类型:全局注册局部注册
    我们的组件都是通过 Vue.component 全局注册的。
    全局注册的组件可以用在它被注册之后的任何(通过new Vue)新创建的Vue根实例,
    也包括其组件树中的所有子组件的模板中。
  • 组件是可复用的 Vue 实例,且带有一个名字。

(3)定义组件名的方式:

  • 使用 kebab-case
    写法:Vue.component('my-component-name', { //xx })
    当使用 kebab-case (短横线分隔命名) 定义一个组件时,在引用这个自定义元素时也必须使用kebab-case,比如。

  • 使用 PascalCase
    写法:Vue.component('MyComponentName', { //xx })
    当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。即 和 都可以。
    注意:直接在DOM(即非字符串的模板)中使用时只有kebab-case是有效的。

<div id="app">
    <button-counter></button-counter>
    <hr>
    <div id="dv" style="width:200px;height:200px;background-color:lightblue;">
        <button-counter>我是#dv下的组件</button-counter>
    </div>
</div>
    <script src="js/vue.js"></script>
    <script>
        // 创建组件button-counter
        Vue.component('button-counter', {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">你点了{{count}}次</button>'
        });

        /*  本例的组件名字是<button-counter>。我们可以在一个通过new Vue创建的Vue根实例中,
            把这个组件作为自定义元素来使用。 */
        new Vue({
            el: '#app'
        });
    </script>

2、组件复用
组件的复用:组件可进行任意次数的使用
注意:

  • 每一个组件的data,必须是一个函数;

  • 每用一次组件, 就会有一个它的新实例被创建,组件之间不会相互影响。

    如下的示例中,当点击按钮时, 每个组件都会控制各自的count(点击次数)。

 <div id="id">
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
 </div>
    <script src="js/vue.js"></script>
    <script>      
        Vue.component("button-counter", {
            // 我们定义<button-counter>组件时,它的data并不是如下面这样直接提供一个对象
            // data:{
            //    count:0
            // },

            // 而是如下这样,一个组件的data选项必须是一个函数
            data: function () {
                return {
                    count: 0
                }
            },
            template:`<button @click="count++">点击{{count}}次</button>`
        });
        let app = new Vue({
            el: "#app"
        });
    </script>

3、全局注册组件
组件在注册之后可以用在任何新创建的Vue根实例(new Vue) 的模板中。
在所有子组件中也是如此,即这三个子组件在各自内部也都可以相互使用。

<style>
    #poemList,#songpoemList,#yuanoperaList{
         width: 300px;
         height: 200px;
         text-align: center;
         line-height: 30px;
   }
   span{
        display: block;
  }
  .poemName,.songpoemName,.yuanoperaName{
       width: 100%;
  }
  .poemContent{
      width: 200px;
      margin-left: 50px;
 }        
</style>
<div id="app">
    <mycomponet-a></mycomponent-a>
    <mycomponent-b></mycomponent-b>
    <mycomponent-c></mycomponent-c>
</div>
    <script src="js/vue.js"></script>
    <script>
        Vue.component('mycomponent-a', {
            data: function () {
                return {
                    poem_title: "唐诗",
                    poem_name: "《静夜思》- 李白",
                    poem_content: "床前明月光,疑是地上霜。举头望明月,低头思故乡。"
                }
            },
            template: `<div id="poemList"><h2>{{poem_title}}</h2><span class="poemName">{{poem_name}}</span><span class="poemContent">{{poem_content}}</span></div>`
        });

        Vue.component('mycomponent-b', {
            data: function () {
                return {
                    songpoem_title: "宋词",
                    songpoem_name:"《虞美人》- 李煜",
                    songpoem_content:"春花秋月何时了,往事知多少?小楼昨夜又东风,故国不堪回首月明!雕栏玉砌应犹在,只是朱颜改。问君能有几多愁?恰似一江春水向东流。"
                }
            },
            template: `<div id="songpoemList"><h2>{{songpoem_title}}</h2><span class="songpoemName">{{songpoem_name}}</span><span class="songpoemContent">{{songpoem_content}}</span></div>`
        });

        Vue.component('mycomponent-c', {
            data: function () {
                return {
                    yuanopera_title: "元曲",
                    yuanopera_name:"《天净沙-秋思》- 马致远",
                    yuanopera_content:"枯藤老树昏鸦,小桥流水人家,古道西风瘦马。夕阳西下,断肠人在天涯。"
                }
            },
            template: `<div id="yuanoperaList"><h2>{{yuanopera_title}}</h2><span class="yuanoperaName">{{yuanopera_name}}</span><span class="yuanoperaContent">{{yuanopera_content}}</span></div>`
        });

        new Vue({
            el: '#app',
        })
    </script>

4、局部注册组件
全局注册往往是不够理想的。比如,你使用一个像webpack打包项目。
如果是全局注册所有的组件, 那么当你不需要使用某个或某些组件时,
它仍然会包含在你最终的包中。会造成了用户下载不必要的js。
这就需要我们注册局部组件。
对于components 对象中的每个属性来说,其属性名就是自定义元素的名字
其属性值就是这个组件的选项对象

 <div id="app">
        <localcom-a message="我是局部组件"></localcom-a>
        <localcom-b message="我是局部组件的兄弟"></localcom-b>
        <localcom-c message="上面是我大哥和二哥"></localcom-c>
    </div>
    <hr>

    <div id="app2">
        <mycom-x info="新组件"></mycom-x>
        <mycom-y info="我也是新组件"></mycom-y>
    </div>
    <script src="js/vue.js"></script>
    <script>
        //由于前面说的全局注册组件带来的问题,我们可以通过一个普通的js对象来定义组件,如下:
        var ComponentA = {
            props: ["message"],
            template: `<div id="dv1"><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
        }
        var ComponentB = {
            props: ["message"],
            template: `<div><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
        }
        var ComponentC = {
            props: ["message"],
            template: `<div><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
        }

        // 然后在 components 选项中定义你想要使用的组件:
        let app = new Vue({
            el: '#app',
            components: {
                'localcom-a': ComponentA,
                'localcom-b': ComponentB,
                'localcom-c': ComponentC
            }
        })
        console.log(app);

        // 注意:局部注册的组件在其子组件中不可用。
        // 比如,你想组件a可以在组件中可用,如下写法:
        var myComX = {
            props: ["info"],
            template: `<div><h1>{{info}}</h1><input type='text' v-model='info'></input></div>`
        }

        var myComY = {
            components: {
                'mycom-x': myComX
            }
        }
        let app2 = new Vue({
            el: "#app2",
            components: {
                'mycom-x': myComX,
                'mycom-y': myComX
            }
        });
        console.log(app2);


        // 或者如果你通过 Babel 和 webpack使用ES2015模块,如下:
        // import ComponentA from './ComponentA.vue'
        // export default {
        //     components: {
        //         ComponentA
        //     },
        //     // ...
        // }
        /*注意
        在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:
        用在模板中的自定义元素的名称
        包含了这个组件选项的变量名 
        */
    </script>

5、prop传值
Prop可以在组件上注册的一些自定义的attribute。
当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个属性
为了给组件传递一个标题,我们可以用一个props选项将其包含在该组件可接受的prop列表中.
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
在上例中,我们能够在组件的实例中访问这个值,就像访问 data 中的值一样。

 <!-- 一个prop被注册之后,可以把数据作为一个自定义的attribute传递进来 -->
    <div id="app">
        <!-- <article-post title="学习Vue指令"></article-post>
        <article-post title="学习Vue事件"></article-post>
        <article-post title="学习Vue组件"></article-post> -->
        
        <article-post v-for="article in articles" :key="article.id" 
        v-bind:title="article.title"></article-post>
    </div>
    <script src="js/vue.js"></script>
    <script>
        Vue.component('article-post', {
            props: ['title'],
            template: '<h3>{{ title }}</h3>'
        });

        let app = new Vue({
            el: "#app",
            data: {
                articles: [{
                        id: 1,
                        title: '学习Vue指令'
                    },
                    {
                        id: 2,
                        title: '学习Vue事件'
                    },
                    {
                        id: 3,
                        title: '学习Vue组件'
                    }
                ]
            }
        });
    </script>