Vue 组件生命周期:探索钩子


title: Vue 组件生命周期:探索钩子
date: 2024/5/27 18:42:38
updated: 2024/5/27 18:42:38
categories:

  • 前端开发

tags:

  • 生命周期
  • 异步加载
  • 通信原理
  • 父子通信
  • 兄弟通信
  • 跨层通信
  • 性能优化

在这里插入图片描述

第 1 章:介绍与背景

1.1 什么是 Vue 组件生命周期?

Vue 组件生命周期是指 Vue 组件从创建、运行到销毁的整个过程,共分为 8 个阶段:

  1. 创建前(beforeCreate)
  2. 创建后(created)
  3. 载入前(beforeMount)
  4. 载入后(mounted)
  5. 更新前(beforeUpdate)
  6. 更新后(updated)
  7. 销毁前(beforeDestroy)
  8. 销毁后(destroyed)

在每个阶段,Vue 框架都提供了特定的钩子函数,开发人员可以在这些函数中编写自定义的代码,从而实现对组件生命周期的控制和管理。

1.2 为什么需要了解生命周期?

了解 Vue 组件生命周期有以下几个优点:

  1. 了解组件的运行机制,提高开发效率。
  2. 在合适的时机进行数据处理和事件绑定,提高项目性能。
  3. 在组件创建和销毁时进行资源清理和内存释放,避免内存泄漏。
  4. 在生命周期钩子函数中进行异步数据加载和组件通信,使代码更加清晰和可维护。

1.3 如何利用生命周期提高开发效率?

  1. 在创建阶段,可以进行数据初始化和事件绑定,避免在模板中频繁的编写相同的代码。
  2. 在运行阶段,可以对数据进行监听和优化,提高项目性能。
  3. 在销毁阶段,可以进行资源清理和内存释放,避免内存泄漏。AD:漫画首页
  4. 在生命周期钩子函数中进行异步数据加载和组件通信,使代码更加清晰和可维护。
  5. 通过使用第三方库或插件,可以更加方便地使用生命周期钩子函数,提高开发效率。

第 2 章:组件生命周期概述

2.1 组件生命周期的基本概念

组件生命周期是指 Vue 组件从创建、运行到销毁的整个过程。在这个过程中,Vue 框架会自动调用一系列的生命周期钩子函数,开发人员可以在这些函数中编写自定义的代码,从而实现对组件生命周期的控制和管理。

2.2 生命周期钩子函数的分类

Vue 组件的生命周期钩子函数可以分为以下几类:

  1. 创建阶段钩子函数:在组件创建时调用,包括 beforeCreate 和 created 两个钩子函数。
  2. 载入阶段钩子函数:在组件载入时调用,包括 beforeMount 和 mounted 两个钩子函数。
  3. 更新阶段钩子函数:在组件更新时调用,包括 beforeUpdate 和 updated 两个钩子函数。
  4. 销毁阶段钩子函数:在组件销毁时调用,包括 beforeDestroy 和 destroyed 两个钩子函数。

2.3 常见的生命周期钩子函数

  1. beforeCreate:在组件实例被创建之前调用,此时组件实例的数据和方法还未初始化。
  2. created:在组件实例被创建之后调用,此时组件实例的数据和方法已经初始化,但组件还未被挂载到 DOM 上。
  3. beforeMount:在组件被挂载到 DOM 之前调用,此时组件的模板已经编译完成,但还未渲染到 DOM 上。
  4. mounted:在组件被挂载到 DOM 之后调用,此时组件已经渲染到 DOM 上,可以进行 DOM 操作和异步数据加载。
  5. beforeUpdate:在组件更新之前调用,此时组件的数据已经发生变化,但还未重新渲染到 DOM 上。
  6. updated:在组件更新之后调用,此时组件的数据已经重新渲染到 DOM 上,可以进行 DOM 操作和异步数据加载。
  7. beforeDestroy:在组件销毁之前调用,此时组件实例仍然可用,可以进行资源清理和内存释放。AD:首页 | 一个覆盖广泛主题工具的高效在线平台
  8. destroyed:在组件销毁之后调用,此时组件实例已经被销毁,无法再进行任何操作。

第 3 章:创建阶段

