<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p>《vue基础学习-组件》提到组件传递数据方式:</p>
讯享网
1. props/$emit
- 父传子:子组件通过 显式声明 自定义 属性,接收父组件的传值。
- 子传父:子组件通过 显式声明 自定义 事件,父组件调用自定义事件接收子组件返回的参数。
2. $ref / $parent
- 父传子:父组件的方法中通过 访问子组件的引用。
- 子传父:子组件中通过 访问父组件的引用。
本节将主要介绍组件调用中涉及的生命周期钩子。
在 Vue.js 中,你可以使用 元素结合 属性来动态地切换组件。这种方式非常灵活,可以根据数据的变化来渲染不同的组件。
讯享网
- :这里使用了 元素,并通过 绑定一个变量 。 的值决定了要渲染哪个组件。
- :这是一个响应式的数据属性,初始值为 。当点击按钮时,这个值会被更新,从而触发组件的切换。
假设你有两个组件 和 :
ComponentA.vue
ComponentB.vue
讯享网
点击 ,加载组件 :

讯享网
点击 ,加载组件 :

点击 ,数值改变:

但如果点击 后,再点击 ,组件 状态没有保存:

如果你希望在切换组件时保留组件的状态,可以使用 包裹 。
在 Vue.js 中, 是一个内置组件,用于缓存组件实例,以避免重复渲染和销毁。
这样,即使组件被切换,它们的状态也会被保留。
点击 后,再点击 ,组件 状态不变:

总结:
- 使用 可以动态地切换组件。
- 结合 可以保留组件的状态。
- 通过改变 绑定的变量值来控制显示哪个组件。
2.1 <keep-alive>包裹的组件怎么去除状态保留
如果你希望在某些情况下不保留组件的状态,可以通过以下几种方法来实现:
2.1.1 使用 include 和 exclude 属性
组件提供了 和 属性,可以用来控制哪些组件会被缓存。你可以根据组件的名称或组件本身来决定是否缓存。
讯享网
2.1.2 动态控制 <keep-alive>
可以通过条件渲染来动态控制是否使用 。

但运行后,发现虽然组件 的方法 、 都执行了,但是状态并没有保留。o(╯□╰)o
查阅资料 关于动态使用keepAlive不生效的问题 发现:
通过 来判断是否生成 ,当列表页面符合条件时,内存缓存了组件状态。当跳转到详情页时,不符合条件,由于 是挂载到 标签上,会把之前 的列表页面进行销毁,再次进入到列表会重新创建。
✔️ 正确的使用方法:
讯享网
☝️ ⚠️ ✨注:实际项目中, 需要配合 共同使用,通过增加 属性,判定组件是否缓存。
讯享网
2.1.3 使用 activated 和 deactivated 生命周期钩子在组件内部控制状态
可以在组件内部使用 和 生命周期钩子来手动管理组件的状态。这些钩子在组件被激活和停用时调用。
例如,不想组件 ComponentB 状态被保留:
在 Vue.js 中, 和 是 Vue 组件的 生命周期钩子,主要用于 包裹的组件。
- :当组件被 激活 时调用。这通常发生在组件从缓存中恢复并重新显示时。
- :当组件被 停用 时调用。这通常发生在组件被隐藏并放入缓存时。
ComponentB.vue
讯享网
点击 ,加载组件 ,打印 :

点击 ,加载组件 ,打印 :

再次点击 ,加载组件 ,打印 :

注意:
- 生命周期钩子 和 必须和 结合使用才生效。
在 Vue.js 中,生命周期钩子(Lifecycle Hooks)是一些特定的函数,你可以在这些函数中执行自定义逻辑。Vue 组件从创建到销毁的过程中会经历一系列的阶段,每个阶段都有相应的钩子函数可以让你插入自定义代码。
Vue 2 和 Vue 3 的生命周期钩子有一些差异。Vue 3 引入了一些新的生命周期钩子,并对一些旧的钩子进行了重命名。
- Vue 2 生命周期钩子
- 创建阶段:
- :在实例初始化之后,数据、事件配置之前被调用。
- :在实例创建完成后被调用。此时实例已完成数据、事件配置。但是挂载阶段还没开始, 属性目前不可见。
- 挂载阶段:
- :在挂载开始之前被调用。相关的 函数首次被调用。
- :在实例挂载到 DOM 之后被调用。
- 更新阶段:
- :在更新 数据之后, 视图重新渲染之前触发。所以, 和 针对视图层的。
- : 视图渲染完成后触发。
- ⚠️注1:只有 上面的数据变化才会触发 和 ,仅属于 中的数据改变是并不能触发。
- ⚠️注2:发起数据请求不能在 和 中操作,会导致无限循环。
- 销毁阶段:
- :在实例销毁之前调用。在这一步,实例仍然完全可用。
- :在实例销毁后调用。此时所有的事件监听器都被移除,所有的子实例也都被销毁。
- 其他钩子:
- :在 组件激活时调用。
- :在 组件停用时调用。
- :捕获一个来自后代组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
- 创建阶段:
- Vue 3 生命周期钩子
- 创建阶段:
- :在 Vue 3 中, 和 钩子被 函数取代。
- 挂载阶段:
- :在挂载开始之前被调用。
- :在实例挂载到 DOM 之后被调用。
- 更新阶段:
- :在数据更新时调用,发生在虚拟 DOM 打补丁之前。
- :在数据更新后调用,此时 DOM 已经更新。
- 销毁阶段:
- :代替 。
- :代替 。
- 其他钩子:
- :代替 。
- :代替 。
- :代替 。
- 创建阶段:
5.1 created
钩子在实例创建完成后被调用。此时实例已完成数据、事件配置。但是挂载阶段还没开始, 属性目前不可见。
典型用例:
- 初始化数据。
- 发起网络请求获取初始数据。
- 设置事件监听器。
5.2 mounted
钩子在实例挂载到 DOM 之后被调用。
典型用例:

