vue基础3(组件,插槽)
1:组件的基本使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 组件注册 */ Vue.component('button-counter', { data: function(){ return { count: 0 } }, template: '<button @click="handle">点击了{{count}}次</button>', methods: { handle: function(){ this.count += 2; } } }) var vm = new Vue({ el: '#app', data: { } }); </script> </body> </html>
2:组件注册事项1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 组件注册注意事项 1、组件参数的data值必须是函数 2、组件模板必须是单个跟元素 3、组件模板的内容可以是模板字符串 */ // Vue.component('button-counter', { // data: function(){ // return { // count: 0 // } // }, // template: '<div><button @click="handle">点击了{{count}}次</button><button>测试</button></div>', // methods: { // handle: function(){ // this.count += 2; // } // } // }) // ----------------------------------- Vue.component('button-counter', { data: function(){ return { count: 0 } }, template: ` <div> <button @click="handle">点击了{{count}}次</button> <button>测试123</button> </div> `, methods: { handle: function(){ this.count += 2; } } }) var vm = new Vue({ el: '#app', data: { } }); </script> </body> </html>
3:组件注册事项2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <button-counter></button-counter> <hello-world></hello-world> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 组件注册注意事项 如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是 在普通的标签模板中,必须使用短横线的方式使用组件 */ Vue.component('HelloWorld', { data: function(){ return { msg: 'HelloWorld' } }, template: '<div>{{msg}}</div>' }); Vue.component('button-counter', { data: function(){ return { count: 0 } }, template: ` <div> <button @click="handle">点击了{{count}}次</button> <button>测试123</button> <HelloWorld></HelloWorld> </div> `, methods: { handle: function(){ this.count += 2; } } }) var vm = new Vue({ el: '#app', data: { } }); </script> </body> </html>
4:局部组件的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <hello-world></hello-world> <hello-tom></hello-tom> <hello-jerry></hello-jerry> <test-com></test-com> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 局部组件注册 局部组件只能在注册他的父组件中使用 */ Vue.component('test-com',{ template: '<div>Test<hello-world></hello-world></div>' }); var HelloWorld = { data: function(){ return { msg: 'HelloWorld' } }, template: '<div>{{msg}}</div>' }; var HelloTom = { data: function(){ return { msg: 'HelloTom' } }, template: '<div>{{msg}}</div>' }; var HelloJerry = { data: function(){ return { msg: 'HelloJerry' } }, template: '<div>{{msg}}</div>' }; var vm = new Vue({ el: '#app', data: { }, components: { 'hello-world': HelloWorld, 'hello-tom': HelloTom, 'hello-jerry': HelloJerry } }); </script> </body> </html>
5:父组件向子组件传值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div>{{pmsg}}</div> <menu-item title='来自父组件的值'></menu-item> <menu-item :title='ptitle' content='hello'></menu-item> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 父组件向子组件传值-基本使用 */ Vue.component('menu-item', { props: ['title', 'content'], data: function() { return { msg: '子组件本身的数据' } }, template: '<div>{{msg + "----" + title + "-----" + content}}</div>' }); var vm = new Vue({ el: '#app', data: { pmsg: '父组件中内容', ptitle: '动态绑定属性' } }); </script> </body> </html>
6:父组件向子组件传值-props的命名规则
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div>{{pmsg}}</div> <menu-item :menu-title='ptitle'></menu-item> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 父组件向子组件传值-props属性名规则 */ Vue.component('third-com', { props: ['testTile'], template: '<div>{{testTile}}</div>' }); Vue.component('menu-item', { props: ['menuTitle'], template: '<div>{{menuTitle}}<third-com testTile="hello"></third-com></div>' }); var vm = new Vue({ el: '#app', data: { pmsg: '父组件中内容', ptitle: '动态绑定属性' } }); </script> </body> </html>
7:父组件向子组件传值-props的属性类型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div>{{pmsg}}</div> <menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 父组件向子组件传值-props属性值类型 */ Vue.component('menu-item', { props: ['pstr','pnum','pboo','parr','pobj'], template: ` <div> <div>{{pstr}}</div> <div>{{12 + pnum}}</div> <div>{{typeof pboo}}</div> <ul> <li :key='index' v-for='(item,index) in parr'>{{item}}</li> </ul> <span>{{pobj.name}}</span> <span>{{pobj.age}}</span> </div> </div> ` }); var vm = new Vue({ el: '#app', data: { pmsg: '父组件中内容', pstr: 'hello', parr: ['apple','orange','banana'], pobj: { name: 'lisi', age: 12 } } }); </script> </body> </html>
8:子组件向父组件传值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div> <menu-item :parr='parr' @enlarge-text='handle'></menu-item> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 子组件向父组件传值-基本用法 props传递数据原则:单向数据流 */ Vue.component('menu-item', { props: ['parr'], template: ` <div> <ul> <li :key='index' v-for='(item,index) in parr'>{{item}}</li> </ul> <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button> </div> ` }); var vm = new Vue({ el: '#app', data: { pmsg: '父组件中内容', parr: ['apple','orange','banana'], fontSize: 10 }, methods: { handle: function(){ // 扩大字体大小 this.fontSize += 5; } } }); </script> </body> </html>
9:子组件向父组件传值 携带参数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div> <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 子组件向父组件传值-携带参数 */ Vue.component('menu-item', { props: ['parr'], template: ` <div> <ul> <li :key='index' v-for='(item,index) in parr'>{{item}}</li> </ul> <button @click='$emit("enlarge-text", 5)'>扩大父组件中字体大小</button> <button @click='$emit("enlarge-text", 10)'>扩大父组件中字体大小</button> </div> ` }); var vm = new Vue({ el: '#app', data: { pmsg: '父组件中内容', parr: ['apple','orange','banana'], fontSize: 10 }, methods: { handle: function(val){ // 扩大字体大小 this.fontSize += val; } } }); </script> </body> </html>
10:兄弟组件之间的数据交互
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div>父组件</div> <div> <button @click='handle'>销毁事件</button> </div> <test-tom></test-tom> <test-jerry></test-jerry> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 兄弟组件之间数据传递 */ // 提供事件中心 var hub = new Vue(); Vue.component('test-tom', { data: function(){ return { num: 0 } }, template: ` <div> <div>TOM:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods: { handle: function(){ hub.$emit('jerry-event', 2); } }, mounted: function() { // 监听事件 hub.$on('tom-event', (val) => { this.num += val; }); } }); Vue.component('test-jerry', { data: function(){ return { num: 0 } }, template: ` <div> <div>JERRY:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods: { handle: function(){ // 触发兄弟组件的事件 hub.$emit('tom-event', 1); } }, mounted: function() { // 监听事件 hub.$on('jerry-event', (val) => { this.num += val; }); } }); var vm = new Vue({ el: '#app', data: { }, methods: { handle: function(){ hub.$off('tom-event'); hub.$off('jerry-event'); } } }); </script> </body> </html>
11:插槽的基本用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <alert-box>有bug发生</alert-box> <alert-box>有一个警告</alert-box> <alert-box></alert-box> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 组件插槽:父组件向子组件传递内容 */ Vue.component('alert-box', { template: ` <div> <strong>ERROR:</strong> <slot>默认内容</slot> </div> ` }); var vm = new Vue({ el: '#app', data: { } }); </script> </body> </html>
12:具名插槽的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <base-layout> <p slot='header'>标题信息</p> <p>主要内容1</p> <p>主要内容2</p> <p slot='footer'>底部信息信息</p> </base-layout> <base-layout> <template slot='header'> <p>标题信息1</p> <p>标题信息2</p> </template> <p>主要内容1</p> <p>主要内容2</p> <template slot='footer'> <p>底部信息信息1</p> <p>底部信息信息2</p> </template> </base-layout> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 具名插槽 */ Vue.component('base-layout', { template: ` <div> <header> <slot name='header'></slot> </header> <main> <slot></slot> </main> <footer> <slot name='footer'></slot> </footer> </div> ` }); var vm = new Vue({ el: '#app', data: { } }); </script> </body> </html>
13:作用域插槽的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <style type="text/css"> .current { color: orange; } </style> <body> <div id="app"> <fruit-list :list='list'> <template slot-scope='slotProps'> <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong> <span v-else>{{slotProps.info.name}}</span> </template> </fruit-list> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 作用域插槽 */ Vue.component('fruit-list', { props: ['list'], template: ` <div> <li :key='item.id' v-for='item in list'> <slot :info='item'>{{item.name}}</slot> </li> </div> ` }); var vm = new Vue({ el: '#app', data: { list: [{ id: 1, name: 'apple' },{ id: 2, name: 'orange' },{ id: 3, name: 'banana' }] } }); </script> </body> </html>