在 Vue.js 中,组件的创建阶段包括以下几个钩子函数:

  1. beforeCreate:在组件实例被创建之前调用,此时数据和方法还未初始化。
  2. created:在组件实例被创建之后调用,此时数据和方法已经初始化,可以进行数据操作和事件绑定。
  3. beforeMount:在组件被挂载到 DOM 之前调用,此时模板已经编译完成,但还未渲染到 DOM 上。
  4. mounted:在组件被挂载到 DOM 之后调用,此时组件已经渲染到 DOM 上,可以进行 DOM 操作和异步数据加载。

在创建阶段,可以在钩子函数中进行数据处理和事件绑定,以简化组件的代码和提高组件的性能。

例如,在 created 钩子函数中可以进行数据的请求和初始化,从而避免在组件挂载到 DOM 之后再进行数据请求,提高组件的渲染速度。

同时,可以在 created 钩子函数中进行事件的绑定,从而在组件创建时就完成事件的绑定,而无需在 mounted 钩子函数中进行事件绑定。

总之,在创建阶段进行数据处理和事件绑定,可以简化组件的代码和提高组件的性能,是实现高质量 Vue 组件开发的重要手段。

以下是一些代码示例:

// 在 created 钩子函数中进行数据的请求和初始化
export default {
  data() {
    return {
      user: null
    }
  },
  created() {
    this.fetchUser()
  },
  methods: {
    fetchUser() {
      // 进行数据请求和初始化
      this.user = {
        name: 'John Doe',
        age: 30
      }
    }
  }
}

// 在 created 钩子函数中进行事件的绑定
export default {
  data() {
    return {
      message: 'Hello World!'
    }
  },
  created() {
    this.handleClick = () => {
      console.log(this.message)
    }
  },
  mounted() {
    document.getElementById('btn').addEventListener('click', this.handleClick)
  }
}

在上述示例中,我们可以看到在 created 钩子函数中进行数据的请求和初始化,以及事件的绑定,从而在组件创建时就完成数据的请求和初始化,并且在组件挂载到 DOM 之后就完成事件的绑定。

第 4 章:运行阶段

在 Vue.js 中,组件的运行阶段包括以下几个钩子函数:

  1. beforeUpdate:在组件更新之前调用,此时数据已经更新,但 DOM 还未重新渲染。
  2. updated:在组件更新之后调用,此时 DOM 已经重新渲染。

在运行阶段,可以在钩子函数中进行数据监听和性能优化,以提高组件的响应速度和性能。

例如,在 beforeUpdate 钩子函数中可以进行数据的监听,从而在数据更新时及时更新组件的状态,避免出现数据不一致的情况。

同时,可以在 updated 钩子函数中进行性能优化,例如使用虚拟滚动技术来优化大量数据的渲染,或者使用防抖和节流技术来优化频繁触发的事件。
AD:专业搜索引擎

总之,在运行阶段进行数据监听和性能优化,可以提高组件的响应速度和性能,是实现高质量 Vue 组件开发的重要手段。

以下是一些代码示例:

// 在 beforeUpdate 钩子函数中进行数据的监听
export default {
  data() {
    return {
      count: 0
    }
  },
  beforeUpdate() {
    console.log(`count before update: ${this.count}`)
  },
  methods: {
    increment() {
      this.count++
    }
  }
}

