每个组件对应的模板结构,需要定义到节点中
template是vue提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的DOM元素;
template中只能包含唯一的根节点
子传父
{{title}}
显示子组件内容: {{num}}
{{title}}
采用的是事件原理:触发机制和监听机制
事件原理执行顺序/阶段:事件捕获(从外到内)->目标(找到目标)->事件冒泡(从内到外)。冒泡采用事件委托。
事件总线eventBus:
凡是牵扯到事件的业务一定要注意:
发送方和接收方都必须同时存在
监听必须早于发送
vue3和vue2实现不一样,vue3推荐使用第三方库,需要安装库:
mitt -> yarn add mitt/cnpm install --save mitt/npm i -S mitt
//main.js 全局配置
import { createApp } from 'vue'
// 注入
import App from './provide-inject/index.vue'
/** 引入事件总线的库
* function mitt(all?: EventHandlerMap): Emitter
* all? 表示这个参数可以不传
* : Emitter 表示这个方法执行以后会得到一个Emitter实例 -> 一个方法要得到一个实例,要执行new运算
*/
import Mitt from 'mitt'
const app = createApp(App)
// 去注册全局事件对象--给全局的实例注册一个全局的配置属性对象,它的值是一个Emitter
app.config.globalProperties.$eventBus = new Mitt()
app.mount('#root')
A 组件
A 组件的数据 value {{value}}
B 组件
A 组件的数据 value {{myValue}}
eventBus又称事件总线。在Vue中可以使用eventBus作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行的通知其他组件。
事件总线也是一种通信方式,只不过它的功能比较强大,不在局限于父传子或兄弟组件之间通信,它可以跨组件通信,通过事件总线传递的值,不管哪个组件都可以获取到。
原文链接:https://blog.csdn.net/m0_58974838/article/details/118885935
message = $event.target.value">{{message}}
{{message}}
1. 在自己定义表单组件中使用v-model="message"
2. 子组件中
一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props
props:['modelValue'],
template:'',
methods:{
onInput(){
this.$emit('update:modelValue',event.target.value)
}
}
1. 接收参数名 modelValue
2. 触发事件名 update:modelValue
3. 表单元素中 :value="modelValue"
@input="($emit)=>$emit('update:modelValue',event.target.value)"
CustomInput组件中的value不可以叫别的名字,$emit中抛出的方法也只能叫@input
{{message}}
{{searchText}} - {{title}}
-------------------------
项目运用
因为v-model指令是基于数据双向绑定实现的,它的底层原理是使用value属性来绑定数据,input事件来修改数据
//父组件
添加成分数据
//子组件
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为props或emits 的 attribute 或者 v-on
事件监听器。最常见的例子就是 class
、style
和 id
。
当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上
可以理解为通过传递属性的方式的继承,但不是继承
$attrs
这个实例属性来访问组件的所有透传 attribute$attrs
被显式绑定,则不会有警告...
...
子组件
{{$attrs}}
节点三 -->
深层组件
1. 父子组件之间
2. 子组件定义插槽
3. 父组件定义插槽内容
1. 插槽设定名称
2. 父组件根据名称放内容
1. 子组件中slot插槽标签绑定属性
2. 父组件使用插槽处接收属性
父组件
花
绿化带
树
{{treeSlot.title}}
子组件 公路
使用: 子组件中定义数据 商品列表数据
在父组件中定义界面 界面效果
商城
- >
{{item.id}}-{{item.name}}- {{item.price}}
商品列表
解决 跨组件传参问题
provide
和 inject
可以解决这一问题。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
要为组件后代提供数据,需要使用到 provide,provide如果不是函数形式,那只能传递固定参数,不能使用this对象
export default {
data() {
return {
message: 'hello!'
}
},
provide() {
// 使用函数的形式,可以访问到 `this`
return {
message: this.message
}
}
}
要注入上层组件提供的数据,需使用inject(注入)选项来声明
注入会在组件自身的状态之前被解析,因此可以在 data()
中访问到注入的属性
当以数组形式使用 inject
,注入的属性会以同名的 key 暴露到组件实例上。在上面的例子中,提供的属性名为 "message"
,注入后以 this.message
的形式暴露。访问的本地属性名和注入名是相同的。
export default {
inject: ['message'],
data() {
return {
// 基于注入值的初始数据
fullMessage: this.message
}
}
}
用一个不同的本地属性名注入该属性,需要在 inject
选项的属性上使用对象的形式
这里,组件本地化了原注入名 "message"
所提供的的属性,并将其暴露为 this.localMessage
export default {
inject: {
/* 本地属性名 */ localMessage: {
from: /* 注入来源名 */ 'message'
}
}
}
为保证注入方和供给方之间的响应性链接,我们需要使用 computed() 函数提供一个计算属性,在顶层使用provide提供数据,要双向绑定就必须用computed函数。
import { computed } from 'vue'
export default {
data() {
return {
message: 'hello!'
}
},
provide() {
return {
// 显式提供一个计算属性
message: computed(() => this.message)
}
}
}
根组件
{{message}}
第一层父组件
第二层子组件
{{msg}}
更改后名称: {{localContent}}
让多个组件使用同一个挂载点,并动态切换,这就是动态组件
通过 Vue 的
元素和特殊的 is
attribute 实现的
被传给 :is
的值可以是以下几种:
可以使用 is
attribute 来创建一般的 HTML 元素。
在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过
- 首页
- 分类
- 购物车
- 我的