【Vue + keep-alive】路由缓存

一. 需求

列表页,n 条数据项可打开 n 个标签页,同时1条数据项的查看和编辑共用一个标签页。如下所示:


参考

bash 复制代码
// 主页面
// 解决因 路由缓存,导致 编辑后跳转到该页面 不能实时更新数据
onActivated(() => {
  getList()
})

二. 实现

2.1 查看/编辑 返回 主页面

  1. 实现(template模块)
bash 复制代码
<!-- 修改/查看页 -->
<template>
	<div style="padding:20px">
		<el-form ref="formName" :model="form" :rules="formRules"  label-width="120px">
			<template v-if="type == '查看'">
				<el-form-item>
          			<el-col :span="12">
           				<el-form-item label="联系人" prop="contactName">
              				<span>{{ form.contactName }}</span>
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="学历" prop="education">
              				<span>{{ form.education}}</span>
            			</el-form-item>
          			</el-col>
        		</el-form-item>
        		<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="手机号" prop="phone">
              				<span>{{ form.phone }}</span>
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="邮箱" prop="email">
              				<span>{{ form.email }}</span>
            			</el-form-item>
          			</el-col>
        		</el-form-item>
			<template>
			<template v-else>
				<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="联系人" prop="contactName">
              				<el-input v-model="form.contactName" placeholder="请输入联系人" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="学历" prop="education">
              				<el-input v-model="form.education" placeholder="请输入学历" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
        		</el-form-item>
        		<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="手机号" prop="phonenumber">
              				<el-input v-model="form.phonenumber" placeholder="请输入手机号" maxlength="11" show-word-limit />
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="邮箱" prop="email">
              				<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
        		</el-form-item>
			<template>
		</el-form>
		<div v-if="type == '修改'">
      		<el-button @click="handleClick">取 消</el-button>
      		<el-button type="primary" @click="handleSubmit">确 认</el-button>
    	</div>
	</div>
</template>

2.2 返回上一页(script 跳转方式)

修改成功/点击取消 返回主页面

  1. 错误:打开新的标签页
bash 复制代码
/** 确认按钮 */
const submitForm = () => {
  proxy.$refs['formName'].validate(valid => {
    if (valid) {
      if (type.value === '修改') {
      	// 调用接口
        update({ id: detailId, ...form.value }).then(res => {
          if (res.code === 200) {
            proxy.$modal.msgSuccess('修改成功')
            setTimeout(() => {
              // 返回上一页
              handleClick()
            }, 2000)
          }
        })
      }
    }
  })
}
/** 取消 返回到上一页,避免打开新的标签页 */
const handleClick = async() => {
  await router.push({ path: `/xxx` })
}
  1. 正确:不打开新标签页,返回原来的主页面
bash 复制代码
/** 确认按钮 */
const submitForm = () => {
  proxy.$refs['formName'].validate(valid => {
    if (valid) {
      if (type.value === '修改') {
      	// 调用接口
        update({ id: detailId, ...form.value }).then(res => {
          if (res.code === 200) {
            proxy.$modal.msgSuccess('修改成功')
            setTimeout(() => {
              // 返回上一页
              handleClick()
            }, 2000)
          }
        })
      }
    }
  })
}
/** 取消 返回到上一页,避免打开新的标签页 */
const handleClick = () => {
  router.go(-1)
}

2.3 不同 【修改/查看】标签页相互切换

  1. 期望

修改和查看的显示内容,不会因处在同一个页面互相影响。且在切换不同标签时,不会出现数据紊乱情况

  1. 实现
bash 复制代码
<script setup name="Detail">
const route = useRoute() // route.type 判断编辑还是查看
const type = ref('') // 编辑/查看
// 路由监听
watch(
  () => route.query.type,
  newValue => {
      type.value = newValue
},
  {deep: true, immediate: true}
)
</script>
  1. 问题

代码中限制了不能重复调用接口。所以在切换不同 修改/查看 标签页 时一直提醒重复调用。

① 原因

路由缓存

bash 复制代码
<template>
  <!-- vue3.0配置 -->
  <router-view v-slot="{ Component }">
    <keep-alive>
      //  v-if="$route.meta.keepAlive"
      <component :is="Component" />
    </keep-alive>
  </router-view> 
</template>

② 解决:清楚缓存

bash 复制代码
/**
* name:'',     // 路由名称
* query:'{"id","1","type":"编辑"}',
* meta:{
* 	keepAlive  // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false),
* 	icon:''    // 图标名称
* 	title:''   // 名称
* }
* /

{
   path: "/Detail",
   name: "Detail",
   meta: {
       keepAlive: true // 设置页面是否需要使用缓存
   },
   component: () => import("@/views/xxx/Detail/index.vue")
 },


三. 知识点

  1. 路由跳转数据未实时更新,参考1参考2
  2. 路由缓存,参考
  3. 退回到上一页
相关推荐
萌萌哒草头将军42 分钟前
🚀🚀🚀尤雨溪:Vite 和 JavaScript 工具的未来
前端·vue.js·vuex
我家媳妇儿萌哒哒1 小时前
el-upload 点击上传按钮前先判断条件满足再弹选择文件框
前端·javascript·vue.js
加油,前进1 小时前
layui和vue父子级页面及操作
javascript·vue.js·layui
天天向上10241 小时前
el-tree按照用户勾选的顺序记录节点
前端·javascript·vue.js
sha虫剂1 小时前
如何用div手写一个富文本编辑器(contenteditable=“true“)
前端·vue.js·typescript
咔咔库奇2 小时前
深入探索 Vue 3 Fragments:从原理到实战的全方位指南
前端·javascript·vue.js
java_强哥2 小时前
uniapp实现聊天中的接发消息自动滚动、消息定位和回到底部
javascript·vue.js·uni-app
要加油哦~2 小时前
vue | vue 插件化机制,全局注册 和 局部注册
前端·javascript·vue.js
猫头虎-前端技术2 小时前
HTML 与 CSS 的布局机制(盒模型、盒子定位、浮动、Flexbox、Grid)问题总结大全
前端·javascript·css·vue.js·react.js·前端框架·html
天蓝色的鱼鱼2 小时前
Vue重复提交防御体系从入门到精通
前端·vue.js