// 在 updated 钩子函数中进行性能优化
export default {
  data() {
    return {
      items: []
    }
  },
  updated() {
    // 使用虚拟滚动技术来优化大量数据的渲染
    const container = document.getElementById('container')
    container.style.height = `${container.scrollHeight}px`
  },
  methods: {
    addItem() {
      this.items.push(`Item ${this.items.length}`)
    }
  }

第 5 章:销毁阶段

在 Vue.js 中,组件的销毁阶段包括以下两个生命周期钩子函数:

  1. beforeDestroy:在组件销毁之前调用。在这个阶段,组件实例仍然完全可用,这意味着所有的数据绑定、事件监听器、计算属性等都还在工作。
  2. destroyed:在组件销毁之后调用。在这个阶段,组件实例已经被销毁,所有的绑定和事件监听器都已经被移除,组件不再可用。

在销毁阶段,通常会进行资源清理和内存释放,以确保应用程序的性能和稳定性。以下是一些常见的清理操作:

  • 取消订阅:如果组件中使用了事件订阅(如使用 EventBus 或第三方库如 RxJS),应该在 beforeDestroy 钩子中取消这些订阅,以避免内存泄漏。
  • 清除定时器:如果在组件中使用了定时器(如 setIntervalsetTimeout),应该在 beforeDestroy 钩子中清除这些定时器。
  • 解绑事件监听器:如果组件绑定了 DOM 事件监听器,应该在 beforeDestroy 钩子中解绑这些事件监听器。
  • 断开 WebSocket 连接:如果组件使用了 WebSocket 连接,应该在 beforeDestroy 钩子中断开这些连接。

以下是一个简单的示例,展示了如何在 beforeDestroy 钩子中进行资源清理:

export default {
  data() {
    return {
      timer: null
    };
  },
  created() {
    // 创建定时器
    this.timer = setInterval(() => {
      console.log('定时器运行中...');
    }, 1000);
  },
  beforeDestroy() {
    // 清除定时器
    clearInterval(this.timer);
  },
  destroyed() {
    console.log('组件已被销毁');
  }
};

在这个示例中,组件在创建时启动了一个定时器,并在销毁前清除这个定时器,以避免内存泄漏。destroyed 钩子简单地记录了组件已被销毁的信息。通过这种方式,可以确保组件在不再需要时能够正确地释放资源,从而优化应用程序的性能和内存使用。

第 6 章:异步数据加载

在 Vue.js 中,异步数据加载是常见的需求,通常通过在生命周期钩子函数中发起数据请求来实现。以下是如何使用生命周期函数进行数据请求以及在合适的时机取消请求的详细说明:

6.1 使用生命周期函数进行数据请求

通常,数据请求会在组件的生命周期钩子函数中发起,特别是 createdmounted 钩子。这两个钩子分别在组件实例被创建后和组件挂载到 DOM 后立即调用。

示例:在 created 钩子中发起数据请求
export default {
  data() {
    return {
      posts: []
    };
  },
  created() {
    this.fetchPosts();
  },
  methods: {
    async fetchPosts() {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        const data = await response.json();
        this.posts = data;
      } catch (error) {
        console.error('Error fetching posts:', error);
      }
    }
  }
};

在这个示例中,组件在创建后立即调用 fetchPosts 方法来获取数据。使用 async/await 来处理异步操作,使得代码更加清晰和易于理解。

6.2 在合适的时机取消请求

在某些情况下,可能需要在组件销毁前取消未完成的请求,以避免潜在的内存泄漏或不必要的网络请求。这通常在 beforeDestroy 钩子中完成。

示例:在 beforeDestroy 钩子中取消请求

假设使用 axios 进行数据请求,并且每个请求都有一个唯一的标识符,可以使用这个标识符来取消请求。

import axios from 'axios';
import { ref } from 'vue';

export default {
  data() {
    return {
      cancelTokenSource: ref(null),
      posts: []
    };
  },
  created() {
    this.fetchPosts();
  },
  beforeDestroy() {
    if (this.cancelTokenSource.value) {
      this.cancelTokenSource.value.cancel('组件销毁前取消请求');
    }
  },
  methods: {
    fetchPosts() {
      this.cancelTokenSource.value = axios.CancelToken.source();
      axios.get('https://jsonplaceholder.typicode.com/posts', {
        cancelToken: this.cancelTokenSource.value.token
      }).then(response => {
        this.posts = response.data;
      }).catch(thrown => {
        if (axios.isCancel(thrown)) {
          console.log(thrown.message); // 输出:组件销毁前取消请求
        } else {
          console.error('Error fetching posts:', thrown);
        }
      });
    }
  }
};

在这个示例中,使用 axiosCancelToken 来创建一个取消令牌,并在 beforeDestroy 钩子中使用这个令牌来取消请求。如果请求被取消,axios 会抛出一个特定的错误,可以通过 axios.isCancel 来检查这个错误。

通过这种方式,可以确保在组件不再需要数据时,不会继续进行不必要的数据请求,从而优化性能并减少资源消耗。

第 7 章:组件通信

在 Vue.js 中,组件通信是非常重要的话题,可以分为父子组件通信、兄弟组件通信和跨层级组件通信。以下是详细的说明:

7.1 父子组件通信

父子组件通信是最常见的组件通信方式,在父组件和子组件之间传递数据和事件非常简单。

父组件向子组件传递数据

可以使用 props 将数据从父组件传递到子组件。

