Vue的全局组件
全局组件,在所有Vue实例中都可以使用
通过应用程序实例app的component()方法来定义
语法:app.component(组件名,选项对象)
<body>
<div id="app">
<p>{{msg}}</p>
<!-- 组件名称就是调用的标签名<h-l></h-l> -->
<!-- 组件服用,组件多次调用 ,组件间的数据独立,互不影响-->
<my-hello v-for="(item,index) in 3" :key="index"></my-hello>
</div>
<template id="content">
<div>
<h3>template</h3>
<p>挂载的template</p>
<p>name:{{name}}</p>
<input type="text" v-model="name">
</div>
</template>
</body>
<script>
const app = Vue.createApp({ //app是应用程序实例
data(){
return {
msg:'hello vue'
}
}
})
app.component('my-hello',{ //命名方式可以是短线相连
template:'#content',
data(){
return{
name:'tom'
}
}
})
const vm = app.mount('#app') //vm是vue实例,也是一个组件,称为根组件(root组件)
</script>
局部组件
只能在构建组件的Vue实例的容器范围内使用;
依赖于某个Vue实例,通过选项components:{}来定义
语法:
Vue.createApp({
components:{
'component-a':选项对象,
‘component-b’:选项对象
}
})
<script>
const app = Vue.createApp({ //app是应用程序实例
data(){
return {
msg:'hello vue'
}
}
})
app.component('my-hello',{ //命名方式可以是短线相连
template:'#content',
data(){
return{
name:'tom'
}
}
})
const vm = app.mount('#app') //vm是vue实例,也是一个组件,称为根组件(root组件)
</script>
组件间数据传递
默认情况下,每个组件实例都是独立的,组件间无法直接访问数据;
因此需要进行组件间的数据传递,也称为组件间的通信
分类:
父组件向子组件的数据传递步骤:
- 父组件在调用子组件时,以属性绑定的方式将要传递的数据绑定在子组件标签上;
- 在子组件对象中,使用props选项声明获取的数据,进行绑定的属性的拦截,即接收来自父组件的数据
子组件向父组件的数据传递
- 父组件在调用子组件时,监听子组件触发的自定义事件,并在父组件中定义回调方法,用来接收数据
- 在子组件忠使用vm.$emit(事件名,数据)触发自定义事件
<body>
<div id="app">
<my-hello></my-hello>
</div>
<template id="hello">
<div>
<h3>我是hello父组件</h3>
<h1>我是父组件的数据{{msg}}</h1>
<hr>
<!-- 属性绑定的方式 -->
<my-world :message="msg" :age="data" :user="user" @get-data="get"></my-world>
<h3>{{childmsg}}</h3>
</div>
</template>
<template id="world">
<div>
<h1>我是子组件world</h1>
<h3>引用父组件的数据:{{message}},年龄是:{{age}},用书:{{user.sex}}</h3>
<h3>子组件的数据{{childmsg}},{{height}}</h3>
<button @click="send">将子组件的数据传递给父组件</button>
</div>
</template>
</body>
<script>
//h根组件
Vue.createApp({
components:{//父组件
'my-hello':{
template:'#hello',
data(){
return {
msg:'my,hello',
data:18,
user:{
id:1001,
sex:'man'
},
childmsg:null,
height:null
}
},
methods:{
get(childmsg,height){
console.log(childmsg)
this.childmsg = childmsg
this.height = height
}
},
components:{//子组件
'my-world':{
template:'#world',
props:['message','age','user'],
data(){
return {
childmsg:'child',
height:20
}
},
methods:{
send(){
//使用$emit()触发一个事件
this.$emit('get-data',this.childmsg,this.height)
}
}
}
}
}
}
}).mount('#app')
</script>
内置组件
Vue提供了全局的内置组件,这些组件主要完成的都是功能封装
动态组件
- 多个组件使用同一个挂载点,然后动态的在他们之间切换,称为动态组件;
- 用法:
- 使用is属性动态绑定组件,决定那个组件被渲染
<body>
<div id="app">
<button @click="flag = 'CompA'">组件A</button>
<button @click="flag = 'CompB'">组件B</button>
<button @click="flag = 'CompC'">组件c</button>
<!-- <comp-b></comp-b> -->
<hr>
<!-- 动态把绑定组件 -->
<component :is="flag"></component>
</div>
</body>
<script>
Vue.createApp({
data(){
return {
flag:'CompA'
}
},
components:{
CompA:{
template:'<h3>组件A</h3>'
},
CompB:{
template:'<h3>组件B</h3>'
},
CompC:{
template:'<h3>组件C</h3>'
},
},
}).mount('#app')
</script>
缓存组件
- 缓存非活动的组件,可以保留组件状态,避免冲重新渲染,默认每次都会销毁非胡哦东组件并重新创建
- 一般会结合动态组件使用,用于缓存非活动的组件实例,避免组件的重复创建和删除,提高性能
- 用法动态组件
分发组件
- 实现内容的分发,可以在定义组件时指定插槽位置,调用组件时提供要替换插槽位置的内容
- 用法:
- 具名插槽:为插槽指定名称,根据插槽名称进行内容分发
- 在定义插槽时,在slot标签上通过name属性为插槽指定名称
- 在提供插槽内容时,通过为template标签指定v-slot指令,并以指定参数表示插槽名称
<body>
<div id="app">
<!-- 插槽基本用法 -->
<comp-a>
<p>插槽内容</p>
</comp-a>
<hr>
<comp-a>
<span>插槽内容2</span>
</comp-a>
<!-- 具名插槽 -->
<comp-b>
<template v-slot:first-slot>
<p>第一个插槽的内容</p>
</template>
<template v-slot:second-slot>
<p>第二个插槽的内容</p>
</template>
<template v-slot:third-slot>
<p>第三个插槽的内容</p>
</template>
</comp-b>
</div>
<template id="a">
<div>
<h3>组件A</h3>
<!-- 定义插槽位置,其实就是占个位置 -->
<slot></slot>
</div>
</template>
<template id="b">
<div>
<h3>第一次组件B</h3>
<slot name="first-slot"></slot>
<h3>第二次组件B</h3>
<slot name="second-slot"></slot>
<h3>第三次组件B</h3>
<slot name="third-slot"></slot>
</div>
</template>
</body>
<script>
Vue.createApp({
data(){
return {
}
},
components:{
'comp-a':{
template:'#a'
}
},
components:{
'comp-b':{
template:'#b'
}
}
}).mount('#app')
</script>