vue组件
01.组件component.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app"> <Hehe></Hehe> <Hehe></Hehe> <Hehe></Hehe> </div> <script> //组件的创建 let xixi = Vue.extend({template:'<h1>这里是组件</h1>'}); //注册一个组件 Vue.component('组件的名字',创建的组件) Vue.component('Hehe',xixi); //把组件名当成一个标签名来使用 组件名不能和标签名一致 let vm = new Vue({ el:'#app' }) </script> <!-- 1.组件继承自实例 实例有的组件也有,会有一些变异 2.组件的目的是为了实现复用 --> </body> </html>
02.全局组件.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> {{name}} <xixi></xixi> </div> <hr> <div id="app2"> {{name}} <xixi></xixi> </div> <script> // let component = Vue.extend({template:'<h1>呵呵</h1>'}) // let component = Vue.extend({template:'<h1>呵呵</h1>'}) // Vue.component('xixi',component) //全局组件创建的简写 参数1 组件名 参数2 组件的配置项 Vue.component ('xixi',{template:'<h1>呵呵</h1>'}) let vm = new Vue({ el:'#app1', data:{ name:'实例1' }, methods:{ } }) let vm1 = new Vue({ el:'#app2', data:{ name:'实例2' }, methods:{ } }) /* 通过Vue.component 注册的组件叫全局组件 全局组件在所有的实例里都可以用 全局组件的注册要求写在实例的前方 */ </script> </body> </html>
03.局部组件.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> {{name}} <xixi></xixi> <h1h1></h1h1> </div> <hr> <div id="app2"> {{name}} </div> <script> //创建局部组件 let component = Vue.extend({ template:'<h1>这里是局部组件</h1>' }) let vm = new Vue({ el:'#app1', data:{ name:'实例1' }, methods:{ }, components:{ 'xixi':component, 'h1h1':{template:'<h1>这里是局部组件2</h1>'} } }) let vm1 = new Vue({ el:'#app2', data:{ name:'实例2' }, methods:{ } }) /* 局部组件和全局组件的创建方式是一致的 注册方式不一样 局部组件在哪注册在哪用 局部组件注册在 实例里的配置项 components里 */ </script> </body> </html>
04.组件的配置项-template
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> <hehe></hehe> </div> <!-- 组件模板 --> <!-- 最外层的template不会渲染到真实dom上 --> <template id="tp1"> <div class="tp1"> <p v-for='item in 10'>{{item}}</p> </div> </template> <script> // Vue.component('hehe',{ // template:'<h1>hehe</h1>' // }) Vue.component('hehe',{ template:'#tp1' }) let vm2 = new Vue({ el:'#app1', data:{ name:'实例2' } }) // 组件配置项template 和实例里的 el 类似 关联dom元素 //1.dom结构简单 直接使用字符串 //2.dom复杂 template标签 该标签不会真正的渲染 只允许有一个根元素 </script> </body> </html>
05.组件的配置项-data
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> {{name}} <hr> <hehe></hehe> </div> <!-- 组件模板 --> <template id="tp1"> <div> 这里是模板 {{name}} </div> </template> <script> let vm1 = new Vue({ el:'#app1', data:{ name:'这里是实例' }, components:{ hehe:{ template:'#tp1', data(){ return {name:'hmm'} } } } }) // 组件正常情况下无法直接使用实例的数据 只能使用自己的数据 // 实例里的data 是一个对象 //组件里的data是一个函数,返回一个对象,返回的对象就是我们的数据 //为了保证每一个组件有单独的作用域 </script> </body> </html>
06.组件的配置项-methods
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> 这里是实例 <hehe></hehe> <hr> </div> <!-- 组件模板 --> <template id="tp1"> <div> 这里是组件 num:{{num}} <button @click = 'add'>add</button> </div> </template> <script> let vm1 = new Vue({ el:'#app1', data:{ name:'这里是实例' }, components:{ hehe:{ template:'#tp1', data(){ return {num:1} }, methods:{ add(){ //组件里的this指向组件对象 this.num++; } } } } }) </script> </body> </html>
07.组件的配置项-其他配置项
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> 这里是实例 <hehe></hehe> <hr> </div> <!-- 组件模板 --> <template id="hehe"> <div class="hehe"> 这里是hehe组件 <xixi></xixi> </div> </template> <!-- hehe里的xixi组件 --> <template id="xixi"> <div class="xixi"> 这里是嘻嘻组件 </div> </template> <script> let vm1 = new Vue({ el:'#app1', data:{ name:'这里是实例' }, components:{ hehe:{ template:'#hehe', components:{ xixi:{ template:'#xixi' } } } } }) </script> <!-- 组件继承自实例 实例有的组件都有 部分会发生改变 template el data el template data methods directives components 组件里也有components 也可以注册组件 形成了组件嵌套 watch computed 不管嵌套多少级 在哪注册在哪用 --> </body> </html>
08.全局组件的嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> <fa></fa> </div> <!-- 父组件 --> <template id="fa"> <div> 这里是父组件 <son></son> </div> </template> <!-- 子组件 --> <template id="son"> <div> 这里是子组件 </div> </template> <script> Vue.component('fa',{template:'#fa'}) Vue.component('son',{template:'#son'}) let vm1 = new Vue({ el:'#app1' }) /* 全局组件的嵌套 全局组件没有固定的嵌套关系,嵌套关系由书写方式决定的 */ </script> </body> </html>
09.局部组件的嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> <!-- <tp1></tp1> <tp2></tp2> --> <tp1> </tp1> </div> <!-- 组件1 --> <template id="tp1"> <div> 这里是组件1 <tp2></tp2> </div> </template> <!-- 组件2 --> <template id="tp2"> <div> 这里是组件2 </div> </template> <script> let vm1 = new Vue({ el: '#app1', components: { tp1: { template: '#tp1', components:{ tp2:{ template:'#tp2', } } }, // tp2: { // template: '#tp2' // } } }) // 局部组件在注册的过程中 已经确定了嵌套关系 //使用的过程中必须要找这种嵌套关系来使用 </script> </body> </html>
10.组件通信_父子通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <style> .test{ width: 100px; height: 100px; background: red; } </style> <body> <div id="app1"> <baba></baba> </div> <!-- 这里是父组件 --> <template id="baba"> <div class="baba"> <!-- 在父组件里嵌套子组件 --> <button>父组件的按钮</button> <hr> <!-- 自定义属性123 --> <son :hehe='name' xixi='hello'></son> </div> </template> <!-- 这里是子组件 --> <template id="son"> <div class="son"> <div class="test" v-show='show'> 子组件的div <hr> {{hehe}} {{xixi}} </div> </div> </template> <script> Vue.component('baba',{ template:'#baba', data(){ return { name:'han' } } }) Vue.component('son',{ template:'#son', props:['hehe','xixi'],//用来接收自定义属性 data(){ return { show:true } } }) let vm1 = new Vue({ el:'#app1', }) /* 写2个组件是一个嵌套关系 父组件有一个按钮 子组件有一个div 父组件的按钮控制子组件div的显示隐藏 props 自定义属性 */ </script> </body> </html>
11.组件通信_父子通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <style> #app1{ width: 200px; height: 200px; background: red; } .tp1{ width: 100px; height: 100px; background: blue; } </style> <body> <div id="app1" > 这里是实例 {{money1}} <hr> <!--在tp1组件标签上使用 xixi自定义属性 --> <tp1 :xixi='money1'></tp1> </div> <!-- 组件模板 --> <template id="tp1"> <div class="tp1"> 这里是组件 {{xixi}} </div> </template> <script> Vue.component('tp1',{ template:'#tp1', data(){ return { hehe:123 } }, // props:['xixi']//接收自定义属性 props:{ xixi:{type:String}//传值的同时检查数据的类型 } }) let vm1 = new Vue({ el:'#app1', data:{ money1:'shiyi' } }) </script> <!-- 不管是组件还是实例,自己的数据只能自己使用 --> <!-- props 将父亲的数据传给儿子 --> <!-- 1.在组件标签上使用自定属性 2.在组件内部通过props来接受自定义属性 3.接收完了 既可以在组件里直接使用 只能用不能改 --> </body> </html>
12.propsdemo父子通信的例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <style> .test{ width: 100px; height: 100px; background:red; } </style> <body> <div id="app1"> <button @click='toggle'>显示隐藏</button> {{show}} <son :hehe='show'></son> </div> <!-- 子元素 --> <template id="tp1"> <div> hehe:{{hehe}} <div class="test" v-show='hehe'> </div> </div> </template> <script> Vue.component('son',{ template:'#tp1', props:['hehe'] }) let vm1 = new Vue({ el:'#app1', data:{ show:true }, methods:{ toggle(){ this.show =!this.show; } } }) /* 写2个组件时一个嵌套关系 父组件有一个按钮 子组件有一个div 父组件的按钮控制自己 子组件div的显示隐藏 */ </script> </body> </html>
13.emit组件通信_子父通信emit
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> 这里是实例 <hr> <!-- 绑定在子组件上的自定义事件 事件名叫custom 处理函数叫add--> <son @custom1='add'></son> <!-- 绑定在button身上的内置事件 事件名叫click 处理函数叫add --> <!-- <button @click='add'>添加</button> --> </div> <!-- 组件模板 --> <template id='tp1'> <div> 这里是子组件 <button @click='sonClick'>这里是子组件的按钮</button> </div> </template> <script> Vue.component('son',{ template:'#tp1', methods:{ sonClick(){ console.log('子组件的处理方法'); //通过emit方法触发自定义事件 参数1 自定义事件名 this.$emit('custom1',666) } } }) let vm1 = new Vue({ el:'#app1', methods:{ add(num){ alert('点到我了'+num); } } }) /* 自定义事件 emit 可以触发绑定在组件身上的自定义事件 1.在组件标签上绑定一个自定义事件 <son @custom='add'></son> 2.在组件的内部 通过emit 触发这个事件 在子组件里触发父组件的方法!!! */ </script> </body> </html>
14.emitdemo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <body> <div id="app1"> 这里是爸爸 爸爸的钱包余额{{money}} <hr> <!-- 在组件上注册父组件的方法 --> <son @xixi='fatherBuyCry'></son> </div> <!-- 组件模板 --> <template id='son'> <div> 儿子看到玩具了 <button @click='buy'>buybuybuy</button> </div> </template> <script> Vue.component('son',{ template:'#son', methods:{ buy(){ console.log('我想买玩具'); this.$emit('xixi',3) } } }) let vm1 = new Vue({ el:'#app1', data:{ money:20 }, methods:{ fatherBuyCry(num){ //爸爸花钱的方法 this.money = this.money-num; alert('crycry') } } }) </script> <!-- 组件通信 在组建和实例中自己的数据只有自己可以控制 1.父子通信 props 父组件控制子组件 父组件控制自己的数据变化,将变化后的数据通过props自定义属性传给子组件 2.子父通信 $emit 子组件控制父组件的数据 父组件控制自己的数据变化,将控制函数通过emit自定义事件传递子组件 供子组件调用 3.兄弟通信 a.状态提升 b.事件总线 c.全局状态管理 --> </body> </html>
15.兄弟通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js"></script> </head> <style> .test{ width: 100px; height: 100px; background: red; } </style> <body> <div id="app1"> <!-- 将父亲的数据通过自定义属性传给组件1使用 --> <son1 :show='state'></son1> <hr> <!-- 将父亲的方法通过自定义事件传给组件2使用 --> <son2 @custom='faToggle'></son2> </div> <hr> <!-- 组件1 --> <template id="son1"> <div> 这里是组件1 <div class="test" v-show='show'></div> </div> </template> <!-- 组件2 --> <template id="son2"> <div> 这里是组件2 <button @click='son2Click'>显示隐藏</button> </div> </template> <script> /* 组件1 和 组件2 是兄弟 组件1有div 可以显示隐藏 组件2有button 控制显示隐藏 控制显示隐藏的值放在公有的爸爸上 */ Vue.component('son1',{ template:'#son1', props:['show']//接收爸爸传来的数据 }) Vue.component('son2',{ template:'#son2', methods:{ son2Click(){ this.$emit('custom')//触发爸爸传来的函数 } } }) let vm1 = new Vue({ el:'#app1', data:{ state:false }, methods:{ faToggle(){ this.state = !this.state; } } }) </script> </body> </html>