正文
前言:转眼距离上篇 JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查) 已有好几个月了,今天打算将它捡起来,发现好久不用,Vue相关技术点都生疏不少。经过这几个月的时间,Vue的发展也是异常迅猛,不过这好像和博主都没什么太大的关系,博主还是老老实实研究自己的技术吧。技术之路还很长,且行且研究吧。
一、为什么组件很重要
前两天,看到一篇关于 汇总vue开源项目 的文章,资源非常丰富,不得不感叹开源社区的强大。随便点进去看了几个UI组件,基本都不是原生的html用法,如果你不懂Vue的组件相关概念,看到一些“稀奇古怪”的标签写法,可能会使用,但肯定无法理解为什么可以这么写。比如我们随便找了一个名叫IView的来看看:
<i-input type="text" :value.sync="formInline.user" placeholder="Username"> <Icon type="ios-person-outline" slot="prepend"></Icon> </i-input></div>
这样一段代码就能得到如下效果:
博主好奇心重,打算一探究竟,今天就和大家一起来看一看这些“古怪”写法的出处。希望通过本文,让你有一种“哦,原来是这样,不过如此嘛!”的感觉!
二、Vue里面的组件基础知识
1、组件的概念
官方定义:组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
博主理解:Vue里面的组件可以理解为通过对普通html标签的封装,得到一套独立而且可以通用的html标签,我们在页面里面使用这些标签传入相应的参数即可调用封装好的组件。通过下面这张图相信可以一目了然。
由普通的html标签form、input、button、label组成了一个新的元素集合,我们命名为i-form,这个i-form就是vue里面组件的概念。我们在页面里面使用<i-form></i-form>时,通过vue的组件渲染机制,在浏览器里面最终就可以显示成为普通的html标签form、input、button、label。
2、组件原理
通过上图我们知道,vue里面的组件实际上就是一些普通html元素的集合。那么,它是如何将这些自定义标签转换为普通html标签的呢?在介绍组件原理之前,还是先来看一个最简单的组件实例。
<div style="text-align:center;margin-top:200px;" id="app"> <!-- 3. 在Vue实例里面使用组件--> <b-component></b-component> </div> <script src="Content/vue/dist/vue.js"></script> <script type="text/javascript"> // 1.创建组件构造器 var myComponent = Vue.extend({ template: '<div id="bComponent">我是自定义组件的内容</div>' }); //2.注册组件到vue里面 Vue.component('b-component', myComponent) new Vue({ el: '#app', }); </script></div>
得到效果:
整个过程不难理解,主要分为三个大的步骤:
- 定义一个组件构造器,声明组件要渲染的html内容
- 将组件构造器注册到Vue的组件系统里面,使其成为Vue的一个组件,给组件取一个名称,比如b-component
- 在Vue的实例里面使用组件。因为上面两步定义了Vue的组件,既然是Vue的组件,那么要使用组件,首先得有一个Vue的实例,组件必须要在Vue的实例里面使用。
在网上找到一张图可以清晰地解释组件的整个渲染过程。
其实有时为了简便,我们常将1、2步合并,代码如下:
<div style="text-align:center;margin-top:200px;" id="app"> <!-- 2. 在Vue实例里面使用组件--> <b-component></b-component> </div> <script src="Content/vue/dist/vue.js"></script> <script type="text/javascript"> //1.创建组件构造器,注册组件到vue里面 Vue.component('b-component', { template: '<div id="bComponent">我是自定义组件的内容</div>' }) new Vue({ el: '#app', }); </script></div>
得到的结果和上述相同。
3、组件使用
上述解释了下组件的定义和原理,关于组件的简单实用,我们主要介绍以下几个方面。
(1)组件的作用域
这个应该不难理解,组件分为全局组件和局部组件,也就是说,你可以在页面上面定义一个全局组件,页面上面的任何Vue实例都可使用;而对于局部组件,是和具体的Vue实例相关的,只能在当前Vue实例里面使用组件。还有一点需要说明:组件必须在Vue的实例里面使用,在Vue实例之外使用组件无效。通过下面一个例子即可清晰说明它们的区别。
<body> <div style="text-align:center;margin-top:50px;" id="app"> <b-component></b-component> <b-component2></b-component2> </div> <div style="text-align:center;margin-top:50px;" id="app2"> <b-component></b-component> <b-component2></b-component2> </div> <b-component></b-component> <b-component2></b-component2> <script src="Content/vue/dist/vue.js"></script> <script type="text/javascript"> //定义组件 Vue.component('b-component', { template: '<div id="bComponent">我是全局组件,任何Vue实例都可使用</div>' }) new Vue({ el: '#app', components: { 'b-component2': { template: '<div id="bComponent">我是局部组件,只能在app这个div里面使用</div>' } } }); new Vue({ el: '#app2', }); </script> </body></div>
得到结果:
(2)组件的传值
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。这段话怎么理解呢?我们先来看几个例子。
静态Prop
我们先来看看下面的一段简单的代码
<body> <div style="text-align:center;margin-top:50px;" id="app"> <b-component componentmessage="你好"></b-component> </div> <script src="Content/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('b-component', { template: '<div>{{componentmessage}}</div>', props: ['componentmessage'], }) new Vue({ el: '#app' }); </script> </body></div>
通过在组件里面使用props属性,将外部的值传入组件模板。最终渲染到页面上面就得到“<div>你好</div>”这么一段html
动态Prop
在多数情况下,我们在使用Vue实例的时候,一般通过data属性传入模型,比如
new Vue({ el: '#app', data: { name: 'Jim', Age: '28' } });</div>
这个时候,我们的name和age如何传到组件实例里面呢?
<body> <div style="text-align:center;margin-top:50px;" id="app"> <b-component v-bind:my-name="name" v-bind:my-age="Age"></b-component> </div> <script src="Content/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('b-component', { template: '&l