The triggering conditions for component updates
Conditions for Triggering Component Updates
Vue3's component update mechanism relies on the reactivity system. When reactive data changes, it triggers a re-render of the component. Understanding the conditions for triggering component updates is crucial for mastering Vue3's underlying principles.
Reactive Data Changes
Vue3 uses Proxy to implement its reactivity system. When a property of a reactive object is modified, it triggers updates for components that depend on that property. For example:
const state = reactive({ count: 0 })
// Modifying count will trigger updates for components that depend on it
state.count++
For reactive variables created with ref
, modifying their value
property also triggers updates:
const count = ref(0)
// Modifying value will trigger updates
count.value++
Props Changes
When the props passed from a parent component to a child component change, the child component will update. Vue3 performs a shallow comparison of props and only triggers updates if the current props are not equal to the previous props.
// Parent component
<Child :count="parentCount" />
// Child component
export default {
props: ['count'],
setup(props) {
// When parentCount changes, props.count will update
}
}
Slot Content Changes
When the slot content passed from a parent component to a child component changes, the child component will also update:
// Parent component
<Child>
<template #default>
{{ dynamicContent }}
</template>
</Child>
// When dynamicContent changes, the Child component will update
Forced Updates
Although not recommended, you can force a component to update using the forceUpdate
method:
import { getCurrentInstance } from 'vue'
export default {
setup() {
const instance = getCurrentInstance()
const handleForceUpdate = () => {
instance.proxy.$forceUpdate()
}
return { handleForceUpdate }
}
}
Asynchronous Update Queue
Vue3's updates are asynchronous, bundling multiple data changes into a single update cycle. This means that multiple modifications to reactive data within the same event loop will only trigger one component update:
const state = reactive({ count: 0 })
// Only triggers one update
state.count++
state.count++
state.count++
Computed Properties and Watchers
When the value of a computed property changes, it triggers updates for components that depend on that computed property:
const state = reactive({ a: 1, b: 2 })
const sum = computed(() => state.a + state.b)
// Modifying state.a or state.b will cause sum to recompute
// If the value of sum changes, components that depend on it will update
Watchers do not directly trigger component updates, but they can indirectly trigger updates by modifying other reactive data in their callbacks:
watch(
() => state.count,
(newVal) => {
// You can modify other reactive data here to trigger updates
otherState.value = newVal * 2
}
)
Component Instance Updates
Updates are also triggered when certain specific properties of a component instance change:
- Changes to
$attrs
- Changes to
$slots
- Changes to values provided via
provide
when the child component usesinject
Conditional Rendering and List Rendering
Changes to elements controlled by v-if
and v-for
directives will also trigger updates for related components:
// When show changes, it will trigger the creation/destruction or update of the Child component
<Child v-if="show" />
// When list changes, it will trigger updates for list items
<div v-for="item in list" :key="item.id">{{ item.text }}</div>
Custom Directive Updates
If a component uses a custom directive, changes to the directive's bound value will trigger the update
hook, which may also cause the component to update:
// Custom directive
app.directive('highlight', {
updated(el, binding) {
// Executed when binding.value changes
el.style.backgroundColor = binding.value
}
})
// Using the directive
<div v-highlight="color"></div>
// When color changes, it will trigger the update hook
Lifecycle Hook Updates
Modifying reactive data in certain lifecycle hooks will trigger additional updates:
export default {
setup() {
const count = ref(0)
onMounted(() => {
// This will trigger an additional update
count.value++
})
return { count }
}
}
Global State Management
When using state management libraries like Pinia or Vuex, changes to the state will also trigger updates for components that depend on that state:
// Using Pinia
import { useStore } from '@/stores/counter'
export default {
setup() {
const store = useStore()
// When store.count changes, the component will update
return { count: store.count }
}
}
Functional Component Updates
Functional components do not have instances; their updates depend entirely on changes to props:
// Functional component
const FunctionalComponent = (props) => {
return h('div', props.text)
}
// Only re-renders when props.text changes
Render Function Updates
Components created using render functions or the h
function have the same update conditions as components compiled from templates:
export default {
render() {
// The render function re-executes when reactive data changes
return h('div', this.count)
},
data() {
return { count: 0 }
}
}
Async Component Updates
Async components trigger updates once they are loaded, after which they behave like regular components:
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
)
// Triggers an update once the async component is loaded
keep-alive Component Updates
Components cached by keep-alive
trigger the activated
hook when reactivated but do not undergo a full re-render:
<keep-alive>
<component :is="currentComponent" />
</keep-alive>
// When switching currentComponent, cached components are not recreated
// But the activated hook is triggered
Error Boundary Updates
When an error is caught by an error boundary, it triggers updates for the error boundary component:
<ErrorBoundary>
<ChildThatMightError />
</ErrorBoundary>
// When ChildThatMightError throws an error
// ErrorBoundary updates its state and re-renders
Transition Effect Updates
When using the transition
component, enter/leave transition effects also trigger updates for related components:
<transition>
<div v-if="show">Content</div>
</transition>
// When show changes, transition effects are triggered
// This involves component updates and DOM operations
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn