阿里云主机折上折
  • 微信号
Current Site:Index > The triggering conditions for component updates

The triggering conditions for component updates

Author:Chuan Chen 阅读数:33344人阅读 分类: Vue.js

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:

  1. Changes to $attrs
  2. Changes to $slots
  3. Changes to values provided via provide when the child component uses inject

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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.