Vue的核心基础就是组件的使用,组件的使用使我们的项目更好的解耦,更加符合vue的设计思想MVVM。
Vue组件的结构(创建):
// 创建组件 (组件中的属性和下边Vue中的属性名称是相同的,比如data,methods,computed等,但是类型不一样) Vue.component("Vheader", { // Vue.component 固定格式,通过Vue注册一个component(组件) // Vheader组件的名字 第一个字母建议大写,且有意义 data: function () { // data必须是个函数,函数中必须要return,哪怕return是个空的也可以,就是不能省略,省略报错 return {} }, template: `<div class="header"> <div class="w"> <div class="w-l"> <img src="" alt=""> </div> <div class="w-r"> <button>登录</button><button>注册</button> </div> </div> </div>` });
Vue组件的结构(使用):
组件是可以复用的Vue实例,并且带有一个名字,比如上边的<Vheader>。我们可以在一个通过new Vue创建的Vue根实例中,把这个组件左为自定义元素来使用:
详解
组件的注册
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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: { } });
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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 } })
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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", })
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<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>
组件之间的通信
我们的组件在任何地方用的时候都要是一个样子么~
可不可以我们给组件传个参数~让组件在不同的地方表现不同的状态~
我们之前说过博客评论@某某某,点击用户名可以跳转到该用户站点。
这样一个小功能,我们每次@的时候都要写,我们可以封装成组件,传值即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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回调函数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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}) } } });
平行组件之间的通信,喊话需要一个中间调度器,在组件加载完成之后去监听调度器事件,回调函数接收数据。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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的内容。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 点击显示和隐藏 提示框的显示和隐藏 // 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>作为内容承载分发的出口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 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", }) Slot