vue3父子组件同步数据

vue3父子组件同步数据
1.props验证
1.1什么是props验证

指的是:在封装组件时 对外界传递过来的props数据 进行合法性的校验,从而防止数据不合法的问题。

1.2对象类型的props节点

使用对象类型的props节点,可以对每个prop进行 数据类型的校验

对象类型的props节点提供了多种数据验证方案,例如:

  1. 基础的类型检查
  2. 多个可能的类型
  3. 必填项校验
  4. 属性默认值
  5. 自定义验证函数

基础类型的检查:

可以直接为组件的prop属性指定 基础的校验类型,从而防止 组件的使用者 为其绑定 错误类型的数据:

export default {
  props: {  // 支持的 8 种基础类型
  	propA: String,
  	propB: Number,
  	propC: Boolean,
  	propD: Array,
  	propE: Object,
  	propF: Date,
  	propG: Function, // 函数类型
  	propH: Symbol // 符号类型
  }
}

多个可能的类型:

如果某个prop属性值的 类型不唯一,此时可以通过数组的形式,为其指定多个可能的类型,示例代码如下:

export default {
  props: {
  	// propA 属性的值可以是 “字符串” 或 “数字”
  	propA: [String,Number]
  }
}

必填项校验:

export default {
  props: {
  	// 通过 “配置对象” 的形式,来定义 propB 属性的 “验证规则”
  	propB: String, // 当前属性的值必须是 String 字符串类型
  	required: true // 当前属性的值是必填项,如果使用者没指定 propB 属性的值,则在终端进行警告提示
  }
}

属性默认值:

在封装组件时,可以为某个prop属性 指定默认值,实力代码如下:

export default {
  props: {
  	// 通过 “配置对象” 的形式,来定义 propB 属性的 “验证规则”
  	propC: {
  	  type: Number,
  	  default: 100 // 如果使用者没有指定 propC的值,则 propC属性的默认值为100
  	}
  }
}

自定义验证函数:

在封装组件时,可以为prop属性指定 自定义的验证函数,从而对prop属性的值进行更加精确的控制:

export default {
  props: {
  	// 通过 “配置对象” 的形式,来定义 propB 属性的 “验证规则”
  	propD: {
  	  // 通过 validator 函数,对 propD 属性的值进行校验,“属性的值”可以通过形参 value 进行接收
  	  validator(value) {
  	    // propD 属性的值,必须匹配下列字符串中的一个
  	    // validator 函数的返回值为 true 表示验证通过,false表示验证失败
  	    return['success','warning','danger'].indexOf(value) !== -1
  	  }
  	}
  }
}
2.计算属性
2.1什么是计算属性

计算属性 本质上 就是一个 function函数,它可以 实时监听 打他钟数据都变化,并 return一个计算后的新值,供组件渲染DOM时使用。

2.2如何声明计算属性

计算属性需要以 function函数 的形式声明到组件的 computed选项中,示例代码如下:

<input type="text" v-model.number="count">
<p>{{ count }} 乘以 2 的值为: {{ plus }}</p>

data() {
  return { count:1 }
},
computed: {
  plus() { // 计算属性:监听 data 中 count,自动计算出 count * 2 之后的值
	return this.count * 2
  }
}

**注意:**计算属性 侧重于 得到一个 计算得结果,因此计算属性中 必须有return返回值!

2.3计算属性使用的注意点
  1. 计算属性 必须定义在computed节点中
  2. 计算属性 必须是一个function函数
  3. 计算属性 必须有返回值
  4. 计算属性 必须当做普通属性使用
2.4计算属性 vs 方法

相对于方法来说,计算属性会缓存计算的结果,只有计算属性的 依赖项发生变化 时,才会 重新进行运算。因此,计算属性的性能更好:

computed: {
  plus() { // 计算属性的计算结果会被缓存,性能好
	console.log("计算属性被执行啦")
	return this.count * 2
 }
}
methods: {
  plus() { // 方法的计算结果无法被缓存,性能低
	console.log("方法被执行啦")
	return this.count * 2
 }
}
3.自定义事件
3.1什么是自定义事件

在封装组件时,为了让 组件的使用者 可以 监听到组件内状态的变化,此时需要用到 组件的自定义事件。

3.2自定义事件的3个使用步骤

在封装组件时:

  1. 声明 自定义事件
  2. 触发 自定义事件

在使用组件时:

​ 3.监听自定义事件

声明自定义事件

开发者为自定义组件封装的自定义事件,必须事先在 emits 节点中声明,示例代码如下:

<template>
  <h3>Counter组件</h3>
  <button>+1</button>
</template>
<script>
  export default {
    // my-counter 组件的自定义事件,必须事先声明到 emits节点中
    emits: ['change']
  }
</script>

触发自定义事件

在 emits 节点下声明的自定义事件,可以通过 this.$emit(‘自定义事件的名称’)方法进行触发,示例代码如下:

<template>
  <h3>Counter组件</h3>
  <button @click="onBtnClick">+1</button>
</template>
<script>
  export default {
    // my-counter 组件的自定义事件,必须事先声明到 emits节点中
    emits: ['change'],
    methods: {
      onBtnClick() {
        this.$emit('change') // 当点击 +1 按钮时,调用this.$emit()方法,触发自定义的change事件
      }
    }
  }
</script>

监听自定义事件

在使用自定义的组件时,可以通过 v-on 的形式 监听自定义事件。示例代码如下:

<!-- 使用 v-on 指定绑定事件监听 -->
<my-counter @change="getCount"></my-counter>

methods: {
  getCount() {
	console.log('监听到了 count 值的变化')
  }
}
3.3自定义事件传参(子传父)

在调用 this.$emit() 方法触发自定义事件时,可以通过 第2个参数 为自定义事件传参,示例代码如下:

<template>
  <h3>Counter组件</h3>
  <button @click="onBtnClick">+1</button>
</template>
<script>
  export default {
    emits: ['change'],
    methods: {
      onBtnClick() {
        this.$emit('change',this.count) // 触发自定义事件时,通过第二个参数传参
      }
    }
  }
</script>
4.组件上的 v-model
4.1为什么需要在组件上使用 v-model

v-model 是双向数据绑定指令,当 需要维护组件内外数据的同步 时,可以在组件上使用v-model指令。

4.2在组件上使用v-model的步骤

父向子同步数据

在这里插入图片描述

  1. 父组件通过v-bind: 属性绑定的形式,把数据传递给子组件
  2. 子组件中,通过 props 接收父组件传递过来的数据

子向父同步数据

在这里插入图片描述

  1. 在v-bind: 指令之前添加 v-model 指令
  2. 在子组件中声明 emits 自定义事件,格式为 update:xxx
  3. 调用 $emit() 触发自定义事件,更新父组件中的数据

子组件

<template>
  <div>
     <p>count值是:{{ number }}</p>
     <button @click="add">+1</button>
  </div>
</template>
<script>
  export default {
    name: 'MyCounter',
    props: ['number'],
    emits: ['update:number'],
    methods: {
      add() {
        this.$emit('update:number',this.number + 1)
      }
    }
  }
</script>

父组件:

<template>
  <div>
    <h1>App根组件  ---  {{ count }}</h1>
    <my-counter v-model:number="count"></my-counter>
  </div>
</template>
<script>
  import MyCounter from './Counter.vue'
  export default {
    name: 'MyCounter',
    data() {
      return: {
        count: 0,
      }
    }
  }
</script>

了解父子组件同步数据特别特别特别重要!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值