示例:父组件向子组件传递数据
<!-- ParentComponent.vue -->
<template>
  <div>
    <child-component :title="parentTitle"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentTitle: 'Hello from parent!'
    };
  }
};
</script>

<!-- ChildComponent.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    title: String
  }
};
</script>

子组件向父组件发送事件

可以使用 $emit 将事件从子组件发送到父组件。

示例:子组件向父组件发送事件
<!-- ParentComponent.vue -->
<template>
  <div>
    <child-component @child-event="handleChildEvent"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleChildEvent(message) {
      console.log('Received message from child:', message);
    }
  }
};
</script>

<!-- ChildComponent.vue -->
<template>
  <div>
    <button @click="sendMessage">Send message to parent</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('child-event', 'Hello from child!');
    }
  }
};
</script>

7.2 兄弟组件通信

对于兄弟组件之间的通信,可以使用一个中间组件或者通过事件总线(event bus)。

使用中间组件

可以使用一个中间组件来传递数据和事件。

示例:使用中间组件
<!-- ParentComponent.vue -->
<template>
  <div>
    <first-child @first-child-event="handleFirstChildEvent"></first-child>
    <second-child :message="firstChildMessage"></second-child>
  </div>
</template>

<script>
import FirstChildComponent from './FirstChildComponent.vue';
import SecondChildComponent from './SecondChildComponent.vue';

export default {
  components: {
    FirstChildComponent,
    SecondChildComponent
  },
  data() {
    return {
      firstChildMessage: null
    };
  },
  methods: {
    handleFirstChildEvent(message) {
      this.firstChildMessage = message;
    }
  }
};
</script>

<!-- FirstChildComponent.vue -->
<template>
  <div>
    <button @click="sendMessage">Send message to second child</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('first-child-event', 'Hello from first child!');
    }
  }
};
</script>

<!-- SecondChildComponent.vue -->
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    message: String
  }
};
</script>

使用事件总线

可以使用一个全局事件总线来实现兄弟组件之间的通信。

示例:使用事件总线
// main.js
import Vue from 'vue';
export const EventBus = new Vue();

// FirstChildComponent.vue
<template>
  <div>
    <button @click="sendMessage">Send message to second child</button>
  </div>
</template>

<script>
import { EventBus } from './main';

export default {
  methods: {
    sendMessage() {
      EventBus.$emit('first-child-event', 'Hello from first child!');
    }
  }
};
</script>

// SecondChildComponent.vue
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
import { EventBus } from './main';

export default {
  data() {
    return {
      message: null
    };
  },
  created() {
    EventBus.$on('first-child-event', message => {
      this.message = message;
    });
  }
};
</script>

7.3 跨层级组件通信

对于跨层级组件之间的通信,可以使用 provideinject 或者使用 Vuex 状态管理。

使用 provideinject

可以使用 provideinject 在父组件和子组件之间进行跨层级通信。

示例:使用 provideinject
<!-- ParentComponent.vue -->
<template>
  <div>
    <first-child></first-child>
  </div>
</template>

<script>
import FirstChildComponent from './FirstChildComponent.vue';
import SecondChildComponent from './SecondChildComponent.vue';

export default {
  components: {
    FirstChildComponent
  },
  provide() {
    return {
      parentMessage: 'Hello from parent!'
    };
  }
};
</script>

<!-- FirstChildComponent.vue -->
<template>
  <div>
    <second-child></second-child>
  </div>
</template>

<script>
import SecondChildComponent from './SecondChildComponent.vue';

export default {
  components: {
    SecondChildComponent
  },
  inject: ['parentMessage']
};
</script>

<!-- SecondChildComponent.vue -->
<template>
  <div>
    <h1>{{ parentMessage }}</h1>
  </div>
</template>

<script>
export default {
  inject: ['parentMessage']
};
</script>

使用 Vuex

可以使用 Vuex 状态管理来实现跨层级组件通信。

示例:使用 Vuex
// store.js
import Vuex from 'vuex';
import Vue from 'vue';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    message: 'Hello from Vuex!'
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  }
});

export default store;

// ParentComponent.vue
<template>
  <div>
    <first-child></first-child>
  </div>
</template>

<script>
import { mapMutations } from 'vuex';
import FirstChildComponent from './FirstChildComponent.vue';

