Vue组件
组件 (Component) 是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。是可复用的Vue实例。
组件的注册
// html 代码 <div id="app"> <my-component></my-component> </div> // js 代码 Vue.component('my-component', { template: '<div>A component!</div>' }) var app = new Vue({ el: '#app', data: { } });
// html 代码 <div id="app"> <my-component></my-component> </div> // js 代码 // 组件中的data必须是个函数 var Child = { template: '<div>A component!</div>', data: function() { return { name: "gao", } }}; new Vue({ // ... components: { // <my-component> 将只在父组件模板中可用 'my-component': Child } })
// js 代码 Vue.component('child', { template: `<div><button @click="on_click()">{{msg}}</button></div>`, data: function () { return { msg: "点我", } }, methods: { on_click(){ alert(123) } } }); new Vue({ el: "#app", })
<script> var my_component = { template: `<div><h1>{{msg}}</h1></div>`, data(){ return{ msg: "这是子组件" } } }; var global_component = { template: `<div> <h1>{{msg}}</h1> <button @click="on_click">点我</button> <my_component></my_component> </div>`, data(){ return { msg: "全局组件" } }, methods: { on_click() { alert("123") } }, components:{ my_component:my_component, } }; const app = new Vue({ el: "#app", data: { }, components: { global_component: global_component, // my_component: my_component, } }); </script>
组件之间的通信
我们的组件在任何地方用的时候都要是一个样子么~
可不可以我们给组件传个参数~让组件在不同的地方表现不同的状态~
我们之前说过博客评论@某某某,点击用户名可以跳转到该用户站点。
// html 代码 <div id="app"> <child username="gaoxin"></child> </div> // js 代码 Vue.component('child', { template: `<a :href="'/user/'+ username">{{username}}</a>`, props: ["username"], }); var app = new Vue({ el: "#app", data:{ name: "@gaoxin" } });
app.$on(event, callback) 监听当前实例上的自定义事件,事件由$emit触发,回调函数接收事件触发器额外参数。
app.$emit(event, [args....]) 触发当前实例上的事件,额外参数传给监听器的callback回调函数。
// html 代码 <div id="app"> <parent></parent> </div> // js 代码 Vue.component('parent',{ template: ` <div> <child @show_balance="show"></child> <p v-if="active">您的余额998</p> </div> `, data: function () { return { active: false, } }, methods: { show: function(data){ this.active=true; console.log(data) } } }); Vue.component('child', { template: `<div><button @click="on_click()">{{msg}}</button></div>`, data: function () { return { msg: "显示余额", } }, methods: { on_click(){ // alert(123) this.$emit('show_balance', {q:1,b:2}) } } });
平行组件之间的通信,喊话需要一个中间调度器,在组件加载完成之后去监听调度器事件,回调函数接收数据。
// html 代码 <div id="app"> <whh></whh> <shh></shh> </div> // js 代码 var Event = new Vue() Vue.component('whh',{ template: ` <div> 我说: <input @keyup="on_change" v-model="i_said"> </div> `, data: function () { return { i_said: '', } }, methods: { on_change: function () { Event.$emit("whh_said_something", this.i_said) } } }); Vue.component('shh', { template: ` <div> 花花说:{{whh_said}} </div> `, data: function () { return { whh_said: '', } }, mounted: function () { var me = this Event.$on('whh_said_something', function (data) { me.whh_said = data }) } });
混合Mixins
重复功能和数据的储存器,可以覆盖Mixins的内容。
// 点击显示和隐藏 提示框的显示和隐藏 // html 代码 <div id="app"> <PopUp></PopUp> <ToolTip></ToolTip> </div> // js 代码 var base = { data: function () { return { visible: false, } }, methods: { show: function () { this.visible = true }, hide: function () { this.visible = false } } } Vue.component('popup', { template:` <div> <button @click="show">PopUp show</button> <button @click="hide">PopUp hide</button> <div v-if="visible"><p>hello everybody</p></div> </div> `, mixins: [base], data: function () { return { visible: true, } } }); Vue.component('tooltip', { template: ` <div> <div @mouseenter="show" @mouseleave="hide">ToolTip</div> <div v-if="visible"><p>ToolTip</p></div> </div> `, mixins: [base] }); new Vue({ el: "#app", })
插槽 Slot
插槽是一套内容分发的API,在组件中,<slot>作为内容承载分发的出口
// html 代码 <div id="app"> <panel> <div slot="title"> HELLO</div> <div slot="content">hello</div> </panel> <panel></panel> <panel></panel> </div> <template id="panel-tpl"> <div class="panel"> <div class="title"> <slot name="title"></slot> </div> <div class="content"> <slot name="content"></slot> </div> <!--<div class="content">Failure is probably the fortification in your pole. It is like a peek your wallet as the thief, when you are thinking how to spend several hard-won lepta,</div>--> <div class="footer"> <slot name="footer">更多信息</slot> </div> </div> </template> // js 代码 Vue.component('panel', { template: '#panel-tpl', }); new Vue({ el: "#app", })