【前端-VUE】Vue3组件组成部分及组件通信(详解)

一、父子间通信

1.父传子:

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第1张图片

2.子传父:

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第2张图片

3.什么是prop

Prop定义:组件上注册的一些自定义属性

Prop作用:向子组件传递数据

特点

  • 可以传递任意数量的prop
  • 可以传递任意类型的prop

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第3张图片

3.1 props校验

思考:组件的prop可以乱传么?

不可以

作用:为组件的prop指定验证要求,不符合要求,控制台就会有错误提示——>帮助开发者,快速发现错误

语法

①类型校验

②非空校验

③默认值

④自定义校验

props:{

校验的属性名: 类型 //Number String Boolean Array Object…

},

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第4张图片

3.2更详细的props校验

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第5张图片

props:{
    校验的属性名:{
        type:类型, // Number String Boolean …
        required: true, // 是否必填
        default: 默认值, // 默认值
        validator (value){
            // 自定义校验逻辑
            return 是否通过校验
        }
    }
},

4.prop & data、单向数据流

共同点:都可以给组件提供数据。

区别

  • data的数据是自己的——> 随便改
  • prop的数据是外部的 ——> 不能直接改,要遵循 单向数据流

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第6张图片

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第7张图片

总结:

谁的数据谁负责

1.data:自己的数据,随便改(谁的数据谁负责)

2.prop传过来的数据(外部的数据)不能直接改

3.单向数据流:父组件的prop更新,会单向向下流动,影响到子组件

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第8张图片

4.1综合案例

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第9张图片

4.2核心代码

App.vue



TodoMain.vue



Todoheader.vue



TodoFooter.vue



4.3总结

核心步骤:

①拆分基础组件

新建组件——> 拆分存放结构 ——> 导入注册使用

②渲染待办事项

提供数据(公共父组件)——> 父传子传递list ——> v-for渲染

③添加任务

收集数据 v-model ——>监听事件 ——> 子传父传递任务 ——> 父组件unshift

④删除任务

监听删除携带id ——> 子传父传递id ——> 父组件filter删除

⑤底部合计 和 清空功能

底部合计:父传子传递list ——> 合计展示

清空功能:监听点击 ——>子传父通知父组件 ——> 父组件清空

⑥持久化存储

watch监视数据变化,持久化到本地

二、非父子通信

1.非父子通信- event bus 事件总线

作用:非组件之间,进行简易消息传递。(复杂场景——>Vuex)

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第10张图片

1.创建一个能够访问到的事件总栈(空Vue实例)——>utils/EventBus.js

improt Vue form 'vue'
const Bus = new Vue()
export default Bus

2.A组件(接收方),监听Bus实例的事件

created (){
	Bus.$on('sendMsg',(msg)=>{
		this.msg = msg
	})
}

3.B组件(发送方),触发Bus实例的事件

Bus.$emit('sendMsg','这是一个消息')

代码:

App.vue



 BaseA.vue




 BaseB.vue



BaseC.vue




EventBus.js

// 1.创建一个都能访问到的事件总线(空的Vue实例)
import { createApp } from 'vue';
 
const Bus = createApp({}); // 创建一个空的Vue实例
export default Bus

2.非父子通信(拓展)-provide & inject

provide & inject 作用:跨层级共享数据

1.父组件provide提供数据

export default {
	provide (){
		return {
			//普通类型【非响应式】
			color: this.color,
			// 复杂类型【响应式】
			userInfo: this.userInfo,
		}
	}
}

2./孙组件inject取值使用

export default {
	inject: ['color','userInfo'],
	created(){
		console.log(this.color,this.userInfo)
	}
}

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第11张图片

代码:

App.vue



SonA.vue


SonB.vue


GrandSon.vue


 【前端-VUE】Vue3组件组成部分及组件通信(详解)_第12张图片

三、v-model原理

1.原理:

v-model本质上是一个语法糖。例如应用在输入框上,就是value属性和input事件的合写。

作用:提供数据的双向绑定

①数据变,视图跟着变 :value

②页面输入改变,数据会自动改变 @input

注意:$event用于模板中,获取时间中的形参

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第13张图片

2.表单类组件封装&v-model简化代码

2.1表单类组件 封装

①父传子:数据 应该是父组件props传递过来的,v-model拆解 绑定数据

②子传父:监听输入,子传父传值给父组件修改

本质:实现了子组件 和 父组件数据 的双向绑定

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第14张图片

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第15张图片

2.2 父组件v-model 简化代码,实现 子组件 和父组件数据 双向绑定

①子组件中:props通过value接收,事件触发input

②父组件中:v-model给组件直接绑数据 (:value + @input)

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第16张图片

代码:

App.vue


BaseSelect.vue



四、sync修饰符

  • 作用:可以实现 子组件 与 父组件数据 的双向绑定,简化代码
  • 特点:prop属性名,可以自定义,非固定为value
  • 场景:封装弹窗类的基础组件,visible属性 true显示 false隐藏
  • 本质:就是 :属性名 和 @update:属性名 合写

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第17张图片

代码:

App.vue



BaseDialog.vue



五、ref和$refs

作用利用ref$refs可以用于获取dom(文档对象模型中代表HTML元素的JavaScript对象)元素,或组件实例

特点:查找范围——>当前组件内(更精准稳定)

获取dom

1.目标标签-添加ref属性

我是渲染表的容器

2.恰当时机,通过this.$refs.xxx,获取目标标签

mounted(){
console.log(this.$refs.chartRef)
},

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第18张图片

代码:

App.vue



BaseChart.vue



效果图:

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第19张图片

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第20张图片

代码:

App.vue



BaseForm.vue



六、Vue异步更新、$nextTick

需求:编辑标题,编辑框自动聚焦

1.点击编辑,显示编辑框

2.让编辑框立刻获取焦点

this.isShowEdit = true // 显示输入框
this.$refs.inp.focus() // 获取焦点

问题:“显示之后”,立刻获取焦点是不能成功的!

原因:vue是异步更新DOM(提升性能)

【前端-VUE】Vue3组件组成部分及组件通信(详解)_第21张图片

$nextTick:DOM更细后,才会触发执行此方法里的函数体

语法:this.$nextTick(函数体)

this.$nextTick(()=>{
this.$refs.inp.focus()
})

代码:

App.vue



总结:

1.Vue是异步更新DOM的

2.想要在DOM更新完成之后做某件事,可以使用$nextTick

你可能感兴趣的:(前端学习日记,VUE3,JavaScript,前端,vue.js,javascript)