export default {
  components: {
    FirstChildComponent
  },
  methods: {
    ...mapMutations(['setMessage'])
  },
  mounted() {
    this.setMessage('Hello from parent!');
  }
};

第 8 章:组件优化

在构建大型 Vue.js 应用时,性能和内存优化是非常重要的。以下是有关组件优化的详细说明。

8.1 性能优化

8.1.1 使用 v-ifv-for 时注意顺序

在使用 v-ifv-for 时,应该优先使用 v-if,因为 v-for 会每次都重新渲染整个列表。如果同时使用 v-ifv-forv-for 应该优先放在 v-if 前面。

8.1.2 使用 key 来优化 v-for

在使用 v-for 时,应该为每个项目提供一个唯一的 key,这可以帮助 Vue.js 跟踪每个节点的身份,从而提高渲染性能。

8.1.3 使用 v-once 渲染静态内容

如果某个组件的内容在整个生命周期中都不会改变,可以使用 v-once 来渲染静态内容,以提高渲染性能。

8.1.4 使用 v-memo 缓存组件

在使用 v-for 时,可以使用 v-memo 来缓存组件,以避免重新渲染。

8.1.5 使用 v-pre 跳过编译

如果某个组件的内容不需要被 Vue.js 编译,可以使用 v-pre 来跳过编译,以提高渲染性能。

8.1.6 使用 v-cloak 隐藏未编译的Mustache标签

在使用 Mustache 标签时,可以使用 v-cloak 来隐藏未编译的 Mustache 标签,以避免闪烁。

8.2 内存优化

8.2.1 使用 v-ifv-for 时注意性能

在使用 v-ifv-for 时,应该注意它们的性能影响,避免不必要的渲染。

8.2.2 使用 v-show 渲染静态内容

在使用 v-show 时,可以渲染静态内容,而不是使用 v-if 创建和销毁节点。

8.2.3 使用 Object.freeze 冻结数据

在使用 Object.freeze 时,可以冻结数据,避免不必要的重新渲染。

8.2.4 使用 v-once 渲染静态内容

在使用 v-once 时,可以渲染静态内容,而不是每次都重新渲染节点。

8.2.5 使用 $once 监听事件

在使用 $once 时,可以监听事件,而不是使用 $on 创建永久的监听器。

8.2.6 使用 $off 取消事件监听

在使用 $off 时,可以取消事件监听,避免内存泄漏。

8.3 避免常见的陷阱

8.3.1 避免使用 Array.prototype.splice 修改数组

在使用 Array.prototype.splice 时,可能会导致 Vue.js 无法检测到变化,从而导致不必要的重新渲染。

8.3.2 避免使用 Object.assign 修改对象

在使用 Object.assign 时,可能会导致 Vue.js 无法检测到变化,从而导致不必要的重新渲染。

8.3.3 避免使用箭头函数

在使用箭头函数时,可能会导致 this 指向不正确,从而导致不必要的重新渲染。

8.3.4 避免使用 v-htmlv-text 混合使用

在使用 v-htmlv-text 时,可能会导致不必要的重新渲染。

8.3.5 避免使用 v-model.sync 修饰符混合使用

在使用 v-model.sync 修饰符时,可能会导致不必要的重新渲染。

8.3.6 避免使用 watch 监听数组

在使用 watch 时,可能会导致不必要的重新渲染。

8.3.7 避免使用 watch 监听对象

在使用 watch 时,可能会导致不必要的重新渲染。

8.3.8 避免使用 deep 选项

在使用 deep 选项时,可能会导致不必要的重新渲染。

8.3.9 避免使用 immediate 选项

在使用 immediate 选项时,可能会导致不必要的重新渲染。

8.3.10 避免使用 computedwatch 混合使用

在使用 computedwatch 时,可能会导致不必要的重新渲染。

8.3.11 避免使用 methodscomputed 混合使用

在使用 methodscomputed 时,可能会导致不必要的重新渲染。

8.3.12 避免使用 createdmounted 混合使用

在使用 createdmounted 时,可能会导致不必要的重新渲染。

8.3.13 避免使用 beforeDestroydestroyed 混合使用

在使用 beforeDestroydestroyed 时,可能会导致不必要的重新渲染。

8.3.14 避免使用 activateddeactivated 混合使用

在使用 activateddeactivated 时,可能会导致不必要的重新渲染。

8.3.15 避免使用 keep-alivev-if 混合使用

