VueJS Component 组件

  • 什么是组件

    组件 (Component)Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。
    组件是对特点功能代码(html,css,js)的封装, 通过组件的名字可以重复利用该组件中的代码。
    注意:组件的 template 模板必须有且只有一个根标签(所有内容必须由一个标签套起来)。
  • 全局组件

    语法:Vue.component("自定义标签的名字",{配置对象})
    全局组件的特点:
    • 全局组件可以在任何被挂着的标签中使用。
    • 全局组件的配置对象中必须包含 template 属。
    如果该组件的特定功能需要在任何被 Vue 实例挂载的标签中使用;推荐使用全局组件:
    <div id="app">
       //引用全局组件:方式一
       <component1></component1>
    </div>
    
    <div id="app2">
       //引用全局组件:方式二
       <component2></component2>
    </div>
    
    <div id="app3">
       //引用全局组件:方式三
       <component3></component3>
    </div> 
    
    //方式二:定义模板(注意:如果使用script标签,建议加上type="text/template")
    <script type="text/template" id="component2">
       // 这个div是根标签
       <div>
           <h1>全局组件(方式二)</h1>
       </div>
    </script>
    
    // 方式三:定义模板(建议使用)
    <template id="component3">
       //这个div是根标签
       <div>
             <h1>全局组件(方式三)</h1>
       </div>
    </template>
    
    <script>
    //定义全局组件(方式一)
    Vue.component("component1",{
        template:"<h1> 全局组件(方式一)</h1>"
    });
    
    //定义全局组件(方式二)
    Vue.component("component2",{
        template:"#component2"
    });
    
    //定义全局组件(方式三)
    Vue.component("component3",{
        template:"#component3"
    });
          
    //挂载vue实例(方式一)
    var app= new Vue({
        el:"#app",
    });
    
    //挂载vue实例(方式二)
    var app2= new Vue({
        el:"#app2",
    });
    
    //挂载vue实例(方式三)
    var app3= new Vue({
        el:"#app3",
    });
    </script>
    
    尝试一下
  • 局部组件

    局部组件是定义在某个 vue 实例上的
    局部组件语法:
    var app = new Vue({
      el: "#app",
      data: {},
      components : {
        "局部组件的名字1" : {组件的配置对象}
        "局部组件的名字2" : {组件的配置对象}
      }
    });
    
    局部组件只能够在所挂载的标签中使用:
    <div id="app">
       //引用局部组件:方式一
       <component1></component1>
       <hr />
       //引用局部组件:方式二
       <component2></component2>
       <hr />
       //引用局部组件:方式三
       <component3></component3>
    </div>
    //方式二:定义模板(注意:如果使用script标签,建议加上type="text/template")
    <script type="text/template" id="component2">
       // 这个div是根标签
       <div>
           <h1>局部组件(方式二)</h1>
       </div>
    </script>
    
    // 方式三:定义模板(建议使用)
    <template id="component3">
       //这个div是根标签
       <div>
             <h1>局部组件(方式三)</h1>
       </div>
    </template>
    
    <script>
    var app= new Vue({
       el:"#app",
       components:{
           //定义局部组件(方式一)
           "component1":{
                template:"<h1> 局部组件(方式一)</h1>"
           },
           //定义局部组件(方式二)
           "component2":{
               template:"#component2"
           },
           //定义局部组件(方式三)
           "component3":{
               template:"#component3"
           },
       }
    })
    </script>
    
    尝试一下
  • 组件中的数据必须是函数

    组件中数据的定义:
    "组件的名字":{
       template: "",
       data : function(){
          return {
             键1:值1,
             键2:值2
          }
       }
    }
    
    要注意的事项:
    • data 数据只能够以函数的形式返回,因为函数中可以写其他的业务代码。
    • 只能够在各自的组件模板中使用各自的组件中的 data 数据。
    • Vue 对象中的数据不能够在组件中使用,组件的数据也不能够在挂载的 html 标签上使用。
    示例:
    <div id="app">
       // 这里引用的message是vue实例里的data数据
       {{message}}
       //引用组件
       <component1></component1>
    </div>
    
    <template id="component1">
       //这个div是根标签
       <div>
             <h1>我是全局引入的组件</h1>
       </div>
    </template>
    
    <script>
    var app= new Vue({
       el:"#app",
       data:{
           message:"这里是菜鸟教程"
       },
       components:{
           //定义局部组件(方式一)
           "component1":{
               template:"#component1",
               data:function(){
                   return {
                       message:"我是局部组件!!"
                   }
               }
           }
       }
    })
    </script>
    
    尝试一下
  • 组件中的 name 属性

    在给子组件定义属性的时候,通常第一个属性就是 name,例如下面:
    <script>
    export default {
       name: 'VHeader',
       data () {
          return {}
       },
       methods: {
       }
    }
    </script>
    
    定义 name 属性一般有三个方面的作用:
    • 为了方便在组件自身调用自身出现递归的时候便于调用。
    • 单独取消某个页面的 keepalive 缓存时更好的调用。
    • 使用 vue 工具进行查看网页结构的时候更好的查看网页结构。
  • 组件中的 is 属性

    我们通常使用 is 属性解决模板标签 bug 的问题。下面我们通过一个 table 标签的 bug 案例进行说明。
    我们先写一个简单的 Vue 实例,并创造一个 row 的组件,将它的模板 template 置为 '<tr><td>这个是td内容</td></tr>',按照下面的示例进行放置:
    <div id="app">
    <table>
       <tbody>
          <row></row>
          <row></row>
          <row></row>
       </tbody>
    </table>
    </div>
    <script>
       Vue.component('row',{
          template: '<tr><td>这个是td内容</td></tr>'
       });
    
       var vm = new Vue({
          el: "#app"
       });
    </script>
    
    该示例中,由于 H5 的规范 table 标签下 tbody 下只能是 tr,所以浏览器在渲染的时候出了问题。可以看到组件 row 渲染的 "这个是td内容" 都跑到了 table 之外。
    is属性
    解决这个问题的方法就是,我们按照规范在 tbody 之下使用 tr 。但我们用 is=tr 变成 row 组件:
    <div id="app">
    <table>
       <tbody>
          <tr is="row"></tr>
          <tr is="row"></tr>
          <tr is="row"></tr>
       </tbody>
    </table>
    </div>
    <script>
       Vue.component('row',{
          template: '<tr><td>这个是td内容</td></tr>'
       });
    
       var vm = new Vue({
          el: "#app"
       });
    </script>
    
    尝试一下
    这样我们在遵循规范的同时,也使用了 Vuejs 的组件模板;可以看到接下来的浏览器 DOM 渲染已经正常,如下图所示:
    is属性