diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 5c2e75a42c6a4d406ed5ad56cfbf701ced61f31c..5aec24f12931dc20db51640d3b3f59f798e909a9 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -67,6 +67,9 @@ const config = { .end() .plugin('convert-header') .use(headerPlugin) + }, + extendMarkdown: md => { + md.use(require('./markdown/normallizeLink')) } } } diff --git a/docs/.vuepress/markdown/normallizeLink.js b/docs/.vuepress/markdown/normallizeLink.js new file mode 100644 index 0000000000000000000000000000000000000000..60a0e83ab97db0e0ab329914ac3b7b2557adf0a7 --- /dev/null +++ b/docs/.vuepress/markdown/normallizeLink.js @@ -0,0 +1,25 @@ +const fs = require('fs') +const folderNames = [] +fs.readdirSync('docs').forEach(item => { + fs.lstatSync(`docs/${item}`).isDirectory() && folderNames.push(item) +}) + +function isExternal(path) { + return /^[a-z]+:/i.test(path) +} + +function normalizeLink(url) { + if (!url.startsWith('/') && folderNames.some(item => url.startsWith(item))) { + return '/' + url + } + return url +} + +module.exports = function (md) { + md.normalizeLink = (function (oldNormalizeLink) { + return function (url) { + url = isExternal(url) ? url : normalizeLink(url) + return oldNormalizeLink.bind(this)(url) + } + })(md.normalizeLink) +} \ No newline at end of file diff --git a/docs/.vuepress/theme/config/redirectRouter.js b/docs/.vuepress/theme/config/redirectRouter.js new file mode 100644 index 0000000000000000000000000000000000000000..aa1247eb76d711537cff52a7dc825568b45fbecf --- /dev/null +++ b/docs/.vuepress/theme/config/redirectRouter.js @@ -0,0 +1,95 @@ +const routerMap = { + '/collocation/frame/lifecycle#页面生命周期': '/tutorial/page.html#lifecycle', + '/collocation/frame/lifecycle#应用生命周期': '/collocation/App.html#applifecycle', + '/collocation/frame/lifecycle': '/collocation/App.html#applifecycle', + '/collocation/frame/communication': '/tutorial/page.html#页面通讯', + '/collocation/frame/lifecycle#page': '/collocation/App.html#applifecycle', + '/collocation/frame/lifecycle#component': '/tutorial/page.html#componentlifecycle', + '/collocation/frame/timer': '/api/timer.html', + '/collocation/auto/hbuilderx-extension/index': '/worktile/auto/hbuilderx-extension/', + '/collocation/auto/quick-start': '/worktile/auto/quick-start.html', + '/collocation/auto/uniapp-cli-project': '/worktile/auto/uniapp-cli-project.html', + '/collocation/i18n': '/worktile/i18n.html', + '/collocation/env': '/tutorial/env.html', + '/collocation/ssr': '/tutorial/ssr.html', + '/collocation/frame/window#getapp': '/tutorial/page.html#getapp', + + '/component/mp-weixin-plugin': '/tutorial/mp-weixin-plugin.html', + '/component/uniui': '/component/uniui/uni-ui.html', + + '/frame': '/tutorial/', + '/frame#renderjs': '/tutorial/renderjs.html', + '/frame#css变量': '/tutorial/syntax-css.html#css-变量', + '/frame#css引入静态资源': '/tutorial/page-static-assets.html', + '/frame#js文件引入': '/tutorial/page-script.html', + '/frame#字体图标': '/tutorial/syntax-css.html#字体图标', + '/frame#wxs': '/tutorial/miniprogram-subject.html#wxs', + '/frame#flex布局': '/tutorial/syntax-css.html#flex-布局', + '/frame#npm支持': '/tutorial/page-script.html#npm支持', + '/frame#尺寸单位': '/tutorial/syntax-css.html#尺寸单位', + '/frame#目录结构': '/tutorial/project.html#目录结构', + '/frame#路由跳转': '/tutorial/page.html#路由跳转', + '/frame#小程序组件支持': '/tutorial/miniprogram-subject.html', + '/frame#小程序自定义组件支持': '/tutorial/miniprogram-subject.html#小程序自定义组件支持', + '/frame#判断平台': '/worktile/running-env.html#判断平台', + '/frame#typescript-支持': '/tutorial/typescript-subject.html#typescript-支持', + '/frame#全局样式与局部样式': '/tutorial/syntax-css.html#全局样式与局部样式', + '/frame#注意事项-1': '/tutorial/renderjs.html#注意事项', + + '/platform': '/tutorial/platform.html', + + '/api/extend/native-plugin': '/plugin/native-plugin.html', + '/use-html5plus': '/tutorial/use-html5plus.html', + + '/vue-components': '/tutorial/vue-components.html', + '/vue-components.html': '/tutorial/vue-components.html', + '/vue-basics': '/tutorial/vue-basics.html', + '/vue-api': '/tutorial/vue-api.html', + '/vue-vuex': '/tutorial/vue-vuex.html', + '/vue3-api': '/tutorial/vue3-api.html', + '/vue3-basics': '/tutorial/vue3-basihybridcs.html', + '/vue3-vuex': '/tutorial/vue3-vuex.html', + '/migration-to-vue3': '/tutorial/migration-to-vue3.html', + + '/nvue-outline': '/tutorial/nvue-outline.html', + '/nvue-api': '/tutorial/nvue-api.html', + '/nvue-css': '/tutorial/nvue-css.html', + + '/uniCloud/database': '/uniCloud/clientdb.html', + + '/plugin/hybrid': '/hybrid.html', + '/adapt': '/tutorial/adapt.html', + '/share': '/api/plugins/share.html', + '/performance': '/tutorial/performance.html', + '/use-weex': '/tutorial/nvue-outline.html', + '/uni_modules': '/plugin/uni_modules.html', + '/snippet': '/tutorial/snippet.html', +} + +export default ({ fullPath, path, hash }) => { + fullPath = decodeURIComponent(fullPath) + const matchFullPath = routerMap[fullPath]; + if (matchFullPath) { + return { + path: matchFullPath, + replace: true + } + } + + const matchPath = routerMap[path] + if (matchPath) { + return { + path: matchPath, + hash, + replace: true + } + } + + if (path.indexOf('/app-') === 0 || path.indexOf('/android-') === 0 || path.indexOf('/ios-') === 0) { + return { + path: `/tutorial${path}`, + hash, + replace: true + } + } +} \ No newline at end of file diff --git a/docs/.vuepress/theme/enhanceApp.js b/docs/.vuepress/theme/enhanceApp.js index d0a399e95c9d3b4e9af284cb3345df2f1d490aec..9a98dc68b33b411bae9dcf68e9875c3a9a927ee8 100644 --- a/docs/.vuepress/theme/enhanceApp.js +++ b/docs/.vuepress/theme/enhanceApp.js @@ -1,3 +1,5 @@ +import getRedirectRouter from './config/redirectRouter'; + function handleRedirectForCleanUrls(router, to) { if (isRouteExists(router, to.path)) { return to.path @@ -31,25 +33,32 @@ function isRouteExists(router, path) { } function handlePath(router, to) { + // 重定向路由表 + const redirectRouter = getRedirectRouter(to) + if (redirectRouter) return redirectRouter + const id = to.query.id + const hash = decodeURIComponent(id || to.hash).toLowerCase() const redirectPath = handleRedirectForCleanUrls(router, to) - if (id) { return { path: redirectPath, - hash: '#' + decodeURIComponent(id.toLowerCase()) + replace: true, + hash } } if (redirectPath !== to.path) { return { path: redirectPath, - hash: decodeURIComponent(to.hash).toLowerCase() + replace: true, + hash } } if (/\bREADME\b/.test(to.path)) { return { path: to.path.replace(/\bREADME\b/, ''), - hash: decodeURIComponent(to.hash).toLowerCase() + replace: true, + hash } } } diff --git a/docs/component/component-selection.md b/docs/component/component-selection.md index bfc792b7068a192da6abb6a3a4e9acd0f32a1163..0862c4f027099bf177c85d4e3fc07e23a52c0fce 100644 --- a/docs/component/component-selection.md +++ b/docs/component/component-selection.md @@ -68,7 +68,7 @@ uni ui有如下优势: #### 插件市场更多组件 插件市场,[https://ext.dcloud.net.cn](https://ext.dcloud.net.cn),有各种玲琅满目的组件、模板。 其中成套的全端兼容ui库包括: -- [uViewUI](www.uviewui.com):整合了非常多组件,功能丰富、文档清晰,但不支持nvue +- [uViewUI](https://www.uviewui.com):整合了非常多组件,功能丰富、文档清晰,但不支持nvue - [colorUI css库](http://ext.dcloud.net.cn/plugin?id=239):颜值很高,css库而非组件 - [unify UI](https://ext.dcloud.net.cn/plugin?id=2251):全端支持的组件库,侧重nvue - [mypUI](https://ext.dcloud.net.cn/plugin?id=2190):全端支持的组件库,侧重nvue