1.组件的使用
<div id="app">
<button-counter></button-counter>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
//注册组件
Vue.component("button-counter",{
data(){
return{
count:0
}
},
template:'<button>点击了{{count}}次</button>',
methods:{
handle(){
this.count+=2;
}
}
})
var vm=new Vue({
el:"#app",
data:{
}
})
</script>
2.组件注册注意事项
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/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>测试123</button>
</div>
`,
methods: {
handle: function(){
this.count += 2;
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
3.局部组件用法
<div id="app">
<hello-world></hello-world>
<hello-tom></hello-tom>
<hello-jerry></hello-jerry>
<test-com></test-com>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
/*
* 局部组件注册
* 局部组件只能在注册他的父组件中使用*/
Vue.component('test-com',{
template:'<div>Test<hello-world></hello-world></div>'
});
var HelloWorld={
data(){
return {
msg:'helloworld'
}
},
template:'<div>{{msg}}</div>'
};
var HelloTom={
data(){
return{
msg:'hellotom'
}
},
template:'<div>{{msg}}</div>'
};
var HelloJerry={
data(){
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>
4.父组件向子组件
<div id="app">
<div>
{{pmsg}}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
/**
* 父组件向子组件传值-基本使用
*/
Vue.component('menu-item',{
props:['title','content'],
data(){
return{
msg:'子组件本身的数据'
}
},
template:'<div>{{msg+"---"+title+"----"+content}}</div>'
})
var vm = new Vue({
el: "#app",
data: {
pmsg: '父组件中内容',
ptitle: "动态绑定属性",
pcontent: "动态绑定内容",
}
})
</script>
5.父组件向子组件传值
1.props命名规则
<div id="app">
<menu-item :menu-title='ptitle'></menu-item>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/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>
2.props属性值类型
<div id="app">
<menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
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>`
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
pstr: 'hello',
parr: ['apple','orange','banana'],
pobj: {
name: 'lisi',
age: 12
}
}
});
</script>
3.组件携带参数
<div id="app">
<div :style="{fontSize:fontSize+'px'}">{{pmsg}}</div>
<menu-item :parr="parr" @enlarge-text="handle($event)"></menu-item>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('menu-item',{
props:['parr'],
template:'<div>' +
'<ul><li v-for="(item,index) in parr" :key="index">{{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>
4.数据交互
<div id="app">
<div>父组件</div>
<div>
<button @click='handle'>销毁事件</button>
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var hub = new Vue();
Vue.component('test-tom',{
data(){
return{
num:0
}
},
template:'<div>' +
'<div>TOM:{{num}}</div>' +
'<div><button @click="handle">点击</button></div>' +
'</div>',
methods:{
handle(){
hub.$emit('jerry-event',2);
}
},
mounted(){
hub.$on('tom-event',(val)=>{
this.num+=val;
});
}
});
Vue.component('test-jerry',{
data(){
return{
num:0
}
},
template:'<div>' +
'<div>JERRY:{{num}}</div>' +
'<div>' +
'<button @click="handle">点击</button>' +
'</div>' +
'</div>',
methods:{
handle(){
//触发兄弟组件的事件
hub.$emit('tom-event',1);
}
},
mounted(){
//监听事件
hub.$on('jerry-event',(val)=>{
this.num+=val;
})
}
});
var vm = new Vue({
el: "#app",
data: {},
methods: {
handle() {
hub.$off('tom-event');
hub.$off('jerry-event');
}
}
})
6.插槽
<div id="app">
<alert-box>有bug发生</alert-box>
<alert-box>有一个警告</alert-box>
<alert-box></alert-box>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/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>
7.具名插槽
<div id="app">
<base-layout>
<p slot="header1">标题信息</p>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot="footer">底部信息</p>
</base-layout>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
Vue.component("base-layout",{
template:'<div>' +
'<header>' +
'<slot name="header1"></slot>' +
'</header>' +
'<main>' +
'<slot></slot>' +
'</main>' +
'<footer>' +
'<slot name="footer"></slot>' +
'</footer>' +
'</div>'
});
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
8.作用域插槽用法
<style type="text/css">
.current {
color: orange;
}
</style>
<div id="app">
<fruit-list :lists="list">
<template slot-scope="slotProps">
<strong v-if="slotProps.what.id==3" class="current">{{slotProps.what.name}}</strong>
<span v-else>{{slotProps.what.name}}==>123</span>
</template>
</fruit-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('fruit-list',{
props:['lists'],
template:'<div>' +
'<li v-for="item in lists" :key="item.id" >' +
'<slot :what="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>