【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. 退回到上一页
相关推荐
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
jerry6094 小时前
7天用Go从零实现分布式缓存GeeCache(改进)(未完待续)
分布式·缓存·golang
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
Dread_lxy6 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
看山还是山,看水还是。7 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0017 小时前
Redis运行时的10大重要指标
数据库·redis·缓存
奔跑草-7 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript