赞
踩
需要在后台管理系统中的列表数据添加复制功能,复制成功的链接能够在手机浏览器或者微信中打开指定的小程序页面(pages/good/detail/index)
需要在手机浏览器或者微信中唤起小程序有两种方式, 小程序URL Scheme文档,开放范围:非个人主体小程序
注意:iOS系统可以直接打开URL Scheme,Android系统需要使用 H5 页面中转
当前项目使用的技术是 vite-vue-ts,使用明文 URL Scheme方式唤起小程序
安装项目:pnpm create vite my-project-name --template vue-ts
1.列表页复制按钮事件js,实现生成URL Scheme,并复制到剪切板
const handleClick = ()=>{ // URL Scheme需要进入的小程序页面 const path = 'pages/good/detail/index' // URL Scheme携带的参数 const query = encodeURIComponent(`goodId=${record.goodId}&other=${record.other}`) // 拼接完整的 URL Scheme const url = encodeURIComponent(`weixin://dl/business/?appid=222222222222&path=${path}&query=${query}`) // 跳转到新增的H5页面的url(看下文),mpAppId公众号id,appId小程序id const goodUrl = `${location.origin}/good.html?scheme=${url}&mpAppId=11111111111111&appId=222222222222` // 调用后端的接口生成短链接,并复制到剪切板 return myRequest(`api/short/url`, { url:goodUrl }).then((resp) => { // 拷贝到剪切板(看下文utils工具) copyText(resp.data) Message.success('复制成功') return resp.data }) }
2.需要在现有的后台管理系统项目新建一个H5页面
在vite.config.ts中配置项build > rollupOptions > input 中新增配置项 good:
export default defineConfig({
// ... 其他配置
build:{
rollupOptions:{
// ... 其他配置
input: {
good: path.resolve(__dirname, 'good.html'), // 新建H5
index: path.resolve(__dirname, 'index.html'), // 原系统入口页
},
output: {
dir: path.resolve(__dirname, './dist'), // 打包输出问价
},
}
}
})
在vite.config.ts同级目录下新建good.html文件,并引入小程序微信开放标签JDK的js文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/logo.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>跳转中...</title> // 小程序微信开放标签 <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> </head> <body> <div id="app"></div> <script type="module" src="/src/good.ts" ></script> </body> </html>
在src下新建good.ts,挂载页面
import { createApp } from 'vue'
import Auth from './Login.vue'
import './themes/login.less'
createApp(Auth).mount('#app')
在src下新建good.vue页面(H5页面),用来跳转小程序(访问复制出来的URL会进入这个页面,然后在点击进入小程序)
<!-- eslint-disable vue/no-lone-template --> <template> <div class="good"> // 手机浏览器网页直接打开上文复制出来的url <div v-if="isWeiXin ? false : isMobile" class="public-web-container" > <a href="javascript:" class="public-web-jump-button" @click="openWxApp()" > 打开小程序 </a> </div> // 微信中需要使用微信开发标签 <div v-show="isWeiXin" id="weChat-web-container" class="weChat-web-container" > <wx-open-launch-weapp id="launch-btn" class="wx-open-launch-weapp" :appid="appId" :path="weappPath" > <component :is="'script'" type="text/wxtag-template" > <button style="width: 200px; height: 45px; text-align: center; font-size: 17px; display: block; margin: 0 auto; padding: 8px 24px; border: none; border-radius: 4px; background-color: #07c160; color: #fff"> 打开小程序 </button> </component> </wx-open-launch-weapp> </div> // 桌面端提示用手机网页 <div v-if="isDesktop" class="desktop-web-container" > <p>请使用手机打开网页</p> </div> </div> </template> <script lang="ts" setup> // 开放标签获取签名(签名需要后端生成) const getSign = (params: { url: string })=>{ return axios.get(`/api/get/sign?url=${params.url}`) } const isWeiXin = ref<boolean>(false) const isMobile = ref<boolean>(false) const isDesktop = ref<boolean>(false) // mpAppId 公众号id, appId 小程序id const { mpAppId = '11111111111111', appId = '222222222222', scheme } = Object.fromEntries(new URLSearchParams(location.search)) const weappPath = ref('') const errorCb= (e: any) => { console.error('错误原因:', e.detail.errMsg) } onMounted(() => { // 微信页面需要注册开放标签 document.addEventListener('WeixinOpenTagsError', errorCb) if (isWeiXin.value) { getSign({ url: encodeURIComponent(location.href.split('#')[0]) }).then((res) => { const { data } = res.data ;(window as any).wx.config({ debug: false, appId: mpAppId, timestamp: data.timestamp, nonceStr: data.noncestr, signature: data.sign, jsApiList: ['uploadImage'], openTagList: ['wx-open-launch-weapp'], }) }) } }) onUnmounted(() => document.removeEventListener('WeixinOpenTagsError', errorCb)) onBeforeMount(() => { const params = new URLSearchParams(scheme) const query = params.get('query') as string weappPath.value = `${params.get('path')}?${query}` // 区分平台 const ua: any = navigator.userAgent.toLowerCase() const isWXWork = ua.match(/wxwork/i) === 'wxwork' isWeiXin.value = !isWXWork && ua.match(/micromessenger/i) == 'micromessenger' if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) { isMobile.value = true } else { isDesktop.value = true } }) const openWxApp = () => { // 非微信中网页 location.href = decodeURIComponent(scheme) } </script> <style lang="less" scoped> * { padding: 0; margin: 0; } .good{ position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .weChat-web-container, .public-web-container, .desktop-web-container { display: flex; flex-direction: column; align-items: center; } .wx-open-launch-weapp { position: absolute; bottom: 50%; left: 0; right: 0; display: flex; flex-direction: column; align-items: center; transform: translateY(-50%); } .public-web-jump-button { position: absolute; bottom: 50%; transform: translateY(-50%); display: inline-block; width: 184px; margin-left: auto; margin-right: auto; padding: 8px 24px; box-sizing: border-box; background-color: #06ae56; color: #fff; font-weight: 700; font-size: 17px; text-align: center; text-decoration: none; line-height: 1.41176471; border-radius: 4px; overflow: hidden; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .desktop-web-container p { position: absolute; top: 50%; transform: translateY(-50%); } </style>
src > utils > index 工具文件
// 复制剪切板功能 function fallbackCopyTextToClipboard(text: string) { let textArea = document.createElement('textarea') textArea.value = text // Avoid scrolling to bottom textArea.style.top = '0' textArea.style.left = '0' textArea.style.position = 'fixed' document.body.appendChild(textArea) textArea.focus() textArea.select() return new Promise<boolean>((resolve, reject) => { try { let successful = document.execCommand('copy') resolve(successful) } catch (err) { reject(err) } finally { document.body.removeChild(textArea) } }) } export const copyText = (text: string): Promise<boolean> => { if (!navigator.clipboard) { return fallbackCopyTextToClipboard(text) } return navigator.clipboard.writeText(text).then(() => true) }
链接: URL Scheme文档
链接: 获取短链接
链接: 开放标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。