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 相关文章推荐
Web开发之JavaScript
Mar 29 Javascript
jQuery(非HTML5)可编辑表格实现代码
Dec 11 Javascript
解析瀑布流布局:JS+绝对定位的实现
May 08 Javascript
详解JavaScript的策略模式编程
Jun 24 Javascript
jQuery动态星级评分效果实现方法
Aug 06 Javascript
jQuery三级下拉列表导航菜单代码分享
Apr 15 Javascript
Vue.js快速入门实例教程
Oct 15 Javascript
js 实现省市区三级联动菜单效果
Feb 20 Javascript
微信小程序getPhoneNumber获取用户手机号
Sep 29 Javascript
使用store来优化React组件的方法
Oct 23 Javascript
vue通过数据过滤实现表格合并
Nov 30 Javascript
extjs图形绘制之饼图实现方法分析
Mar 06 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连接mysql数据库代码
2009/03/10 PHP
mayfish 数据入库验证代码
2010/04/30 PHP
PHP上传文件时自动分配路径的方法
2015/01/09 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
Javascript中Eval函数的使用说明
2008/10/11 Javascript
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
js形成页面的一种遮罩效果实例代码
2014/01/04 Javascript
js实现带圆角的两级导航菜单效果代码
2015/08/24 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
jQuery链式调用与show知识浅析
2016/05/11 Javascript
Node.js检测端口(port)是否被占用的简单示例
2016/09/29 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
Vuex之理解Getters的用法实例
2017/04/19 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
vue项目上传Github预览的实现示例
2018/11/06 Javascript
node+express框架中连接使用mysql(经验总结)
2018/11/10 Javascript
浅谈layui分页控件field参数接收对象的问题
2019/09/20 Javascript
ES6中Set和Map用法实例详解
2020/03/02 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
python实现代理服务功能实例
2013/11/15 Python
详解tensorflow载入数据的三种方式
2018/04/24 Python
python数字图像处理实现直方图与均衡化
2018/05/04 Python
python 读取串口数据的示例
2020/11/09 Python
Myprotein加拿大官网:欧洲第一的运动营养品牌
2018/01/06 全球购物
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
PHP解析URL是哪个函数?怎么用?
2013/05/09 面试题
计算机网络专业个人的自我评价
2013/10/17 职场文书
骨干教师培训制度
2014/01/13 职场文书
环境工程专业自荐信范文
2014/03/18 职场文书
师德师风个人自我剖析材料
2014/09/27 职场文书
司考复习计划
2015/01/19 职场文书
2016校本研修培训心得体会
2016/01/08 职场文书
Python pygame实现中国象棋单机版源码
2021/06/20 Python
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis