1.解决非父子组件之间的传值问题
非父子组件传值(Bus/总线/发布订阅模式/观察者模式)
给 Vue类上挂在一个属性,然后创建vue实例时,实例就拥有了这个属性
Vue.prototype.bus = new Vue();
//发送
this.bus.$emit('change',this.selfContent);
//监听
this.bus.$on('change',function (value) {
this_.selfContent = value;
});
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>非父子组件传值(Bus/总线/发布订阅模式/观察者模式)</title> </head> <body> <script src="../../vue.js"></script> <div id="app"> <child content="dong"></child> <child content="hao"></child> </div> <script> Vue.prototype.bus = new Vue(); Vue.component('child',{ data:function(){ return { selfContent:this.content } }, props:{ content:String, }, template:'<div @click="HandleClick">{{selfContent}}</div>', methods:{ HandleClick:function () { this.bus.$emit('change',this.selfContent); } }, // #组件被挂载时候执行 mounted:function () { var this_ = this this.bus.$on('change',function (value) { this_.selfContent = value; }); } }); var vm = new Vue({ el:"#app" }) </script> </body> </html>
2. 插槽
使用:
<child> <!--定义插槽--> <p>dell</p> <p>dell</p> <p>dell</p> </child>
//slot标签使用插槽
Vue.component('child',{ props:['content'], template:`<div> <p>hello</p> <slot></slot> </div>` })
默认插槽:
<default></default> Vue.component('default',{ template:`<div> <slot>我是默认值</slot> </div>` })
具名插槽:
<body-content> <!--具名插槽--> <div class="header" slot="header">header</div> <div class="footer" slot="footer">footer</div> </body-content> // #header-footer // 当不传时,使用默认值 Vue.component("body-content",{ template:`<div> <slot name="header"></slot> <div class="content">content</div> <slot name="footer"></slot> <slot name="default-header"> <h1>默认header</h1> </slot> </div>` })
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用插槽(slot)</title> <script src="../../vue.js"></script> </head> <div id="app"> <child> <!--插槽--> <p>dell</p> <p>dell</p> <p>dell</p> </child> <!--#默认值--> <default></default> <!--// #header-footer--> <body-content> <!--具名插槽--> <div class="header" slot="header">header</div> <div class="footer" slot="footer">footer</div> </body-content> </div> <script> Vue.component('child',{ props:['content'], template:`<div> <p>hello</p> <slot></slot> </div>` }) Vue.component('default',{ template:`<div> <slot>我是默认值</slot> </div>` }) // #header-footer // 当不传时,使用默认值 Vue.component("body-content",{ template:`<div> <slot name="header"></slot> <div class="content">content</div> <slot name="footer"></slot> <slot name="default-header"> <h1>默认header</h1> </slot> </div>` }) var vm =new Vue({ el:"#app" }) </script> <body> </body> </html>
3. 作用域插槽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>作用域插槽</title> <script src="../../vue.js"></script> </head> <body> <div id="app"> <child> <!--作用域插槽 template--> <template slot-scope="props"> <h1>{{props.item}}</h1> </template> </child> <!--dom结构由外部传递--> <!--使用template标签,并且用slot-scope接收--> </div> <script> Vue.component('child',{ data:function(){ return { list:[1,2,3,4,5,6] } }, // :item="item"子组件向父组件中传递数据 template:`<div> <ul> <slot v-for="item in list" :item="item"> </slot> </ul> </div>` }) var vm = new Vue({ el:"#app" }) </script> </body> </html>
4.动态组件和v-once指令
使用component标签 动态显示组件
<component :is="type"></component>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>动态组件和v-once指令</title> <script src="../../vue.js"></script> </head> <body> <div id="app"> <!--<child-one v-if="type==='child-one'"></child-one>--> <!--<child-two v-if="type==='child-two'"></child-two>--> <component :is="type"></component> <!--耗费性能,重复销毁 创建--> <!--v-once直接放到内存里--> <button @click="handleBtnclick">click me</button> </div> <script> Vue.component('child-one',{ template:`<div v-once>this is child one</div>` }) Vue.component('child-two',{ template:`<div v-once>this is child two</div>` }) var vm = new Vue({ el:"#app", data:{ type:'child-one' }, methods:{ handleBtnclick:function () { this.type = this.type==='child-one'?'child-two':'child-one' } } }) </script> </body> </html>