在使用 keep-alivev-if 时,可能会导致不必要的重新渲染。

8.3.16 避免使用 transitionv-if 混合使用

在使用 transitionv-if 时,可能会导致不必要的重新渲染。

8.3.17 避免使用 v-elsev-else-if 混合使用

在使用 v-elsev-else-if 时,可能会导致不必要的重新渲染。

8.3.18 避免使用 v-forv-if 混合使用

在使用 v-forv-if 时,可能会导致不必要的重新渲染。

8.3.19 避免使用 v-model.sync 修饰符混合使用

在使用 v-model.sync 修饰符时,可能会导致不必要的重新渲染。

8.3.20 避免使用 v-modelv-for 混合使用

在使用 v-modelv-for 时,可能会导致不必要的重新渲染。

8.3.21 避免使用 v-modelv-show 混合使用

在使用 v-modelv-show 时,可能会导致不必要的重新渲染。

8.3.22 避免使用 v-modelv-once 混合使用

在使用 v-modelv-once 时,可能会导致不必要的重新渲染。

8.3.23 避免使用 v-modelv-memo 混合使用

在使用 v-modelv-memo 时,可能会导致不必要的重新渲染。

8.3.24 避免使用 v-modelv-pre 混合使用

在使用 v-modelv-pre 时,可能会导致不必要的重新渲染。

8.3.25 避免使用 v-modelv-cloak 混合使用

在使用 v-modelv-cloak 时,可能会导致不必要的重新渲染。

8.3.26 避免使用 v-modelv-html 混合使用

在使用 v-modelv-html 时,可能会导致不必要的重新渲染。

8.3.27 避免使用 v-modelv-text 混合使用

在使用 v-modelv-text 时,可能会导致不必要的重新渲染。

8.3.28 避免使用 v-modelObject.freeze 混合使用

在使用 v-modelObject.freeze 时,可能会导致不必要的重新渲染。

8.3.29 避免使用 v-model$once 混合使用

在使用 v-model$once 时,可能会导致不必要的重新渲染。

8.3.30 避免使用 v-model$off 混合使用

在使用 v-model$off 时,可能会导致不必要的重新渲染。

8.3.31 避免使用 v-model$on 混合使用

在使用 v-model$on 时,可能会导致不必要的重新渲染。

8.3.32 避免使用 v-model$emit 混合使用

在使用 v-model$emit 时,可能会导致不必要的重新渲染。

8.3.33 避免使用 v-model$refs 混合使用

在使用 v-model$refs 时,可能会导致不必要的重新渲染。

8.3.34 避免使用 v-model$nextTick 混合使用

在使用 v-model$nextTick 时,可能会导致不必要的重新渲染。

8.3.35 避免使用 v-modelvm.$forceUpdate 混合使用

在使用 v-modelvm.$forceUpdate 时,可能会导致不必要的重新渲染。

8.3.36 避免使用 v-modelvm.$set 混合使用

在使用 v-modelvm.$set 时,可能会导致不必要的重新渲染。

8.3.37 避免使用 v-modelvm.$delete 混合使用

在使用 v-modelvm.$delete 时,可能会导致不必要的重新渲染。

8.3.38 避免使用 v-modelvm.$watch 混合使用

在使用 v-modelvm.$watch 时,可能会导致不必要的重新渲染。

8.3.39 避免使用 v-modelvm.$watch 深度监听混合使用

在使用 v-modelvm.$watch 深度监听时,可能会导致不必要的重新渲染。

8.3.40 避免使用 v-modelvm.$watch 立即执行混合使用

在使用 v-modelvm.$watch 立即执行时,可能会导致不必要的重新渲染。

8.3.41 避免使用 v-modelvm.$set 数组混合使用

在使用 v-modelvm.$set 数组时,可能会导致不必要的重新渲染。

8.3.42 避免使用 v-modelvm.$delete 数组混合使用

在使用 v-modelvm.$delete 数组时,可能会导致不必要的重新渲染。

8.3.43 避免使用 v-modelvm.$watch 数组混合使用

在使用 v-modelvm.$watch 数组时,可能会导致不必要的重新渲染。

8.3.44 避免使用 v-modelvm.$watch 数组深度监听混合使用

在使用 v-modelvm.$watch 数组深度监听时,可能会导致不必要的重新渲染。

