在前面vue的一些博客中,咱们几乎将vue的基础差很少学习完了,而从本篇博客开始将会进入到vue的另外一个阶段性学习,本篇博客的内容在之后的vue项目中占很大的比重,因此小伙伴们须要认真学习,本篇博客的内容也比较简单,看过我博客的人都知道我所写的每一篇博客都是很是的详细的,因此你们不要担忧学不会。我会尽可能将所学的知识讲解的通俗易懂,让你们学习起来更加快乐,那么一块儿来看看吧!javascript
解释:组件系统是 Vue 的另外一个重要概念,由于它是一种抽象,容许咱们使用小型、独立和一般可复用的组件构建大型应用。仔细想一想,几乎任意类型的应用界面均可以抽象为一个组件树css
组件一般能够用来制做单页应用程序(SPA)html
组件的话咱们主要分为两类,一种是局部组件,一种是全局组件,接下来我会介绍这两种组件vue
全局组件毫无疑问,确定是不少地方均可以访问的了,html5
Vue.component('组件名',{
template:'模板'
})java
这是最简单定义全局组件的语法,接下来带你们简单入门一下全局组件数组
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>全局组件注册方式一</title> </head> <body> <div id="app"> <t1></t1> </div> <div id="demo"> <t1></t1> </div> <script type="text/template" id="template1"> <div>这是一个组件</div> </script> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('t1',{ template:'#template1' }) let vm=new Vue({ el:'#app' }) let d=new Vue({ el:'#demo' }) </script> </body> </html>
首先咱们使用script标签来定义模板而后将模板在组件中注册,在这里咱们定义了两个vue实例,发如今demo和app中均可以使用,证实全局组件注册成功了,这是定义组件的第一种方法,接下来咱们学习第二种app
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <temp></temp> </div> <template id="template1"> <div>这是一个组件</div> </template> <div id="demo"> <temp></temp> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('temp',{ template:'#template1' }) let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ } }) let app=new Vue({ el:'#demo' }) </script> </body> </html>
第二种方法咱们直接使用vue提供的template标签订义模板而后再组件中注册就能够了,dom
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <my-compent></my-compent> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('myCompent',{ template:'<div>这是第三种定义组件的方法</div>' }) let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ } }) </script> </body> </html>
这是第三种定义全局组件的方法,三种方法中均可以使用,主要看我的习惯,反正我是比较喜欢第三种,全局组件注册讲到这里就结束了,接下来主要讲解局部组件祖册。布局
局部组件的话固然是定义在vue实例里面定义的了,局部组件只在当前vue实例中有效
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>局部组件注册</title> </head> <body> <div id="app"> <hello></hello> <!--<hi></hi>--> </div> <div id="demo"> <hi></hi> <!--<hello></hello>--> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm1=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ 'hello':{ template:'<div>我叫hello,你叫什么</div>' } } }) let vm2=new Vue({ el:'#demo', components:{ 'hi':{ template:'<div>我叫hi,你叫什么</div>' } } }) </script> </body> </html>
结果的话我就不贴出来了,你们能够尝试一下,若是咱们在app中使用hi组件或者在demo中使用hello组件的话,vue将会给出警告的,由于咱们注册的是局部组件,因此没法使用。
在介绍ref引用以前,我想带你们实现一个小demo,需求是这样的,页面上共有四个按钮分别为红,黄,绿,蓝,当咱们点击某个按钮的时候就显示对应的颜色,以下图所示
当咱们点击红色的时候,显示红色,依次类推,那就由我带你们实现这个小demo吧!固然仍是应用组件的知识,毕竟趁热打铁
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}">{{color}}</button> <div class="box"></div> </div>`, } } }) </script> </body> </html>
效果
在这里咱们定义了局部组件,而后在局部组件中返回了颜色对应的数组,渲染的时候将颜色渲染到对应的按钮上,而且为每一个按钮绑定对应的背景颜色。
接下来咱们为每个按钮添加事件,而后点击的时候获取对应的颜色,咱们在事件中传入对应的颜色值名称就能够
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick(color)">{{color}}</button> <div class="box"></div> </div>`, methods:{ handleClick(color){ console.log(color); } } } } }) </script> </body> </html>
结果
当咱们依次点击对应的按钮的时候,对应颜色的值已经取到了,固然咱们如今已经实现这个功能了,可是为了巩固一下之前的知识,我也会教你们使用另外一种方法来获取就是下文提到的dataset的使用。
在html5中新增了data-xx的属性,咱们知道data-xx能够用来存数据因此咱们也能够将对应的颜色保存在data-xx中,而后经过dataset获取
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick" :data-color="color">{{color}}</button> <div class="box"></div> </div>`, methods:{ handleClick(e){ const color=e.target.dataset.color; console.log(color); } } } } }) </script> </body> </html>
使用这种方法也能够实现依次点击,获取对应颜色的值,结果的话和上面的结果同样,在这里我就不截图了
获取到对应的颜色以后咱们就要实现如上的效果,如今就必须用到ref的引用了
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick(color)" :data-color="color">{{color}}</button> <div class="box" ref="squareBox"></div> </div>`, methods:{ handleClick(color){ const box=this.$refs.squareBox; box.style.backgroundColor=color; } } } } }) </script> </body> </html>
效果
效果的话咱们已经实现了,可是咱们仍是不知道什么是ref,别着急,且听我一一道来
咱们知道javascript操做dom是很是消耗性能的,所以在vue中提供了ref来获取相应的dom元素获取方法是this.$refs获取的是全部含有ref引用的dom元素,主要分为四种,以下实例。
单独绑定的话,主要就是获取相应的dom元素,就像原生的javascript获取元素同样或者是jQuery中的$获取元素同样,看下实例就知道了,
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref单独绑定</title> </head> <body> <div id="app"> <div ref="square_box" class="box"></div> <button @click="handleClick">获取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ var dom=document.getElementsByClassName('box')[0]; console.log(this.$refs.square_box); console.log(dom); } }, computed:{ } }) </script> </body> </html>
在这个实例中,咱们使用了两种方法来获取dom元素,一种是使用ref来获取,另外一种使用原生的javascript来获取,能够看到两种方法都获取到了dom元素
结果:
在javascript中,咱们获取相同的节点是经过document.getElementsByClassName('节点名称')或者document.getElementByName('节点名称'),可是jQuery中使用$来获取的,返回的是一个数组,可是ref绑定多个相同的元素以后,后面绑定的会覆盖前面绑定的,这就是ref绑定元素神奇的一方面。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref绑定重复的元素</title> </head> <body> <div id="app"> <div class="box" ref="v_box"></div> <div class="box" ref="v_box"></div> <button @click="hanldeClick">获取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ hanldeClick(){ var doms=document.getElementsByClassName('box'); console.log(doms); console.log(this.$refs.v_box); } }, computed:{ } }) </script> </body> </html>
在这个示例中,咱们一样使用上面的两种方法来获取元素,这样一对比结果就出来了,使用ref获取的元素只用一个,就是最后面写的会覆盖前面写的,总之不管有多个重复的元素使用ref老是会返回最后一个结果。
结果:
若是在实际项目中真的有这个需求,须要绑定多个相同的元素呢?很简单使用v-for就能够了。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>v-for中ref实现的效果</title> </head> <body> <div id="app"> <template v-for="index of 10"> <div class="box" ref="f_box"></div> </template> <button @click="handleClick">获取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ console.log(this.$refs.f_box); let doms=document.getElementsByClassName('box'); console.log(doms); } }, computed:{ } }) </script> </body> </html>
一样仍是使用两种方法来获取节点,如今的话,咱们发现使用ref在v-for循环中获取的dom元素是一个数组(集合),原生的javascript仍是没有变和以前的同样
ref强大之处不只仅表如今前三个方面,它还能够绑定组件呢?绑定组件返回的是组件实例(组件的应用是组件的实例对象),这个也能够说是还有一点用处,这也是ref最后须要介绍的一项。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref绑定组件</title> </head> <body> <div id="app"> <hello ref="hello"></hello> <button @click="handleClick">获取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ console.log(this.$refs.hello); } }, computed:{ }, components:{ 'hello':{ 'template':'<div>你好</div>', } } }) </script> </body> </html>
结果:
能够看到ref绑定组件返回组件实例,ref的使用到这里我就已经讲解完了,整体来讲ref仍是比较简单的
本篇博客咱们主要学习了两个知识点,一个是认识组件(全局组件注册和局部组件注册),第二个是$ref的引用,知识点也比较简单,我讲解的也比较全面,下一篇博客我会带你们详细介绍组件的使用。