vue中实现子组件相互切换且数据不丢失的策略详解
项目场景:
今天的项目场景: 项目为数据报表,但是一个父页面中有很多的子页面,而且子页面中不是相互关联,但是数据又有联系.
问题描述
子页面相互切换的时候之前填写好的数据会丢失,无法保存.这样想提交所有的子页面的数据就出现问题.
原因分析:
分析原因就是子组件在切换的时候,我使用的是动态组件,这个动态组件的底层原理是v-if去判断,这样子组件就有一个消失重建的过程. 如何让子组件保存不消失.而且还需要在切换回来的时候其他子页面的数据改了之后,当前的子页面的数据也会同步?
解决方案:
vue中有一个延缓什么周期的组件,keep-alive
将子组件用keep-alive包裹之后
<keep-alive> <component :is="'tab' + active" :ref="'tab' + active"></component> </keep-alive>
整体代码:
<template> <div class="userbox"> <comm-card> <!-- title 标题 v-bind : v-on @ v-slot # --> <template #title> <div class="box"> <span>有子组件-案例2</span> </div> </template> <!-- content 正文--> <template #content> <div style="width: 100%"> <div class="tabtitle" style="margin-bottom: 20px"> <el-tag v-for="tag in tags" :key="tag.name" closable :type="tag.type" style="margin-left: 20px; width: 100px; text-align: center" @click="tabclicks(tag.id)" > {{ tag.name }} </el-tag> </div> <div class="tabbox"> <keep-alive> <component :is="'tab' + active" :ref="'tab' + active"></component> </keep-alive> </div> <div> <el-button type="primary" @click="save()">提交</el-button> </div> </div> </template> </comm-card> </div> </template> <script> /* 1, 不能让子组件在切换的时候,值消失,必须使用缓存技术, v-show 或者 keep-alive 2, 为了提高性能或者简化代码,可以使用component 动态组件加载技术 3, 使用ref技术获取子组件的值 4, 结合tab栏点击事件,实现获取值的时机 */ // 第一步 引入 import commCard from "../../components/commonCard"; import tab1 from "./components/sun1.vue"; import tab2 from "./components/sun2.vue"; import tab3 from "./components/sun3.vue"; // 第二步 注册到我们的components中 export default { components: { commCard, tab1, tab2, tab3, }, data() { return { active: 1, tags: [ { id: 1, name: "菜单1", type: "" }, { id: 2, name: "菜单2", type: "success" }, { id: 3, name: "菜单3", type: "warning" }, ], values: {}, // 存不同的子组件的值 }; }, methods: { tabclicks(value) { //在点击的时候开始存入上一个子组件的值 this.values[this.active - 1] = this.$refs["tab" + this.active].obj; // 切换到已经点击的子组件上 this.active = this.tags.findIndex((ele) => { return ele.id == value; }) + 1; }, save() { //解决方案,将不同组件的值用不懂对象名称包裹 // 获取当前子组件的值 this.values[this.active - 1] = this.$refs["tab" + this.active].obj; // 打印所以得子组件的值 console.log(this.values); }, }, }; </script> <style lang="less" scoped> .box { display: flex; justify-content: space-between; align-items: center; width: 100%; } </style>
完美解决问题!
番外:component实现组件切换
1.代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件切换</title> </head> <body> <div class="body"> <input type="button" value="登录" @click="name='login'"> <input type="button" value="注册" @click="name='register'"> <input type="button" value="首页" @click="name='index'"> <!-- 使用 component 元素实现组件之间的切换 --> <component :is="name"></component> </div> <!-- 登录组件 --> <template id="login"> <h3>我是登录组件</h3> </template> <!-- 注册组件 --> <template id="register"> <h3>我是注册组件</h3> </template> <!-- 首页组件 --> <template id="index"> <h3>我是首页组件</h3> </template> <script src="../lib/vue-2.4.0.js"></script> <script> /* 登录组件 */ Vue.component("login", { template: "#login" }) /* 注册组件 */ Vue.component("register", { template: "#register" }) /* 首页组件 */ Vue.component('index', { template: "#index" }) let vm = new Vue({ el: ".body", data: { name:'login' } }) </script> </body> </html>
效果:
讲解:
(1)定义三个不同的组件
(2)在 vue 实例的控制区域中写入 component 元素,设置 is 属性(需要通过 v-bind 进行数据绑定),其值为将要显示的组件的名称
(3)在 data 中定义一个 name 值,其初始值为 ‘login’(注意要用引号包裹起来)
(4)为各个按钮设置事件绑定,点击时修改 name 为对应的值(注意 name 的值要用引号包裹起来)
以上就是vue中实现子组件相互切换且数据不丢失的策略详解的详细内容,更多关于vue子组件相互切换的资料请关注脚本之家其它相关文章!
相关文章
TypeScript基本类型 typeof 和keyof案例详解
这篇文章主要介绍了TypeScript基本类型 typeof 和keyof案例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-10-10vue+element-ui+sortable.js实现表格拖拽功能
这篇文章主要为大家详细介绍了vue+element-ui+sortable.js实现表格拖拽功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2022-04-04vue踩坑记-在项目中安装依赖模块npm install报错
这篇文章主要介绍了vue踩坑记-在项目中安装依赖模块npm install报错,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-04-04使用vue-antDesign menu页面方式(添加面包屑跳转)
这篇文章主要介绍了使用vue-antDesign menu页面方式(添加面包屑跳转),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-01-01
最新评论