8.3.45 避免使用 v-modelvm.$watch 数组立即执行混合使用

在使用 v-modelvm.$watch 数组立即执行时,可能会导致不必要的重新渲染。

8.3.46 避免使用 v-modelvm.$set 对象混合使用

在使用 v-modelvm.$set 对象时,可能会导致不必要的重新渲染。

8.3.47 避免使用 v-modelvm.$delete 对象混合使用

在使用 v-modelvm.$delete 对象时,可能会导致不必要的重新渲染。

8.3.48 避免使用 v-modelvm.$watch 对象混合使用

在使用 v-modelvm.$watch 对象时,可能会导致不必要的重新渲染。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/652600.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超声波清洗机哪家好一点?四款无比卓越精品不可错过

在日常生活中&#xff0c;眼镜成为了我们不可或缺的伙伴&#xff0c;无论是阅读书籍、工作还是享受自然风光&#xff0c;清晰的视野总是至关重要。然而&#xff0c;眼镜上不可避免地会沾染灰尘、油脂甚至细菌&#xff0c;影响我们的视觉体验。传统的眼镜清洗方法虽然简单&#…

【Godot4.2】Godot中的继承与组合

概述 继承和组合是编程中常用的两种策略,旨在尽可能多地重用代码。继承应用得非常广泛&#xff0c;但我认为组合在很多场景下会更加合适一些。 基于组合&#xff0c;游戏开发前辈们专门设计出了实体组件模式&#xff08;EC模式&#xff09;和进阶的ECS模式。本篇所提及的Godot…

芯片设计 | FPGA设计的各种仿真概念分析

前仿真,即功能仿真。 可使用专用于仿真的工具对设计进行功能仿真,以验证电路功能是否符合设计要求。 通过功能仿真能够及时发现设计中的错误,从而加快设计进度,提高设计的可靠性。 综合后的仿真 把综合生成的标准延时反标注到综合仿真模型去,可估计门延时带来的影响,…

如何搭建个人观测云平台

如何搭建个人观测云平台 安装DataKit什么是DataKit&#xff1f; 仪表板指标管理监控 开通阿里云观测云服务后&#xff0c;在观测云平台页面进行下面的操作。 安装DataKit 什么是DataKit&#xff1f; DataKit 是观测云官方发布的数据采集应用&#xff0c;支持上百种数据的采集…

【二叉树】非递归实现前中后序遍历

目录 前言 算法思想 非递归实现前序遍历 过程分析 代码 非递归实现中序遍历 过程分析 代码 非递归实现后序遍历 过程分析 代码 前言 1&#xff09;前序&#xff1a;根 左子树 右子树 2&#xff09;中序&#xff1a;左子树 根 右子树 3&#xff09;后序&#xff1…

CSS学习笔记:rem实现移动端适配的原理——媒体查询

移动端适配 移动端即手机端&#xff0c;也称M端 移动端适配&#xff1a;同一套移动端页面在不同屏幕尺寸的手机上可以实现宽度和高度的自适应&#xff0c;也就是页面中元素的宽度和高度可以根据屏幕尺寸的变化等比缩放 rem配合媒体查询可实现移动端适配 rem单位 媒体查询 …

post请求

文章目录 一、get请求和post请求区别二、get请求和post请求的用法对比1.get请求2.post请求 三、如何知道是get请求还是post请求 一、get请求和post请求区别 二者区别就是一句话&#xff1a;post请求更安全 二、get请求和post请求的用法对比 1.get请求 get请求: 请求参数&am…

安泰电子:高压功率放大器应用场合介绍

高压功率放大器是一种电子设备&#xff0c;用于将低电压信号放大到较高电压水平&#xff0c;以满足各种应用需求。它在多个领域中具有广泛的应用&#xff0c;包括科学研究、工业生产、通信技术以及医疗设备。下面安泰电子将介绍高压功率放大器的应用场合。 科学研究 高压功率放…

SpringBoot实现接口防抖的几种方案,杜绝重复提交

插&#xff1a; AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

YOLOV10阅读总结

GitHub - THU-MIG/yolov10: YOLOv10: Real-Time End-to-End Object Detection YOLOv10 - Ultralytics YOLO Docs https://arxiv.org/pdf/2405.14458 论文地址 最近yolo又出了个yolov10了&#xff0c;不得不感慨CV是真卷&#xff0c;毕竟yolov9也才没多久。记录一下阅读笔记。…

