Vue 组件基础用法

本文围绕Vue组件的基础用法展开,介绍了组件可扩展HTML元素、封装代码,实现页面拼接,使前端页面易扩展、灵活性高且组件解耦。还详细阐述了组件注册(全局、局部、嵌套)、模板分离、命名约定、模板限制、根元素、data函数及原生事件等方面的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面的话

组件是Vue.js最核心的功能,也是整个框架设计最精彩的地方。组件可以扩展HTML元素,封装可重用的代码。根据项目需求,抽象出一些组件,每个组件里包含了展现、功能和样式。每个页面,根据自己所需,使用不同的组件来拼接页面。这种模式使前端页面易于扩展,且灵活性高,而且组件之间也实现了解耦。

概述
 <div id="app">
     <xiao-qi></xiao-qi>
  </div>

上面这个例子中的自定义标签< xiao-qi>< / xiao-qi>就是一个组件。组件是一个自定义元素或称为一个模块。

组件注册

注册组件包括全局注册和局部注册

[全局注册]

全局注册后,任何Vue实例都可以使用。要注册全局组件可以使用Vue.component(‘tagName’,{})的语法形式。

  Vue.component('my-component',{
             // 选项
         });

my-component就是注册的组件自定义标签名称,推荐使用小写加减号分割的形式命名。
注意: 要想在父实例中使用这个组件,必须要在实例创建前注册,之后就可以使用 的形式来使用组件。

<div id="app1">
     <my-component></my-component>
 </div>
 <script>
 // 全局注册
  Vue.component('my-component',{
        template: '<p> 这是组件的内容 </p>'
    });
   // 创建实例
	  var app1 = new Vue({
        el: '#app1'
    })
</script>

在这里插入图片描述
在组件选项中添加template选项就可以显示组件的内容。template中的DOM结构必须被一个元素包含,如果直接写成“这是组件的内容”不带“< div>< /div>” 是无法渲染的。

[局部注册]

在Vue实例中使用components选项可以局部注册一个组件,注册后的组件只有在该实例作用域下有效。

<div id="app2">
         <my-component></my-component>
 </div>
<script>
	var Child = {
        template: '<p>这是一个局部组件</p>'
    }
    var app2 = new Vue({
        el: "#app2",
        components: {
            'my-component': Child
        }
    });
</script>

在这里插入图片描述

[组件嵌套]

组件中还可以使用components选项嵌套组件

 <div id="app3">
        <my-component></my-component>
  </div>
<scirpt>
	 var headTitel = {
        template:'<p>我是一个标题</p>'
    };
    var headText = {
        template: '<p>我是内容</p>'
    };
    var header = {
        template: `<div>
               <headTitel></headTitel>
                <headText></headText>
        </div>`,
        // 组件内使用components注册组件
        components: {
            'headTitel': headTitel,
            'headText': headText
        }
    }
	var app3 = new Vue({
        el: '#app3',
        components: {
            'my-component': header
        }
    })
</script>

在这里插入图片描述

模板分离

在template选项中拼接HTML元素比较麻烦,也导致了HTML和JS的高耦合性。庆幸的是Vue提供两种方式将定义在js中的HTML模板分离出来。
[script]

在script标签里使用text/x-template类型,并且指定一个id 。

<script type="text/x-template" id="hello-vue-template">
      <p>Hello Vue</p>
 </script>   
 Vue.complate('hello-world',{
      template: '#hello-vue-template'
      })

相当于

Vue.complate('hello-world',{
            template: '<p>Hello Vue</p>'
  })  

示例

 <div id="app4">
        <my-component></my-component>
    </div>
    <script type="text/x-template" id="example-template">
        <p>小示例</p>
    </script>
<script>
	var app4 = new Vue({
        el: '#app4',
        //局部注册
        components: {
            'my-component':  {
                template: '#example-template'
            }
        }
    })
</script>

在这里插入图片描述

[template]

如果使用标签,则不需要指定type属性

   <div id="app5">
         <my-component></my-component>
     </div>
     <template id="hello-template">
        <div>hello Vue.js</div>
     </template>
<script>
	 var app5 = new Vue({
        el: "#app5",
        components: {
            'my-component': {
                template: "#hello-template"
            }
        }
    })
</script>

在这里插入图片描述

命名约定

对于组件的命名,W3C规范是字母小写且包含一个中划线(-),虽然Vue没有强制要求,但最好遵循规范。

在HTMl模板中始终使用 kebab-cased-component

  <kebab-cased-component></kebab-cased-component>
  <camel-cased-component></camel-cased-component>
  <pascal-cased-component></pascal-cased-component>

