在Vue3 setup中获取 Dom 和 调用子组件方法
获取Dom
<template>
<div class="todo" ref="todoDom"></div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
const todoDom = ref<any>(null);
onMounted(() => {
console.log(todoDom.value);
});
</script>
调用子组件方法
父组件(Todo.vue)
<template>
<div class="todo-list">
<todo-item
:ref="setItemRef"
v-for="(item, index) of todoList"
:key="index"
@click="handleClick(item, index)"
></todo-item>
</div>
</template>
<script lang="ts" setup>
import TodoItem from './TodoItem.vue';
import { ref, nextTick, onBeforeUpdate } from 'vue';
const todoList = [
{ id: 1, name: 'todoItem1' },
{ id: 2, name: 'todoItem2' },
{ id: 3, name: 'todoItem3' },
]
const itemRefs = ref<any>([]); // 储存获取的Dom元素或子组件实例
const setItemRef = (el) => {
if (el) {
itemRefs.value.push(el);
}
};
// 每次更新前把实例清空
onBeforeUpdate(() => {
itemRefs.value = [];
});
const handleClick = (item, index) => {
nextTick(() => {
itemRefs.value[index].changeCircle && itemRefs.value[index].changeCircle();
});
};
</script>
<style>
.todo-list {
display: flex;
}
</style>
子组件(TodoItem.vue)
<template>
<div class="todo-item">
<div class="circle" v-show="circleStatus"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, defineExpose } from 'vue';
const circleStatus = ref<Boolean>(true);
const changeCircle = () => {
circleStatus.value = !circleStatus.value;
};
// 将子组件的方法和属性暴露出去
defineExpose({
circleStatus,
changeCircle,
});
</script>
<style>
.todo-item {
position: relative;
width: 100px;
height: 100px;
background-color: #f5f5f5;
}
.circle {
position: relative;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #f00;
}
</style>