文件
OmniCard/mpuniapp/uni_modules/uni-link-x/components/uni-link/uni-link.uvue

347 行
9.5 KiB
Plaintext

<template>
<text style="text-decoration-line: underline" @click="openURL">
<slot></slot>
</text>
</template>
<script lang="uts" setup>
/**
* 链接
* @description 链接组件
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
// #ifdef APP
import { openSchema } from '@/uni_modules/uts-openSchema'
// #endif
defineOptions({
name: 'UniLink',
styleIsolation: 'app'
})
type Props = {
/**
* @description 链接地址,点击组件时要打开的 URL
* @default ""
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
href?: string
/**
* @description 打开方式。"_self" 在当前应用内置 webview 中打开;"_blank" 在外部浏览器中打开(小程序端会复制链接提示用户外部打开)
* @default "_self"
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
target?: '_blank' | '_self'
/**
* @description `target="_blank"`失败时,可以通过本属性控制失败回退策略。"turn-self"使用_self方式打开;"copy-link-modal"复制链接并弹框提醒;"none"不回退,触发失败回调
* @default "turn-self"
* @uniPlatform {
* "app": {
* "android": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.21"
* },
* "ios": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.11"
* },
* "harmony": {
* "uniVer": "x",
* "unixVer": "5.07",
* "unixVaporVer": "5.07"
* }
* },
* "mp": {
* "weixin": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "5.07"
* }
* }
*/
blankFallback: 'turn-self' | 'copy-link-modal' | 'none'
}
type LocaleType = 'zh-Hans' | 'zh-Hant' | 'en' | 'fr' | 'la'
type LocaleMessages = {
emptyHref: string
popupBlocked: string
internalOpenFailed: string
copiedOpenInBrowserPrefix: string
copyFailedOpenInBrowser: string
}
const LINK_WEBVIEW_PAGE_PATH = '/uni_modules/uni-link-x/pages/link-webview'
const props = withDefaults(defineProps<Props>(), {
href: '',
target: '_self',
blankFallback: 'turn-self'
})
const emit = defineEmits<{
error: [message: string]
}>()
const appLanguage = (uni.getAppBaseInfo().appLanguage ?? 'en').toLowerCase()
function resolveLocaleType() : LocaleType {
if (
appLanguage.indexOf('zh-hant') == 0 ||
appLanguage.indexOf('zh-tw') == 0 ||
appLanguage.indexOf('zh-hk') == 0 ||
appLanguage.indexOf('zh-mo') == 0
) {
return 'zh-Hant'
}
if (appLanguage.indexOf('zh') == 0) {
return 'zh-Hans'
}
if (appLanguage.indexOf('fr') == 0) {
return 'fr'
}
if (appLanguage.indexOf('la') == 0 || appLanguage.indexOf('lat') == 0) {
return 'la'
}
return 'en'
}
function getLocaleMessages() : LocaleMessages {
const localeType = resolveLocaleType()
if (localeType == 'zh-Hans') {
return {
emptyHref: '链接地址不能为空',
popupBlocked: '浏览器拦截了新窗口',
internalOpenFailed: '应用中未找到uni-link组件下的link-webview页面',
copiedOpenInBrowserPrefix: '已复制链接,请使用外部浏览器打开:',
copyFailedOpenInBrowser: '复制链接失败,请手动复制链接并使用外部浏览器打开'
}
}
if (localeType == 'zh-Hant') {
return {
emptyHref: '連結地址不能為空',
popupBlocked: '瀏覽器封鎖了新視窗',
internalOpenFailed: '應用中未找到 uni-link 組件下的 link-webview 頁面',
copiedOpenInBrowserPrefix: '已複製連結,請使用外部瀏覽器開啟:',
copyFailedOpenInBrowser: '複製連結失敗,請手動複製連結並使用外部瀏覽器開啟'
}
}
if (localeType == 'fr') {
return {
emptyHref: 'L’URL ne peut pas être vide',
popupBlocked: 'Le navigateur a bloqué la nouvelle fenêtre',
internalOpenFailed: 'Échec de l\'ouverture de la page @uni_modules/uni-link-x/pages/link-webview',
copiedOpenInBrowserPrefix: 'Le lien a été copié. Veuillez l’ouvrir dans un navigateur externe :',
copyFailedOpenInBrowser: 'Échec de la copie du lien. Veuillez le copier manuellement et l’ouvrir dans un navigateur externe.'
}
}
if (localeType == 'la') {
return {
emptyHref: 'Inscriptio nexus vacua esse non potest',
popupBlocked: 'Navigator fenestram novam prohibuit',
internalOpenFailed: 'Pagina aperiri non potuit @uni_modules/uni-link-x/pages/link-webview',
copiedOpenInBrowserPrefix: 'Nexus descriptus est. Quaeso eum in navigatro externo aperi:',
copyFailedOpenInBrowser: 'Descriptio nexus defecit. Quaeso nexum manu describe et in navigatro externo aperi.'
}
}
return {
emptyHref: 'The link URL cannot be empty',
popupBlocked: 'The browser blocked the new window',
internalOpenFailed: 'Failed to open page @uni_modules/uni-link-x/pages/link-webview',
copiedOpenInBrowserPrefix: 'The link has been copied. Please open it in an external browser:',
copyFailedOpenInBrowser: 'Failed to copy the link. Please copy it manually and open it in an external browser.'
}
}
function showPrompt(content : string) {
uni.showModal({
content,
showCancel: false
})
}
function copyLinkAndPrompt(url : string) {
const messages = getLocaleMessages()
uni.setClipboardData({
data: url,
showToast: false,
success: () => {
showPrompt(messages.copiedOpenInBrowserPrefix + '\n' + url)
},
fail: () => {
showPrompt(messages.copyFailedOpenInBrowser)
}
})
}
function reportOpenError(message : string) {
emit('error', message)
}
function openInBuiltInWebview(url : string) {
uni.navigateTo({
url: `${LINK_WEBVIEW_PAGE_PATH}?url=${encodeURIComponent(url)}`,
success: () => {},
fail: () => {
// 异常情况下可能pages.json中漏配了本组件下的link-webview.uvue页面
reportOpenError(getLocaleMessages().internalOpenFailed)
}
})
}
function openURL() {
const url = props.href.trim()
if (url.length == 0) {
reportOpenError(getLocaleMessages().emptyHref)
return
}
if (props.target == '_self') {
openInBuiltInWebview(url)
}
else{
// _blank方式
// #ifdef WEB
const targetWindow = window.open(url, '_blank')
if (targetWindow != null) {
return
}
else if (props.blankFallback=="turn-self"){
openInBuiltInWebview(url)
return
}
else if(props.blankFallback=="copy-link-modal"){
copyLinkAndPrompt(url)
return
}
reportOpenError(getLocaleMessages().popupBlocked)
// #endif
// #ifdef MP
if (props.blankFallback=="turn-self"){
openInBuiltInWebview(url)
}
else if(props.blankFallback=="copy-link-modal"){
copyLinkAndPrompt(url)
}
// #endif
// #ifdef APP
try {
openSchema(url)
} catch (error) {
// 这里常见的情况是iOS设备在真机运行时缺少xcode环境编译openSchema失败
if (props.blankFallback=="turn-self"){
openInBuiltInWebview(url)
}
else if(props.blankFallback=="copy-link-modal"){
copyLinkAndPrompt(url)
}
else{
reportOpenError((error as Error).message) // 报错后发送错误事件,这里的错误原因未知,无法自行提前国际化
}
}
// #endif
}
}
</script>
<style>
</style>