vue 注册组件的使用详解


Posted in Javascript onMay 05, 2018

一、介绍

       组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树

vue 注册组件的使用详解

 那么什么是组件呢?

  组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素。

二、如何注册组件

   Vue.js的组件的使用有3个步骤:创建组件构造器、注册组件和使用组件。

vue 注册组件的使用详解

 下面用代码演示这三步

<!DOCTYPE html>
<html>
 <body>
  <div id="app">
   <!-- 注意: #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
   <my-component></my-component>
  </div>
 </body>
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
 <script>
  <!-- 1.创建一个组件构造器 -->
  var myComponent = Vue.extend({
   template: '<div>This is my first component!</div>'
  })
  
  <!-- 2.注册组件,并指定组件的标签,组件的HTML标签为<my-component> -->
  Vue.component('my-component', myComponent)
  
  <!-- 3.通过id=app进行挂载 -->
  new Vue({
   el: '#app'
  });
  
 </script>
</html>

    运行结果如下:

vue 注册组件的使用详解

   一、 全局注册和局部注册

       调用Vue.component()注册组件时,组件的注册是全局的,这意味着该组件可以在任意Vue示例下使用。
如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册。

 我自己的理解只要是component就代表全局组件,components代表局部组件

    上面的示例可以改为局部注册的方式:

<!DOCTYPE html>
<html>
 <body>
  <div id="app">
   <!-- 3. my-component只能在#app下使用-->
   <my-component></my-component>
  </div>
 </body>
 <script src="js/vue.js"></script>
 <script>
  // 1.创建一个组件构造器
  var myComponent = Vue.extend({
   template: '<div>This is my first component!</div>'
  })
  
  new Vue({
   el: '#app',
   components: {
   // 2. 将myComponent组件注册到Vue实例下
    'my-component' : myComponent
   }
  });
 </script>
</html>

       由于my-component组件是注册在#app元素对应的Vue实例下的,所以它不能在其它Vue实例下使用。

<div id="app2">
 <!-- 不能使用my-component组件,因为my-component是一个局部组件,它属于#app-->
 <my-component></my-component>
</div>

<script>
 new Vue({
  el: '#app2'
 });
</script>

 二、组件注册语法糖

    以上组件注册的方式有些繁琐,Vue.js为了简化这个过程,提供了注册语法糖

// 全局注册,my-component1是标签名称
Vue.component('my-component1',{
 template: '<div>This is the first component!</div>'
})
var vm1 = new Vue({
 el: '#app1'
})

       Vue.component()的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template属性定义组件模板。
使用这种方式,Vue在背后会自动地调用Vue.extend()。

   components实现局部注册

