vue3笔记 - 父子组件通信
父传子
说明:父组件将数据绑定在组件标签上;子组件props
接收
父组件:
<template>
<Child :msg="msg" />
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const msg = ref('hello world')
</script>
子组件,使用defineProps
接收:
<template>
<div>收到父组件传的值:{{ msg }}</div>
</template>
<script setup>
const props = defineProps({
msg: {
type: String
}
})
</script>
子传父
说明:父组件定义自定义事件,绑定在子组件标签上;子组件使用emit
,触发方法、传值
父组件:
<template>
<Child @addCount="addCount" @resetCount="resetCount" />
<div>count: {{ count }}</div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
let count = ref(0)
function addCount(e) {
count.value += e
}
function resetCount() {
count.value = 0
}
</script>
子组件使用defineEmits声明事件:
<template>
<el-button type="primary" @click="addCount">累加count</el-button>
<el-button type="primary" @click="resetCount">重置count</el-button>
</template>
<script setup>
import { defineEmits } from 'vue'
const emit = defineEmits(['addCount', 'resetCount'])
function addCount() {
emit('addCount', 22)
}
function resetCount() {
emit('resetCount')
}
</script>
子组件直接修改父组件传过来的值
父组件:
vue2如果想让子组件能直接修改数据,使用的是.sync
, vue3 使用v-model
<template>
<Child v-model:count="count" />
<div>count: {{ count }}</div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
let count = ref(0)
</script>
子组件:
需要声明一个 update:count
事件
<template>
<el-button type="primary" @click="updateCount">修改count</el-button>
</template>
<script setup>
import { defineEmits } from 'vue'
const props = defineProps({
count: {
type: Number
}
})
const emit = defineEmits(['addCount', 'resetCount', 'update:count'])
function updateCount() {
emit('update:count', 100)
}
</script>
defineExpose
使用<script setup>
的组件,不会暴露任何声明的变量属性,也就是无法向vue2中:this.$refs.child.data
类似这样获取数据
如果想操作,可以使用defineExpose
来显式的指定出,需要暴露出去的属性
父组件:
<template>
<el-button type="warning" @click="getChildVal">获取子组件中的值</el-button>
<div>{{ childMsg }}</div>
<el-button type="primary" @click="runChildFunc">执行子组件的方法</el-button>
<child ref="child" />
</template>
<script setup>
import { ref } from 'vue'
import Child from './child.vue'
// 必须跟子组件 ref 保持一致
const child = ref(null)
const childMsg = ref('')
// 获取子组件的数据
function getChildVal() {
childMsg.value = child.value.msg
}
// 执行子组件的方法
function runChildFunc() {
child.value.testFunc()
}
</script>
子组件需要使用defineExpose
暴露变量和方法:
<template>
<div v-if="isShow">被父组件执行了,你个吊毛</div>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('在座的各位都是辣鸡!!!')
const isShow = ref(false)
const testFunc = function () {
isShow.value = !isShow.value
}
defineExpose({
msg,
testFunc
})
</script>
ref属性
使用ref获取DOM或者组件实例
与vue2写法的区别,vue2中:
this.$refs.child.data
vue3没有this
,需要声明一个 和 标签ref
保持一致的响应式变量,进行操作;如果想获取子组件的数据,可以看上面的defineExpose
- 操作单个组件 或者 DOM
<template>
<child ref="child" />
</template>
<script setup>
import Child from './child.vue'
// 变量名称必须跟子组件 ref 保持一致
const child = ref()
// 如果想获取子组件的数据,可以看上面的defineExpose
console.log(child.value)
console.log(child.value.msg)
</script>
- 操作多个DOM
定义一个函数,动态绑定到ref上即可
<template>
<ul>
<li v-for="item in 10" :ref="setRef">{{ item }}</li>
</ul>
</template>
<script setup>
const setRef = (el) => {
console.log(el)
}
</script>
上面写法不太好区分某个DOM,也可以写成如下:
<template>
<ul>
<li v-for="item in 10" :ref="el => setRef(el, item)">{{ item }}</li>
</ul>
</template>
<script setup>
const setRef = (el, item) => {
console.log(el, item)
}
</script>
本文来自博客园,作者:时光凉忆,转载请注明原文链接:https://www.cnblogs.com/naturl/p/17079867.html