The new feature of template references (ref) translates this sentence into English.
Template Refs (ref) New Features
Vue.js 3.x has significantly upgraded the template ref functionality, providing more flexible and powerful ways to use refs. These improvements allow developers to manipulate DOM elements and component instances more directly while maintaining Vue's reactivity.
Basic Usage of ref
In Vue 3, refs can be created in two ways:
// Options API
export default {
data() {
return {
myRef: null
}
}
}
// Composition API
import { ref } from 'vue'
const myRef = ref(null)
When used in templates, simply add the ref attribute to an element or component:
<template>
<div ref="myRef">This is a referenceable element</div>
<ChildComponent ref="childComponent" />
</template>
Functional ref
Vue 3 introduces a new functional ref syntax, allowing the use of functions in ref bindings:
<template>
<div :ref="(el) => { divElement = el }">Functional reference</div>
</template>
<script setup>
import { ref } from 'vue'
const divElement = ref(null)
</script>
This approach is particularly useful for dynamically generated refs, such as in v-for loops:
<template>
<div v-for="item in items" :key="item.id" :ref="setItemRef">
{{ item.text }}
</div>
</template>
<script setup>
import { ref, onBeforeUpdate } from 'vue'
const items = ref([/* ... */])
const itemRefs = ref([])
const setItemRef = el => {
if (el) {
itemRefs.value.push(el)
}
}
// Clear the refs array before updates
onBeforeUpdate(() => {
itemRefs.value = []
})
</script>
Using ref on Components
When ref is used on a component, it points to the component instance:
<template>
<ChildComponent ref="child" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
import ChildComponent from './ChildComponent.vue'
const child = ref(null)
onMounted(() => {
// Access child component methods
child.value.someMethod()
// Access child component properties
console.log(child.value.someProperty)
})
</script>
Controlling Exposed Content with expose
Vue 3 introduces the expose option to precisely control what a component exposes:
<!-- ChildComponent.vue -->
<script setup>
import { ref } from 'vue'
const internalState = ref('Private data')
const publicMethod = () => {
console.log('This is a public method')
}
// Only expose publicMethod
defineExpose({
publicMethod
})
</script>
Type Inference for ref with TypeScript
Vue 3 offers better TypeScript support, providing precise type hints for refs:
import { ref } from 'vue'
import type { HTMLInputElement } from 'vue'
const inputRef = ref<HTMLInputElement | null>(null)
onMounted(() => {
if (inputRef.value) {
inputRef.value.focus() // Has correct type hints
}
})
Dynamic Components and ref
Refs on dynamic components behave differently and require special handling:
<template>
<component :is="currentComponent" ref="dynamicComponent" />
</template>
<script setup>
import { ref, shallowRef } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'
const currentComponent = shallowRef(CompA)
const dynamicComponent = ref(null)
// The ref updates automatically when switching components
function toggleComponent() {
currentComponent.value = currentComponent.value === CompA ? CompB : CompA
}
</script>
ref with Custom Directives
Custom directives can also work with refs:
<template>
<div ref="target" v-custom-directive>Directive target</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const target = ref(null)
const vCustomDirective = {
mounted(el) {
console.log('Directive mounted', el === target.value) // true
}
}
</script>
Using ref in Render Functions
In render functions, refs need to be passed as the second argument:
import { h, ref } from 'vue'
const myRef = ref(null)
export default {
setup() {
return () => h('div', { ref: myRef }, 'Reference in render function')
}
}
ref with Teleport Component
Refs in Teleport components point to the teleported DOM element:
<template>
<Teleport to="body">
<div ref="teleported">Element to be teleported to body</div>
</Teleport>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const teleported = ref(null)
onMounted(() => {
console.log(teleported.value.parentNode) // body
})
</script>
Performance Considerations for ref
For large lists, using ref collections may impact performance. Vue provides optimized solutions for ref arrays:
<template>
<div v-for="i in 1000" :key="i" :ref="setRef">Item {{ i }}</div>
</template>
<script setup>
import { ref } from 'vue'
const refs = ref([])
function setRef(el) {
if (el) {
refs.value.push(el)
}
}
</script>
ref and SSR Compatibility
In server-side rendering (SSR) environments, ref behavior requires attention:
<script setup>
import { ref, onMounted } from 'vue'
const clientOnlyRef = ref(null)
onMounted(() => {
// Executes only on the client side
console.log(clientOnlyRef.value)
})
</script>
ref with Suspense Component
In Suspense environments, refs need to wait for async components to resolve:
<template>
<Suspense>
<template #default>
<AsyncComponent ref="asyncComp" />
</template>
</Suspense>
</template>
<script setup>
import { ref } from 'vue'
import AsyncComponent from './AsyncComponent.vue'
const asyncComp = ref(null)
// Needs to wait for Suspense to resolve
</script>
Debugging Tips for ref
During development, refs can be easily debugged:
import { ref } from 'vue'
const debugRef = ref(null)
// Add a watcher to observe ref changes
watch(debugRef, (newVal) => {
console.log('ref value changed:', newVal)
}, { immediate: true })
Integrating ref with Third-Party Libraries
Refs provide convenient integration points with third-party libraries:
<template>
<div ref="chartContainer"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
const chartContainer = ref(null)
onMounted(() => {
const chart = echarts.init(chartContainer.value)
chart.setOption({/* ... */})
})
</script>
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:自定义指令变化