var vm2 = new Vue({
 el: '#app2',
 components: {
  // 局部注册,my-component2是标签名称
  'my-component2': {
   template: '<div>This is the second component!</div>'
  },
  // 局部注册,my-component3是标签名称
  'my-component3': {
   template: '<div>This is the third component!</div>'
  }
 }
}

三、父组件和子组件

 我们可以在组件中定义并使用其他组件,这就构成了父子组件的关系。

<!DOCTYPE html>
<html>
 <body>
  <div id="app">
   <parent-component>
   </parent-component>
  </div>
 </body>
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
 <script>
  
  var Child = Vue.extend({
   template: '<p>This is a child component!</p>'
  })
  
  var Parent = Vue.extend({
   // 在Parent组件内使用<child-component>标签
   template :'<p>This is a Parent component</p><child-component></child-component>',
   components: {
    // 局部注册Child组件,该组件只能在Parent组件内使用
    'child-component': Child
   }
  })
  
  // 全局注册Parent组件
  Vue.component('parent-component', Parent)
  
  new Vue({
   el: '#app'
  })
  
 </script>
</html>

 这段代码的运行结果如下

vue 注册组件的使用详解

四、使用script或template标签

       尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。
庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>vue组件</title>
 <script src="js/vue.js"></script>
</head>
<body>
 <div id="app1">
  <my-com></my-com>
  <my-com1></my-com1>
 </div>
 <template id="myCom">
  <div>这是template标签构建的组件</div>
 </template>
 <script type="text/x-template" id="myCom1">
  <div>这是script标签构建的组件</div>
 </script>
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
 <script>
  Vue.component('my-com1', {
   template: '#myCom1'
  });

  var app1 = new Vue({
   el: '#app1',
   components: {
    'my-com': {
     template: '#myCom'
    }
   }
  });
 </script>
</body>
</html>

 运行结果:

vue 注册组件的使用详解

注意:使用<script>标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>标签内定义的内容。

vue 注册组件的使用详解

      在理解了组件的创建和注册过程后,我建议使用<script>或<template>标签来定义组件的HTML模板。
这使得HTML代码和JavaScript代码是分离的,便于阅读和维护。

 五、模板的注意事项

     1. 以子标签的形式在父组件中使用

<div id="app">
 <parent-component>
  <child-component></child-component>
 </parent-component>
</div>

 上面是错误的。为什么这种方式无效呢?因为当子组件注册到父组件时,Vue.js会编译好父组件的模板,模板的内容已经决定了父组件将要渲染的HTML。

<parent-component>…</parent-component>相当于运行时,它的一些子标签只会被当作普通的HTML来执行,<child-component></child-component>不是标准的HTML标签,会被浏览器直接忽视掉

     2.组件的模板只能有一个根元素。下面的情况是不允许的。

template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>
            <button>hello</button>`

     3.组件中的data必须是函数

       注册组件时传入的配置和创建Vue实例差不多,但也有不同,其中一个就是data属性必须是一个函数。

这是因为如果像Vue实例那样,传入一个对象,由于JS中对象类型的变量实际上保存的是对象的引用,所以当存在多个这样的组件时,会共享数据,导致一个组件中数据的改变会引起其他组件数据的改变。

而使用一个返回对象的函数,每次使用组件都会创建一个新的对象,这样就不会出现共享数据的问题来了。

     4.关于DOM模板的解析

       当使用 DOM 作为模版时 (例如,将 el 选项挂载到一个已存在的元素上), 你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素 <ul>,<ol>,<table>,<select> 限制了能被它包裹的元素,而一些像 <option> 这样的元素只能出现在某些其它元素内部

   在自定义组件中使用这些受限制的元素时会导致一些问题,例如

<table>
 <my-row>...</my-row>
</table>

        自定义组件 <my-row> 被认为是无效的内容,因此在渲染的时候会导致错误。这时应使用特殊的 is 属性:

<table>
 <tr is="my-row"></tr>
</table>

       也就是说,标准HTML中,一些元素中只能放置特定的子元素,另一些元素只能存在于特定的父元素中。比如table中不能放置div,tr的父元素不能div等。所以,当使用自定义标签时,标签名还是那些标签的名字,但是可以在标签的is属性中填写自定义组件的名字。

 

三、动态组件

    有的时候,在不同组件之间进行动态切换是非常有用的,比如在一个多标签的界面里

    简单点说:就是几个组件放在一个挂载点下,然后根据父组件的某个变量来决定显示哪个,或者都不显示。

    要点:在挂载点使用component标签,然后使用v-bind:is=”组件名”,会自动去找匹配的组件名,如果没有,则不显示

动态组件,先看案例效果:

代码演示:css代码就不复制了,上面案例效果里有。

<script src="https://unpkg.com/vue"></script>
<div id="dynamic-component-demo" class="demo">
 <button v-for="tab in tabs" 
   v-bind:key="tab" 
   v-bind:class="['tab-button', { active: currentTab === tab }]" 
   v-on:click="currentTab = tab">{{ tab }}</button>
 <component v-bind:is="currentTabComponent" class="tab"></component>
</div>

     这里v-bind:key其实可有可无,具体key介绍可以看官网。

     这里v-bind:class和v-on:click都是用来为了改变样式用的。

    关键是component组件标签。

<script>
 //显示定义了三个组件
 Vue.component('tab-科长', {
  template: '<div>一共有100个科长</div>'
 })
 Vue.component('tab-处长', {
  template: '<div>一种有50个处长</div>'
 })
 Vue.component('tab-局长', {
  template: '<div>一共有10个局长</div>'
 })

 new Vue({
  el: '#dynamic-component-demo',
  data: {
   currentTab: '局长',
   tabs: ['科长', '处长', '局长']
  },
 //计算属性,根据currentTab的改变来判断选择哪个组件
  computed: {
   currentTabComponent: function() {
    return 'tab-' + this.currentTab
   }
  }
 })
</script>

总结

以上所述是小编给大家介绍的vue 注册组件的使用详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
jQuery 锚点跳转滚动条平滑滚动一句话代码
Apr 30 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
Jul 20 Javascript
javascript页面动态显示时间变化示例代码
Dec 18 Javascript
javascript生成随机颜色示例代码
May 05 Javascript
jquery实现树形菜单完整代码
Dec 29 Javascript
jQuery实现鼠标经过时高亮,同时其他同级元素变暗的效果
Sep 18 Javascript
js获取浏览器高度 窗口高度 元素尺寸 偏移属性的方法
Nov 21 Javascript
JavaScript实现图片切换效果
Aug 12 Javascript
微信小程序获取手机号授权用户登录功能
Nov 09 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
Nov 17 Javascript
JS图片预加载三种实现方法解析
May 08 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
Nov 13 Javascript
Vue三层嵌套路由的示例代码
May 05 #Javascript
动态加载JavaScript文件的3种方式
May 05 #Javascript
Node.js的Koa实现JWT用户认证方法
May 05 #Javascript
浅谈vue项目可以从哪些方面进行优化
May 05 #Javascript
Angular模版驱动表单的使用总结
May 05 #Javascript
浅谈Angular HttpClient简单入门
May 04 #Javascript
Vue项目全局配置微信分享思路详解
May 04 #Javascript
You might like
php 智能404跳转代码,适合换域名没改变目录的网站
2010/06/04 PHP
PHP分页效率终结版(推荐)
2013/07/01 PHP
php实现兼容2038年后Unix时间戳转换函数
2015/03/18 PHP
ThinkPHP中使用Ueditor富文本编辑器
2015/09/02 PHP
PHP开发APP端微信支付功能
2017/02/17 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
JSON 数据格式介绍
2012/01/13 Javascript
jquery选择器大全 全面详解jquery选择器
2014/03/06 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
2015/06/10 Javascript
JavaScript去除数组里重复值的方法
2015/07/13 Javascript
javascript中arguments,callee,caller详解
2016/03/16 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
JavaScript中自带的 reduce()方法使用示例详解
2016/08/10 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
详解React Native开源时间日期选择器组件(react-native-datetime)
2017/09/13 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
2017/10/26 Javascript
使用proxy实现一个更优雅的vue【推荐】
2018/06/19 Javascript
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
2019/07/10 Javascript
js中console在一行内打印字符串和对象的方法
2019/09/10 Javascript
[02:38]DOTA2亚洲邀请赛 IG战队巡礼
2015/02/03 DOTA
shelve  用来持久化任意的Python对象实例代码
2016/10/12 Python
Python实现Linux的find命令实例分享
2017/06/04 Python
基于循环神经网络(RNN)实现影评情感分类
2018/03/26 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
活动宣传策划方案
2014/05/23 职场文书
节水口号标语
2014/06/19 职场文书
电子工程求职信
2014/07/17 职场文书
船舶工程技术专业求职信
2014/08/07 职场文书
房产公证委托书范本
2014/09/20 职场文书
个人股份转让协议书范本
2014/10/26 职场文书
2014年学习委员工作总结
2014/11/14 职场文书
致运动员加油稿
2015/07/21 职场文书
详解thinkphp的Auth类认证
2021/05/28 PHP
详解Java实现数据结构之并查集
2021/06/23 Java/Android
Java spring单点登录系统
2021/09/04 Java/Android
spring 项目实现限流方法示例
2022/07/15 Java/Android