在注册组件时,使用中划线、小驼峰、大驼峰三种任意一种

  components: {
        // 使用 中划线形式注册
        'kebab-cased-complate':{},
        //使用 小驼峰形式注册
        'camelCasedComponent':{},
        // 使用 大驼峰形式注册
        'PascalCasedComponent':{}
      }
模板限制

Vue组件的模板在某些情况在会受到HTML的限制,比如< table>内规定只允许
是< tr>、< td>、< th>等这些表格元素,所以在< table>内直接使用组件时无效的. 这种情况下可以使用is属性来挂载组件。

[is属性]

<div id="app6">
        <table>
            <tbody is="my-component1"></tbody>
        </table>
    </div>
    <template id="g-template">
        <p>这是挂载的组件</p>
    </template>
 <script>
 	 Vue.component('my-component1',{
        template: "#g-template"
    });
	 var app6 = new Vue({
        el:"#app6",
    })
</script>

在这里插入图片描述
tbody在渲染时,会被替代为组件的内容。常见的限制元素还有ol、ul、select

注意:如果使用的是字符串模板,是不受限制的。

根元素

Vue强制要求每个Vue实例(组件本质就是一个Vue实例)需要有一个根元素.否则会报错。

   <div id="app7">
            <my-component2></my-component2>
      </div> 
 <script>
  Vue.component('my-component2',{
    template: `         
        <p>第一段</p>
        <p>第二段</p>        
    `
});
  var app7 = new Vue({
    el:"#app7",
})
</script>

在这里插入图片描述

需要改写为:

         Vue.component('my-component2',{
        template: ` 
            <div>        
            <p>第一段</p>
            <p>第二段</p> 
            </div>       
        `
    });
data函数

除了template选项外,组件中还可以使用项Vue实例那样其他的选项,比如data、computed、 methods等。但是在使用data时,和实例稍微有点区别,data必须是函数,然后将数据return出去

  <div id="app8">
        <my-component3></my-component3>
  </div>
<script>
 Vue.component('my-component3',{
        template: '<div>{{ message }}</div>',
        data() {
            return {
                message: '组件内容'
            }
        }
    })
  var app8 = new Vue({
        el:"#app8",
    })  
</script>

在这里插入图片描述
注意:
js对象是引用关系,所以如果return出的对象引用了外部的一个对象,那么这个对象就是共享的,任何一方修改都会同步。

例如:

  <div id="app9">
         <my-component4></my-component4>
         <my-component4></my-component4>
         <my-component4></my-component4>
  </div>
<script>
 var data = {
        counter: 0
    };
    var app9 = new Vue({
        el: '#app9',
        components: {
            'my-component4':{
                template: '<button @click="counter++">{{ counter }}</button>',
                data(){
                    return  data
                }
            }      
        }
    })	
</script>  

在这里插入图片描述
上面这个示例的data对象就是共享的。组件使用了3次,但是点检的任意一个button,3个的数字都会加1 就是因为组件的data引用的是外部对象。

这肯定不是我们所希望的,可以给组件返回一个新的data对象来 独立。

将上面的组件改为:

      components: {
        'my-component4':{
            template: '<button @click="counter++">{{ counter }}</button>',
            data(){
                return   {
                    counter: 0
                }
            }
        }      
    }

这样3个按钮就不会相互影响了

原生事件

有时可能我们想在组件的根元素上监听一个事件。直接使用v-on指令时不生效的。

 <div id="app10">
         <my-component @click="doSomeThing"></my-component>
         <p>{{ message}}</p>
  </div>
<script>
		 var app10 = new Vue({
        el:"#app10",
        components: {
            'my-component': {
                template: '<button>按钮</button>'
            }
        },
        data: {
            message: 0
        },
        methods: {
            doSomeThing: function() {
                this.message++;
return this.message;
            }
        }
    })
</script>

无论怎么点击都没有反应
在这里插入图片描述
可以使用 .native 修饰 v-on指令即可

 <div id="app10">
         <my-component @click.native="doSomeThing"></my-component>
         <p>{{ message}}</p>
 </div>
 <script>
		 var app10 = new Vue({
        el:"#app10",
        components: {
            'my-component': {
                template: '<button>按钮</button>'
            }
        },
        data: {
            message: 0
        },
        methods: {
            doSomeThing: function() {
                this.message++;
return this.message;
            }
        }
    })
</script>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

crazy的蓝色梦想

如果对你有帮助,就鼓励我一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值