vue-4

一、文章内容概括

1.组件的三大组成部分(结构/样式/逻辑)

​ scoped解决样式冲突/data是一个函数

2.组件通信

  1. 组件通信语法
  2. 父传子
  3. 子传父
  4. 非父子通信(扩展)

3.进阶语法

  1. v-model原理
  2. v-model应用于组件
  3. sync修饰符
  4. ref和$refs
  5. $nextTick

二、scoped解决样式冲突

1.默认情况

写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。

  1. 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响

  2. 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件

2.代码演示

BaseOne.vue





BaseTwo.vue






App.vue




3.scoped原理

  1. 当前组件内标签都被添加data-v-hash值 的属性
  2. css选择器都被添加 [data-v-hash值] 的属性选择器

最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到

在这里插入图片描述

4.总结

  1. style的默认样式是作用到哪里的?
  2. scoped的作用是什么?
  3. style中推不推荐加scoped?

三、data必须是一个函数

1、data为什么要写成函数

一个组件的 data 选项必须是一个函数。目的是为了:保证每个组件实例,维护独立的一份数据对象。

每次创建新的组件实例,都会新执行一次data 函数,得到一个新对象。

vue-4_第1张图片

2.代码演示

BaseCount.vue






App.vue






3.总结

data写成函数的目的是什么?

四、组件通信

1.什么是组件通信?

组件通信,就是指组件与组件之间的数据传递

  • 组件的数据是独立的,无法直接访问其他组件的数据。
  • 想使用其他组件的数据,就需要组件通信

2.组件之间如何通信

vue-4_第2张图片

思考:

  1. 组件之间有哪些关系?
  2. 对应的组件通信方案有哪几类?

3.组件关系分类

  1. 父子关系
  2. 非父子关系

vue-4_第3张图片

4.通信解决方案

vue-4_第4张图片

5.父子通信流程

  1. 父组件通过 props 将数据传递给子组件
  2. 子组件利用 $emit 通知父组件修改更新

vue-4_第5张图片

6.父向子通信代码示例

父组件通过props将数据传递给子组件

父组件App.vue






子组件Son.vue






vue-4_第6张图片

父向子传值步骤

  1. 给子组件以添加属性的方式传值
  2. 子组件内部通过props接收
  3. 模板中直接使用 props接收的值

7.子向父通信代码示例

父组件App.vue






子组件Son.vue






子组件利用 $emit 通知父组件,进行修改更新

vue-4_第7张图片

子向父传值步骤

  1. $emit触发事件,给父组件发送消息通知
  2. 父组件监听$emit触发的事件
  3. 提供处理函数,在函数的性参中获取传过来的参数

8.总结

  1. 组件关系分类有哪两种
  2. 父子组件通信的流程是什么?
    1. 父向子
    2. 子向父

五、什么是props

1.Props 定义

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

2.Props 作用

向子组件传递数据

3.特点

  1. 可以 传递 任意数量 的prop
  2. 可以 传递 任意类型 的prop

vue-4_第8张图片

4.代码演示

父组件App.vue






子组件UserInfo.vue






六、props校验

1.思考

组件的props可以乱传吗

2.作用

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

3.语法

  • 类型校验
  • 非空校验
  • 默认值
  • 自定义校验

vue-4_第9张图片

4.代码演示

App.vue






BaseProgress.vue






七、props校验完整写法

1.语法

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

2.代码实例


3.注意

1.default和required一般不同时写(因为当时必填项时,肯定是有值的)

2.default后面如果是简单类型的值,可以直接写默认。如果是复杂类型的值,则需要以函数的形式return一个默认值

八、props&data、单向数据流

1.共同点

都可以给组件提供数据

2.区别

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

3.单向数据流:

父级props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的

4.代码演示

App.vue






BaseCount.vue






vue-4_第10张图片

5.口诀

谁的数据谁负责

九、非父子通信-event bus 事件总线

1.作用

非父子组件之间,进行简易消息传递。(复杂场景→ Vuex)

