模板:
<tremplate>
<div ref="element"></div>
</template>
脚本:
export default {
setup() {
const element = ref(null);
return {
element,
};
},
};
这是在 vue3 中定义 ref 的正常方法,但是是以 JavaScript 的方式。 如果我使用 TypeScript,我需要为值定义一个类型
element
,对吗?
如何确保值的类型正确
element
?
<template>
<ChildComponent ref="childRef">
</template>
<script lang="ts" setup>
import ChildComponent from './ChildComponent.vue'
import { ref } from 'vue'
const childRef = ref<InstanceType<typeof ChildComponent>>()
childRef.value.childMethods()
</script>
嗯,这取决于您是否需要键入并提供成员信息(公共属性、方法等)。如果你这样做,那么你需要为它定义一个类型;否则,您不必这样做,只需使用
.value
访问未包装的引用,即可将其保留为 any
类型(我打赌您已经找到了这个)。
但是如果必须这样做,您需要告诉编译器它是什么或者它将被分配给什么。为此,您需要使用 ref
HTMLDivElement
(或简单地
HTMLElement
如果您不关心它必须提供的特定成员)。
export default defineComponent({
setup() {
const el = ref<HTMLDivElement>();
onMounted(() => {
el.value // DIV element
});
return {
el
}
}
})
在 JavaScript 中,没有类型检查,因此在 null
函数上传递
ref
与不传递任何内容一样好(这对于模板引用来说尤其没问题)*;从某种意义上说,它甚至可能会被认为具有误导性,因为展开的值实际上解析为其他东西但是
null
。* 使用 Composition API 时,“反应式引用”和“模板引用”的概念是统一的。我们在已安装的钩子上访问这种特定类型的
ref
的原因是因为 DOM 元素将在初始渲染后分配给它。 参考资料:
const el = ref<HTMLDivElement>();
el
不是 HTMLDivElement。相反,它是元素的代理。该代理的
$el
是实际的 HTMLDivElement。虽然我不确定我是否做对了。在组件中,我设法将其键入如下:import { ComponentPublicInstance, defineComponent, ref } from 'vue';
export default defineComponent({
// snipped...
setup() {
const field = ref<ComponentPublicInstance<HTMLInputElement>>();
return {
field,
fun() { field.value.$el.value = 'some value'; }
};
}
// snipped...
});
<template>
<input ref="fileInput" style="display: none;" type="file" @change="onFileSelected" />
<button @click="fileInput?.click()">Pick Files</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const fileInput = ref<HTMLDivElement | null>(null)
function onFileSelected(event: any) { console.log("Event: " + event) }
</script>
<template>
<div ref="coolDiv">Some text</div>
<button @click="changeCoolDiv">Pick Files</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const coolDiv = ref<HTMLDivElement>()
function changeCoolDiv() {
if(coolDiv) {
coolDiv.value // Div element
}
}
</script>
您可以使用VNodeRef。
const swiperRef = ref<VNodeRef>();
使用
<script setup>
的组件默认是关闭的 - 即,通过模板引用或
$parent
链检索的组件的公共实例,不会公开 内部声明的任何绑定。要显式公开组件中的属性,请使用 defineExpose 编译器宏:
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
当父级通过模板引用获取此组件的实例时,检索到的实例将具有
{ a: number, b: number }
的形状(引用会像普通实例一样自动展开)。
示例代码MyModal.vue
:
<script setup lang="ts">
import { ref } from 'vue'
const isContentShown = ref(false)
const open = () => (isContentShown.value = true)
defineExpose({
open
})
</script>
父组件
App.vue
:
<script setup lang="ts">
import MyModal from './MyModal.vue'
const modal = ref<InstanceType<typeof MyModal> | null>(null)
const openModal = () => {
modal.value?.open()
}
</script>
vue-class-component
软件包(这里是 beta v8,但与
@Component
相同,而不是 @Option
将在早期版本中工作):<template>
<div ref="element">
<MyOtherComponent ref="otherComponent" />
</div>
</template>
<script lang="ts">
import { Options, Vue } from 'vue-class-component'
import MyOtherComponent from '../MyOtherComponent.vue'
@Options({
components: {
MyOtherComponent,
},
})
export default class MyComponent extends Vue {
$refs!: {
element: HTMLDivElement,
otherComponent: InstanceType<typeof MyOtherComponent>,
}
mounted() {
this.$refs.otherComponent.myOtherComponentMethod()
}
}
</script>
,在 Ref
中使用类型
vue
示例:
import type { Ref } from 'vue'
name: Ref<string> = ref()
interface IUser {
name: string,
sex: string
}
user: Ref<IUser> = ref({
name: '',
sex: ''
})