## 组件化
-工程化 组件化 模块化
命名规则:
组件定义时,名称可以是短横线,也可以是驼峰式
1 假如是驼峰式命名,使用组件的时候,只能在字符串模板中用驼峰式
不能再普通的标签模板中,普通的标签模板中只能用短横线
短行线到处都可以使用
基础使用——全局定义组件方式
================维护自身的数据与方法======================
Vue.component('my-button', {
//template必须要有
template: `
<div>
<button @click="increase">普通按钮{{num}}</button>
<MyComp></MyComp>
</div>
`,
data() {
return {
num: 0
}
},
methods: {
increase() {
this.num++;
}
}
});
=============================================
Vue.component('MyComp', {
template: '<h2>MyComp</h2>'
});
new Vue({
el: '#app'
});
====================布局========================
<div id="app">
<my-button></my-button>
<my-button></my-button>
<my-button></my-button>
</div>
基础使用——局部定义组件方式
//定义组件对象
let myComp = {
template: `<div>局部组件</div>`,
data() {
return {
num: 10,
}
}
};
//加载组件
new Vue({
el: '#app',
data() {
return {
total: 0,
}
},
// 子组件
components: {
'my-comp': myComp
}
});
===================页面布局===================
<div id="app">
<my-comp></my-comp>
</div>
【3】父子组件嵌套
<!-- 普通模板中:支持短行线;如果有连字符,则props中必须为驼峰式 -->
<child :pmsg="pmsg" :text="text"></child>
===========================组件定义==========================
根组件:
new Vue({
el: '#app',
data() {
return {
pmsg: 'father comp',
text: 'world'
}
}
});
//父子组件
Vue.component('child', {
//props 中名称支持 驼峰式:
props: ['pmsg', 'text'],
template: `
<div>
{{msg}}--{{pmsg}}--{{text}}
<child2 :testDemo="msg"></child2>
</div>
`,
data() {
return {
msg: 'child'
}
}
});
Vue.component('child2', {
props: ['testDemo'],
template: `<div>{{testDemo}}</div>`
});
父子组件数据传递问题
<div id="app">
<div :style="{fontSize:fontSize+'px'}">内容</div>
<!-- 属性后面的为父组件的变量 -->
<!-- 通过自定义事件绑定到父组件上的方法 -->
<menu-item :br="hobbies" :font-size="fontSize" @enlarge-text="handle(fontSize)"></menu-item>
</div>
=======================================
Vue.component('menu-item', {
props: ['br', 'fontSize'], //给的是属性
template: `
<div>
<ul>
<li :key="index" v-for='(item,index) in br'>
{{item}}
</li>
</ul>
<button @click="$emit('enlarge-text')">放大字号</button>
<button @click="increaseFS1()">放大字号</button>
</div>
`,
methods: {
increaseFS1() {
// 注意传参:第一个为事件名称,后面为传入的参数
this.$emit('enlarge-text', 12);
}
}
});
=======================根组件================================
new Vue({
el: '#app',
data() {
return {
hobbies: ['coding', 'running', 'eating'],
fontSize: 16
}
},
methods: {
handle(fontSize) {
let arr = [...arguments];
console.log(arguments);
console.log(arr);
this.fontSize += arr[0];
}
}
});
//slot:占位符
<div id="app">
<alert-msg>类型错误</alert-msg>
<alert-msg></alert-msg>
<alert-msg>服务器内部错误</alert-msg>
<alert-msg></alert-msg>
</div>
=============================
Vue.component('alert-msg', {
//slot:占位符
template: `
<div>
<strong>Error</strong>
<!--<p>TypeError</p>-->
<slot>something is wrong!</slot>
</div>
`,
});
new Vue({
el: '#app',
data() {
return {}
}
});
vm.$emit(‘事件名’,递增倍数)
<div id="app">
<test1></test1>
<test2></test2>
<button @click='destroy'>销毁</button>
</div>
=============================
事件注册中心
let vm = new Vue();
========组件1声明
Vue.component('test1', {
data() {
return {
a: 0,
}
},
template: `
<div>
<p>test1-{{a}}</p>
<p><button @click='handle'>点击</button></p>
</div>
`,
//实例挂载
mounted() {
vm.$on('test1-event', val => {
this.a += val;
});
},
methods: {
handle() {
//触发兄弟组件test2的事件
vm.$emit('test2-event', 2);
}
}
});
=======兄弟2组件
Vue.component('test2', {
data() {
return {
a: 0,
}
},
template: `
<div>
<p>test2-{{a}}</p>
<p><button @click='handle'>点击</button></p>
</div>
`,
//实例挂载
mounted() {
//监听
vm.$on('test2-event', val => {
this.a += val;
});
},
methods: {
handle() {
//触发,发布
vm.$emit('test1-event', 3);
//$off():移除
}
}
});
====根组件
new Vue({
el: '#app',
data() {
return {}
},
methods: {
destroy() {
vm.$off('test1-event');
}
}
});
slot-infro应用
==============组件定义
Vue.component('cars-list', {
props: ['cars'],
template: `
<div>
<ul>
<li v-for="(car,index) in cars" :key="index">
<slot :info='car'>{{car.name}}</slot>
</li>
</ul>
</div>
`
});
================布局
<div id="app">
<cars-list :cars='cars'>
<!-- 通过slot-scope = v-slot:default, 获取 slot的值 :info为属性 -->
<template slot-scope='slotProps'>
<!-- 作用域插槽 -->
<p v-if="slotProps.info.id===2" class="red">
{{slotProps.info.name}}
</p>
<!-- <p v-else>{{slotProps.info.name}}</p> -->
</template>
</cars-list>
</div>
============根组件主要:数据定义
new Vue({
el: '#app',
data() {
return {
cars: [{
id: 1,
name: 'bm'
}, {
id: 2,
name: 'bc'
}, {
id: 3,
name: 'ad'
}],
}
}
});
slot布局
=================定义组件框架布局
Vue.component('base-layout', {
template: `
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot name='main'></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
`,
});
====================组件应用
<div id="app">
<base-layout>
<template slot="header">
<p>头部1</p>
<p>头部</p>
</template>
<template slot="footer">
<p>尾部2</p>
<p>尾部</p>
</template>
<p slot="main">主体</p>
</base-layout>
</div>