2.步骤

  1. 创建一个都能访问的事件总线 (空Vue实例)

    import Vue from 'vue'
    const Bus = new Vue()
    export default Bus
    
  2. A组件(接受方),监听Bus的 $on事件

    created () {
      Bus.$on('sendMsg', (msg) => {
        this.msg = msg
      })
    }
    
  3. B组件(发送方),触发Bus的$emit事件

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

    vue-4_第11张图片

3.代码示例

utils/EventBus.js

import Vue from 'vue'
const Bus = new Vue()
export default Bus

BaseA.vue(接受方)






BaseB.vue(发送方)






App.vue






4.总结

1.非父子组件传值借助什么?

2.什么是事件总线

3.发送方应该调用事件总线的哪个方法

4.接收方应该调用事件总线的哪个方法

5.一个组件发送数据,可不可以被多个组件接收

十、非父子通信-provide&inject

1.作用

跨层级共享数据

2.场景

vue-4_第12张图片

3.语法

  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)
  }
}

4.注意

  • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
  • 子/孙组件通过inject获取的数据,不能在自身组件内修改

5.代码演示

GrandSon.vue






SonA.vue






SonB.vue






App.vue






十一、v-model原理

1.原理:

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



2.作用:

提供数据的双向绑定

  • 数据变,视图跟着变 :value
  • 视图变,数据跟着变 @input

3.注意

$event 用于在模板中,获取事件的形参

4.代码示例






5.v-model使用在其他表单元素上的原理

不同的表单元素, v-model在底层的处理机制是不一样的。比如给checkbox使用v-model

底层处理的是 checked属性和change事件。

不过咱们只需要掌握应用在文本框上的原理即可

十二、表单类组件封装

1.需求目标

实现子组件和父组件数据的双向绑定 (实现App.vue中的selectId和子组件选中的数据进行双向绑定)

2.代码演示

App.vue






相当于如下代码(简化):







BaseSelect.vue






十三、v-model简化代码

1.目标:

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

2.如何简化:

v-model其实就是 :value和@input事件的简写

  • 子组件:props通过value接收数据,事件触发 input
  • 父组件:v-model直接绑定数据

3.代码示例

子组件


props: {
  value: String
},
methods: {
  handleChange (e) {
    this.$emit('input', e.target.value)
  }
}

父组件


十四、.sync修饰符

1.作用

可以实现 子组件父组件数据双向绑定,简化代码

特点:prop属性名可以自定义,非固定value

简单理解:子组件可以修改父组件传过来的props值

2.场景

封装弹框类的基础组件, visible属性 true显示 false隐藏

3.本质

.sync修饰符 就是 :属性名@update:属性名 合写

4.语法

父组件

//.sync写法

--------------------------------------
//完整写法

子组件

props: {
  visible: Boolean
},

this.$emit('update:visible', false)

5.代码示例

App.vue






BaseDialog.vue





	

6.总结

1.父组件如果想让子组件修改传过去的值 必须加什么修饰符?

2.子组件要修改父组件的props值 必须使用什么语法?

十五、ref和$refs

1.作用

利用ref 和 $refs 可以用于 获取 dom 元素 或 组件实例

2.特点:

查找范围 → 当前组件内(更精确稳定)

3.语法

获取 dom 元素

1.给要获取的盒子添加ref属性

<div ref="chartRef">我是渲染图表的容器div>

2.获取时通过 $refs获取 this.$refs.chartRef 获取

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

获取 组件实例

1.目标组件 - 添加ref属性


2.恰当时机,通过this.$refs.xxx获取目标组件,就可以调用组件对象里面的方法

this.$refs.baseForm.组件方法();

4.注意

之前只用document.querySelect(‘.box’) 获取的是整个页面中的盒子

5.代码示例

App.vue






BaseChart.vue






十六、异步更新 & $nextTick

1.需求

编辑标题, 编辑框自动聚焦

  1. 点击编辑,显示编辑框
  2. 让编辑框,立刻获取焦点

vue-4_第13张图片

2.代码实现



 

3.问题

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

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

4.解决方案

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

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

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

注意:$nextTick 内的函数体 一定是箭头函数,这样才能让函数内部的this指向Vue实例

你可能感兴趣的:(#,VUE,vue.js,前端,javascript)