curl请求url正常,通过web端请求就400异常的问题记录

通过抓包发现如上图&#xff0c;有2个authorization header&#xff0c;其中一个是开发人员代码生成的&#xff0c;另一个是web端http请求自己携带的。目标是去除web自己携带的。 解决方法&#xff1a; 生成一个FeignConfig的类&#xff0c;requestInterceptor进行空实现。 Fe…

暑期社会实践即将强势来袭,投稿三下乡文章最强攻略

以热爱充实自我 以笃行丰盈青春 这个盛夏“乡”约 纷纷迈出了社会实践的有力步伐 在展开社会实践的同时 也不要忘记投稿宣传的重要性哦 快快收藏住这份投稿攻略 助力团队展现更多精彩的实践故事! No.1 感悟思想伟力&#xff0c;守好“红色根脉” No.2 循迹“八八战略…

【基于 PyTorch 的 Python 深度学习】9 目标检测与语义分割(2)

前言 文章性质&#xff1a;学习笔记 &#x1f4d6; 学习资料&#xff1a;吴茂贵《 Python 深度学习基于 PyTorch ( 第 2 版 ) 》【ISBN】978-7-111-71880-2 主要内容&#xff1a;根据学习资料撰写的学习笔记&#xff0c;该篇主要介绍了优化候选框的几种方法。 一、优化候选框的…

人工智能超万卡集群的核心设计原则和架构

超万卡集群的核心设计原则和架构 超万卡集群建设方兴未艾,当前主要依托英伟达GPU及其设备。英伟达GPU在大模型训练中表现卓越,但国产AI芯片虽进步显著,性能与生态构建仍存差距。面对诸多挑战,构建技术领先、基于国产生态的超万卡集群,仍需不断突破与创新。 大模型升级至万…

腾讯前端4轮面经分享,期望薪资28K

笔者原来在北京360企业安全工作&#xff0c;当时因为大学四年的学业是在北京完成的&#xff0c;所以就顺势通过校招在北京工作了。但家里是南方的&#xff0c;对南方的饮食和生活习惯更加喜欢一些&#xff0c;所以对深圳广州的公司特别是腾讯觊觎已久&#xff0c;所以就在今年2…

期货学习笔记-斐波那契学习1

斐波那契数列介绍 斐波那契数列是1、1、2、3、5、8、13、21、34、55、89…据说这是数学家莱昂纳多 斐波那契研究兔子繁殖时发现的一个神奇数列&#xff0c;似乎大自然在按照这个数列进行演化&#xff0c;一个斐波那契数字是由该数列相邻的前两个数字相加得到的 在斐波那契交易…

Spark Sql写代码方式(yarn)以及 spark sql整合hive详解

引入部分&#xff1a;通常我们在IDEA中写spark代码中如果设置了loacl参数&#xff0c;基本都是在IDEA本地运行&#xff0c;不会提交到 standalone或yarn上运行&#xff0c;在前几篇文章中写的大多数都是该种形式的spark代码&#xff0c;但也写到了如何将spark代码提交到standal…

大模型微调:Lora

原理图 原理&#xff1a;不改变原始大模型参数&#xff0c;只加入一个类似残差分支&#xff0c;先降纬再升纬&#xff0c;因为模型是过参数化的&#xff0c;它们有更小的内在维度&#xff0c;模型主要依赖于这个低的内在维度&#xff08;low intrinsic dimension&#xff09;去…

基于LLM的优化器评测

基于LLM的优化器评测 求解的目标函数测试结果测试代码测试日志 背景: ​ 很多时候我们需要为系统寻找最优的超参.比如模型训练,推理的量化等.本文尝试将LLM当成优化器,帮忙我们寻找最优的超参. 验证方法: 1.设计一个已知最优解的多项式,该多项式有3个变量(因为3个变量可以通过…

飞睿智能高精度、低功耗测距,无线室内定位UWB芯片如何改变智能家居

在数字化和智能化快速发展的今天&#xff0c;定位技术已经成为我们日常生活中不可或缺的一部分。然而&#xff0c;传统的GPS定位技术在室内环境中往往束手无策&#xff0c;给我们的生活带来了诸多不便。幸运的是&#xff0c;随着科技的不断进步&#xff0c;一种名为UWB&#xf…