vue04-组件通信
文章目录
一:组件通信
组件通信,就是指组件与组件之间的数据传递。
- 组件的数据是独立的,无法直接访问其他组件的数据。
- 想用其他组件的数据 -> 组件通信
组件分类关系

对于父子关系的组件:props & $emit
对于非父子关系的组件:provide & inject 或者使用 eventbus
通用的解决方式:Vuex -> 适合复杂的业务场景

1:父子组件通信



prop高级认知

props支持校验
- 类型校验
props: {
校验的属性名:类型 // Number, String, Boolean
}
// 例如
props: {
weight: Number // weight这个属性必须是Number类型的
}
- 非空校验 & 默认值 & 自定义校验
props: {
type: Number, // 类型
required: true, // 是否是必须传递的
default: 0, // 默认值
validator (value) { // 自定义校验,参数是属性的值,然后如果返回true,说明校验成功,否则校验失败
if (value >= 0 && value <= 100) {
return true;
} else {
return false;
}
}
}

2:非父子组件通信
eventbus 事件总线 - 了解

provide & inject -> 了解

二:v-model原理
1:语法糖v-model(基本了解)
v-model = :value + @input
数据 -> :value -> 页面页面 -> @input + $event -> 数据

2:父子组件的通信-表单类组件封装

father.vue
- 定义数据 ->
data() {return }- 通过v-on的方式传递数据给子组件
:子组件的属性名称='父组件的属性名称'- 通过事件监听,监听子组件中数据的变化,然后传递给父组件
@父事件名称="父组件的属性名称 = $event"
<template>
<div>
<!-- :value -> 数据到视图层 -->
<!-- @change -> 视图层到数据层 -->
<select :value="cityId" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
<option value="105">杭州</option>
</select>
</div>
</template>
<script>
export default {
props: {
cityId: {
type: String,
default: ''
}
},
data() {
return {
city: ''
}
},
watch: {
value(val) {
this.city = val
}
},
methods: {
handleChange(e) {
// emit -> 发射
// 发射事件,告诉father组件,修改的新值
this.$emit('input', e.target.value)
}
}
}
</script>
<style lang="scss" scoped>
</style>
son.vue
- export中指定props,完成父组件中的属性 -> 子组件属性的传递(单向流)
- 使用数据
- 定义监听事件,监听数据的变化
@change=事件方法- 定义事件方法,使用
this.$emit('父事件名称', e.target.value)发送更改的结果给到父组件
<template>
<div>
<!-- :value -> 数据到视图层 -->
<!-- @change -> 视图层到数据层 -->
<select :value="cityId" @change="change">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
<option value="105">杭州</option>
</select>
</div>
</template>
<script>
export default {
props: {
cityId: {
type: String,
default: ''
}
},
methods: {
change(e) {
// emit -> 发射
// 发射事件,告诉father组件,修改的新值
this.$emit('changeId', e.target.value)
}
}
}
</script>
<style lang="scss" scoped>
</style>
3:父子通信中v-model的优化(重要)
因为v-model是:value + @input,所以在父组件中可以使用v-model进行简写操作
- 注意在子组件中发射事件的时候,执行父组件的名称是
input,同时子组件的属性名称是value
<template>
<div>
<!-- :value -> 数据到视图层 -->
<!-- @change -> 视图层到数据层 -->
<select :value="value" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
<option value="105">杭州</option>
</select>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
}
},
methods: {
handleChange(e) {
// emit -> 发射
// 发射事件,告诉father组件,修改的新值
this.$emit('input', e.target.value)
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="son">
<!-- 传递给子组件, 子组件的参数名是cityId, 对应父组件的参数是selectId -->
<!-- 监听子组件的changeId事件,并把事件参数赋给selectId -->
<!-- 因为:value + @input 所以直接用v-model简写 -->
<Son v-model="selectId"></Son>
</div>
</template>
<script>
import Son from "@/components/MySon.vue";
export default {
components: {
Son
},
data() {
return {
// 父组件传递给子组件的参数,定义数据
selectId: '102'
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>

4:总结一下

三:.sync修饰符和@update

四:ref & this.$refs
1:获取dom


2:获取组件

五:vue异步更新$nextTick

<template>
<div class="test">
<!-- 是否在编辑状态 -->
<div v-if="isEdit">
<!-- ref -> 声明使用本组件的,和后面的this.$refs搭配 -->
<input ref="inp" v-model="editValue" type="text">
<button>确认</button>
</div>
<div v-else>
<span>{{ title }}</span>
<button @click="handlerEdit">编辑</button>
</div>
</div>
</template>
<script>
export default {
name: 'MyButton',
data() {
return {
isEdit: false,
editValue: '',
title: "我是一个标题"
}
},
methods: {
handlerEdit() {
// 1:显示输入框
this.isEdit = true
// 2:让输入框获取焦点
console.log(this.$refs.inp) // undefined, 因为是异步的,所以需要在nextTick中获取
// 所以使用Vue异步更新this.$nextTick(() => {xxxx})
this.$nextTick(() => {
this.$refs.inp.focus()
})
}
},
}
</script>
<style scoped lang="less">
</style>
2138

被折叠的 条评论
为什么被折叠?