- 操作 DOM,一般结合 ,确保子组件 DOM 已经被更新。
- 初始化第三方库(如 jQuery 插件)。
- 启动定时器或动画。
讯享网
5.3 beforeUpdate
典型用例:
- 在数据更新前保存当前状态。
- 清理无效的数据或状态。
- 如果一个组件的数据更新会影响到其他组件的状态,可以在 中发送事件通知其他组件进行相应的处理。
5.4 updated
典型用例:
- 操作更新后的 DOM。
- 基于更新后的 DOM 的操作,比如调整布局、更新样式等。
- 结合 beforeUpdate 记录时间戳,计算视图渲染时间,进行性能测试,以便后续优化。
- 如果组件之间需要在数据更新后进行交互,可以在 钩子中发送事件或调用其他组件的方法。
5.5 beforeDestroy、beforeUnmount
典型用例:
- 清理定时器。
- 取消网络请求。
- 移除事件监听器。
5.6 destroyed、unmounted
典型用例:
- 最终清理工作。
- 记录日志。
完整示例 Lifecycle.vue:
组件加载,触发 、

点击 “changeMessage”,因为message 没有在视图中展示,不会触发 、。

点击“increment”,触发 、。
视图渲染前,获取 DOM 视图中 为更新前数据,数据 中的 已经被修改,但未渲染更新到 DOM 视图中。(可以 断点调试)
视图渲染完成,DOM 视图中 和 数据 中的 均被修改。

再次点击“increment”,,触发 、。

是 Vue.js 中的一个方法,用于在下次 DOM 更新循环结束之后执行延迟回调。
当修改了 组件中的数据时,Vue.js 并不会立即进行视图更新。Vue.js 会将修改的数据记录下来,并在下一次事件循环时才更新视图。而 方法则是用于等待这个事件循环结束后再执行回调函数。这样可以确保 已经被更新,以及可以操作到最新的 。
讯享网

结果可见, 内回调函数是异步执行的,所以先打印 “333”, 再打印 “222”。而且,等子组件视图更新结束之后,才执行 内回调函数,保证操作到最新的 。
⚠️ 注意:虽然 方法可以解决异步更新导致的问题,但如果过度使用该方法会导致性能问题。因此,在实际开发中,只有在必要的情况下才应该使用 方法。
6.1 常见应用场景
1.获取更新后的DOM尺寸和位置
2.执行复杂的计算
讯享网
回调函数内能确保获取的是最新的数据。
3.在父组件中,等待子组件数据更新后再执行操作,确保操作最新数据

4.监听视图变化并执行相应操作
讯享网

6.2 与 updated 区别
- :在当前 DOM 更新周期结束后执行回调函数。适用于需要在数据变化后立即访问更新后的 DOM 的情况。
- 生命周期钩子:在组件因为数据变化而重新渲染后调用。适用于在组件更新后执行某些操作的情况。
选择哪种方式取决于你的具体需求:
- 如果你需要在特定的数据变化后立即执行某些操作,使用 。
- 如果你需要在组件每次更新后执行某些操作,使用 生命周期钩子。
6.3 应用
获取了左侧菜单的列表树,在 的 方法中更新菜单数的数据源 ,更新数据源后,希望能 高亮 的菜单。
如果这样写:
这样不一定能达到你要的效果,因为高亮操作的时候,数据源虽然更新了,但是 DOM 有可能还没渲染完成,这时候你操作高亮 DOM 是找不到的。
这时,就需要用 。
讯享网
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/146582.html