文章目录
一、组件
1. 组件的注册
局部注册、全局注册
js
// 导入需要注册的组件
import 组件对象 from '.vue文件路径'
import HmHeader from './components/HmHeader'
export default { // 局部注册
components: {
'组件名': 组件对象,
HmHeader:HmHeaer,
HmHeader
}
}
-------------------------
// main.js
// 导入需要全局注册的组件
import HmButton from './components/HmButton'
// 进行全局注册(组件名,组件对象)
Vue.component('HmButton', HmButton)
写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。
-
全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响
-
局部样式 : 可以给组件加上scoped 属性,可以让样式只作用于当前组件
scoped属性原理:
- 当前组件内所有标签都被添加data-v-hash值 的属性
- css选择器都被添加 [data-v-hash值] 的属性选择器
最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到

2. 组件通信
组件的数据是独立的,无法直接访问其他组件的数据。
将组件简单分为父子关系与非父子关系,两种类型通信方式不太
父子通信
- 父组件通过 props 将数据传递给子组件
vue
// 父组件App.vue
<template>
<div class="app">
<UserInfo
:username="username"
:age="age"
:hobby="hobby"
></UserInfo>
</div>
</template>
<script>
import UserInfo from './components/UserInfo.vue'
export default {
data() {
return {
username: 'LiLi',
age: 18,
hobby: ['篮球', '足球', '羽毛球'],
}
},
components: {
UserInfo,
},
}
</script>
<style>
</style>
vue
// 子组件
<template>
<div class="userinfo">
<h3>我是个人信息组件</h3>
<div>姓名:{{ username }}</div>
<div>年龄:{{ age }}</div>
<div>兴趣爱好:{{ hobby.join(',') }}</div>
</div>
</template>
<script>
export default {
props: ['username', 'age', 'hobby']
}
</script>
<style>
.userinfo {
width: 300px;
border: 3px solid #000;
padding: 20px;
}
.userinfo > div {
margin: 20px 10px;
}
</style>
props校验:为组件的 prop 指定验证要求 ,不符合要求,控制台就会有错误提示
js
props: {
校验的属性名: {
type: 类型, // Number String Boolean ...
required: true, // 是否必填
default: 默认值, // 默认值
validator (value) {
// 自定义校验逻辑
return 是否通过校验
}
}
},
- 子组件利用 $emit 通知父组件修改更新
-
$emit触发事件,给父组件发送消息通知
-
父组件监听$emit触发的事件
-
提供处理函数,在函数的性参中获取传过来的参数
非父子通信
以下是简易的消息传递,复杂场景需要使用Vuex
可以是一对多的情况,一个组件发送消息,凡是监听了该消息的组件都可以使用。
- event bus 事件总线
-
创建一个都能访问的事件总线 (空Vue实例)
jsimport Vue from 'vue' const Bus = new Vue() export default Bus -
A组件(接受方),监听Bus的 $on事件
vuecreated () { Bus.$on('sendMsg', (msg) => { this.msg = msg }) } -
B组件(发送方),触发Bus的$emit事件
vueBus.$emit('sendMsg', '这是一个消息')
- provide&inject
跨层级共享数据
- 父组件 provide提供数据
js
export default {
provide () {
return {
// 普通类型【非响应式】
color: this.color,
// 复杂类型【响应式】
userInfo: this.userInfo,
}
}
}
2.子/孙组件 inject获取数据
js
export default {
inject: ['color','userInfo'],
created () {
console.log(this.color, this.userInfo)
}
}
注意:
- provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
- 子/孙组件通过inject获取的数据,不能在自身组件内修改,谁的数据谁管理,需要"通知"父组件管理
二、插槽
插槽嵌入在标签内部,可以让标签内的结构支持自定义
1. 默认插槽
-
组件内需要定制的结构部分,改用**
<slot></slot>**占位 -
使用组件时, **<组件名></组件名>**标签内部, 传入结构替换slot
-
给插槽传入内容时,可以传入纯文本、html标签、组件
-
在
<slot>标签内,放置内容, 作为默认显示内容,外部使用组件并传递时,则slot整体会被换掉
2. 具名插槽
一个组件内有多处结构,需要外部传入标签,进行定制 时使用具名插槽。
- 多个slot使用name属性区分名字
- template配合v-slot:名字来分发对应标签
- v-slot简单写法 v-slot ---> #
js
<div class="header">
<slot></slot>
</div>
<div class="content">
<slot></slot>
</div>
<div class="footer">
<slot></slot>
</div>
----------------
<MyContent>
<template v-slot="header">标题</template>
<template v-slot="content">标题</template>
<template v-slot="footer">标题</template>
</MyContent>
3. 插槽的作用域
给 插槽绑定数据 ,将来 使用组件时可以用
-
给 slot 标签, 以 添加属性的方式传值
vue<slot :id="item.id" msg="测试文本"></slot> -
所有添加的属性, 都会被收集到一个对象中
vue{ id: 3, msg: '测试文本' } -
在template中, 通过
#插槽名= "obj"接收,默认插槽名为 defaultvue<MyTable :list="list"> <template #default="obj"> <button @click="del(obj.id)">删除</button> </template> </MyTable>