🧑 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
背景
线上的一个项目因为嵌套路由过深,客户觉得复制分享的链接地址太长,所以需要增加一个分享短链接的功能。
方案
在网上搜索短链接跳转的方法大部分都是使用node服务实现的。
虽然实现并不复杂,但是考虑到多维护一个服务就多一份加班的可能性。我还是想要一个更加简单的方法。
而VueRouter就可以实现短链接跳转的功能。
直接往路由表插入一组短链接路由,redirect指向对应的路由。示例如下:
// shortLinks.js - 短链接配置 export const shortRoutes = [ { path: '/sbKLEy/:id', redirect: '/consectetur/adipiscing/elit/:id', name: 'sbKLEy', meta: { title: '页面1' }, }, ];
import { shortRoutes } from './shortLinks'; const routes = [ ...shortRoutes, { path: '/consectetur/adipiscing/elit/:id', name: 'consectetur', meta: { title: '页面1' }, component: () => import('@/views/consectetur/adipiscing/elit.vue'), }, ]; const router = new VueRouter({ routes, mode: 'history', });
这样的访问/sbKLEy/:id
路径的时候,直接就会跳转到/consectetur/adipiscing/elit/:id
。
query、params也都能正常重定向到源页面。
这个方案缺点就是只能缩短URL的 路径 部分。如果你的页面上有大量的查询参数部分,那这个方法能缩短的字符很有限。
好了,跳转功能没有问题,接下来就可以实现分享功能了。
分享功能
我们分享的逻辑是,用当前的路由地址去 短链接路由表 查询有无对应地址。有则使用短链接为分享路径,无则继续使用当前路由。然后将分享路径写入到粘贴板。
在实现分享功能之前,先准备两个工具函数:
/** * 根据给定的路径和参数对象,生成一个包含占位符的路径字符串 * @param {Object} route - 包含路径和参数的对象 * @param {string} route.path - 路径字符串 * @param {Object} route.params - 参数对象 * @returns {string} - 替换参数后的路径字符串,其中参数被替换为占位符 * @example * 输入: "/users/123", { id: "123" } * 输出: "/users/:id" */ function getSourcePath(path, params) { let sourcePath = path; // 按占位符名称的长度排序,从长到短,避免替换错误 const keys = Object.keys(params).sort((a, b) => b.length - a.length); for (const key of keys) { if (!Object.hasOwnProperty.call(params, key)) continue; const value = params[key]; const regex = new RegExp(value, 'g'); // 全局匹配该值 sourcePath = sourcePath.replace(regex, `:${key}`); } return sourcePath.replace(//+$/, ""); } /** * 根据给定的路径和参数对象,生成一个包含实际参数值的路径字符串 * @param {string} path - 路径模板,其中包含占位符,如 ":id" * @param {Object} params - 参数对象,包含占位符对应的值 * @returns {string} - 替换占位符后的实际路径字符串 * @example * 输入: "/users/:id", { id: "123" } * 输出: "/users/123" */ function getParamsPath(path, params) { let paramsPath = path; // 遍历占位符,确保每个占位符都能被替换 for (const key in params) { if (!Object.hasOwnProperty.call(params, key)) continue; const value = params[key]; const regex = new RegExp(`:${key}(?=\/|$)`, 'g'); // 确保只替换占位符 paramsPath = paramsPath.replace(regex, value); } return paramsPath.replace(//+$/, ""); }
这两个函数是相反的功能,一个是将/users/123
转为/users/:id
,另一个是将/users/:id
转回/users/123
。
getSourcePath
方法是按值查找替换,在两个param
值相同的情况下可能会替换错误。这里有需要的可以深入再完善一下。
因为我项目内没有多个param
的路由,所以就不再继续完善该函数了。
接下来就是分享函数 handleShare
export function handleShare (route) { // 待分享的路由路径 let sharePath = route.path // 源路径 const sourcePath = getSourcePath(route.path, route.params) // 映射的短链接路由 const redirectMapRoute = redirectMap.find(item => item.redirect === sourcePath) if (redirectMapRoute) { sharePath = getParamsPath(redirectMapRoute.path, route.params) } // 将完整路径中的路径替换为分享路径-省去处理 query 部分 sharePath = route.fullPath.replace(route.path, sharePath) // 复制内容 const shareUrl = `【${document.title}】 ${window.location.origin + sharePath}` // 将分享路径复制到剪切板,并且处理兼容问题 try { navigator.clipboard.writeText(shareUrl) .then(() => { Message({ message: '分享链接复制成功', type: 'success' }) }) } catch (err) { var copyInput = document.createElement('input') copyInput.setAttribute('value', shareUrl) document.body.appendChild(copyInput) copyInput.select() document.execCommand('copy') document.body.removeChild(copyInput) Message({ message: '分享链接复制成功', type: 'success' }) } }
功能大致就是:从短链接路由表中查找是否有对应映射的路由,有就使用该短链接路由作为分享地址,然后复制。
随后只需要在页面分享按钮的上添加上这个方法调用就ok了。
// vue2 <div @click="handleShare($route)"> 分享 </div> // vue3 <div @click="handleShare(route)"> 分享 </div> ... import { useRoute } from 'vue-router' const route = useRoute()
短链接路由生成
原先的页面路由如果很多的话。我们就再写个一次性的工具函数,遍历页面路由然后生成短链接路由表。
/** * 路径中提取参数部分 * @param {string} path - 包含参数的路径字符串 * @returns {string} - 提取出的参数部分,以斜杠分隔 */ function getParams (path) { const params = path.split('/').filter(i => i.startsWith(':')) if (params.length) return '/' + params.join('/') return '' } // 生成分享短链接路由表 function getShortRoutes () { const shortRoutes = [] function getRedirect(currentRoutes, parentPath = '') { currentRoutes.forEach(route => { let path = route.path // 相对路径需要拼接父路径 if (!route.path.startsWith('/')) path = parentPath + '/' + route.path // 随机生成一个短链接 const shortPath = nanoid(6) shortRoutes.push({ path: `/${shortPath}${getParams(path)}`, redirect: path, name: shortPath, props: route.props, meta: route.meta }) // 继续递归子路由 if (route.children) getRedirect(route.children, path) }) } getRedirect(routes) return shortRoutes } console.log(getShortRoutes())
很简单的函数,执行后到控制台取生成的结果就好了。这里有两点需要说一下。
- 相对路径需要拼接上父路径才是完整的
redirect
路径。 - 生成短链接路径使用的是
nanoid
随机生成,nanoid
默认使用URL友好字符,不需要担心字符问题。
本文转载于:https://juejin.cn/post/7450703068805267519
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
来源链接:https://www.cnblogs.com/smileZAZ/p/18820986
没有回复内容