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 相关文章推荐
如何用JavaScript定义一个类
Sep 12 Javascript
EasyUI中combobox默认值注意事项
Mar 01 Javascript
javascript实现随机生成DIV背景色
Jun 20 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
Sep 21 Javascript
jquery submit()不能提交表单的解决方法
Apr 24 jQuery
vue页面跳转后返回原页面初始位置方法
Feb 11 Javascript
详解Vue中使用Echarts的两种方式
Jul 03 Javascript
微信小程序实现滑动切换自定义页码的方法分析
Dec 29 Javascript
Node.js之readline模块的使用详解
Mar 25 Javascript
微信小程序wxs实现吸顶效果
Jan 08 Javascript
让IDE识别webpack的别名alias的实现方法
May 06 Javascript
node运行js获得输出的三种方式示例详解
Jul 02 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
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
php中二维数组排序问题方法详解
2015/08/28 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
JavaScript 拖拉缩放效果
2008/12/10 Javascript
利用js获取服务器时间的两个简单方法
2010/01/08 Javascript
在javascript中对于DOM的加强
2013/04/11 Javascript
JS实现的自定义网页拖动类
2015/11/06 Javascript
JS实现兼容各种浏览器的高级拖动方法完整实例【测试可用】
2016/06/21 Javascript
AjaxUpLoad.js实现文件上传
2018/03/05 Javascript
JS实现前端页面的搜索功能
2018/06/12 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
详解vue2.0模拟后台json数据
2019/05/16 Javascript
vue限制输入框只能输入8位整数和2位小数的代码
2019/11/06 Javascript
vue实现图片懒加载的方法分析
2020/02/05 Javascript
用Python脚本生成Android SALT扰码的方法
2013/09/18 Python
使用python解析xml成对应的html示例分享
2014/04/02 Python
pycharm执行python时,填写参数的方法
2018/10/29 Python
Flask框架web开发之零基础入门
2018/12/10 Python
python接口自动化测试之接口数据依赖的实现方法
2019/04/26 Python
详解DeBug Python神级工具PySnooper
2019/07/03 Python
pyenv虚拟环境管理python多版本和软件库的方法
2019/12/26 Python
Python定义函数实现累计求和操作
2020/05/03 Python
python中@property的作用和getter setter的解释
2020/12/22 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
DJI美国:消费类无人机领域的领导者
2018/04/27 全球购物
lookfantastic荷兰:在线购买奢华护肤、护发和化妆品
2018/11/27 全球购物
读书心得体会
2013/12/28 职场文书
公司门卫岗位职责
2014/03/15 职场文书
品牌服务方案
2014/06/03 职场文书
男性健康日的活动方案
2014/08/18 职场文书
2014年党员自我评议对照检查材料
2014/09/20 职场文书
精神文明建设汇报材料
2014/12/24 职场文书
公司给客户的感谢信
2015/01/23 职场文书
考博导师推荐信范文
2015/03/27 职场文书
PyQt5 显示超清高分辨率图片的方法
2021/04/11 Python