uniapp+vite解析markdown语法模板|uniapp键盘弹起问题

624 阅读2分钟

这次主要给大家分享下uniapp构建的多端项目如何支持chatgpt会话中markdown语法高亮渲染功能,以及uniapp软键盘导致页面顶起问题的解决方案。

Screenshot_2023-06-25-11-25-17-427_uni.UNI2A0CB34.jpg

Screenshot_2023-06-25-11-24-17-968_uni.UNI2A0CB34.jpg

如上图,已经支持h5/小程序/App端markdown语法解析及高亮功能。

8b4da3b3d9b511e679ba7a31b1255e92_1289798-20230625082127594-1754336575.gif

45e987f46ef2c9a07d1ca2ce5199a232_1289798-20230625082232994-503235810.gif

演示了在App端+小程序端键盘弹起,整体页面及自定义顶部条不会被撑起的问题。

uniapp解析markdown高亮

如何在uniapp中支持多端解析markdown语法及代码高亮?这里使用了markdown-it和highlight.js插件处理。

// 引入markdown-it和highlight.js插件
import MarkdownIt from '@/plugins/markdown-it.min.js'
import hljs from '@/plugins/highlight/highlight.min.js'
// import '@/plugins/highlight/github-dark.min.css'
import '@/plugins/highlight/atom-one-light.css'
import parseHtml from '@/plugins/html-parser.js'

插件的话,大家自行去安装下载。

  • 初始化markdown插件
const markdown = MarkdownIt({
   html: true,
   highlight: function(str, lang) {
    let preCode = ""
    try {
      preCode = hljs.highlightAuto(str).value
    } catch (err) {
      preCode = markdown.utils.escapeHtml(str);
    }
    // 自定义行号
    const lines = preCode.split(/\n/).slice(0, -1)
    let html = lines.map((item, index) => {
      // 去掉空行
      if( item == ''){
        return ''
      }
      return '<li><span class="line-num" data-line="' + (index + 1) + '"></span>' + item +'</li>'
    }).join('')
    html = '<ol style="padding: 0px 30px;">' + html + '</ol>'
    
    // 代码复制
    copyCode.push(str)
    let htmlCode = `<div class="markdown-wrap">`
      // #ifndef MP-WEIXIN
        htmlCode += `<div style="color: #aaa;text-align: right;font-size: 12px;padding:8px;">`
          htmlCode += `${lang}<a class="copy-btn" code-data-index="${copyCode.length - 1}" style="margin-left: 8px;">复制代码</a>`
        htmlCode += `</div>`
      // #endif
        htmlCode += `<pre class="hljs" style="padding:0 8px;margin-bottom:5px;overflow: auto;border-radius: 5px;"><code>${html}</code></pre>`;
      htmlCode += '</div>'
    return htmlCode
  }
})
  • 解析markdown语法结构
const parseNodes = (value) => {
   if(!value) return
   
   let htmlString = ''
  if (value.split("```").length % 2) {
    let msgContent = value
    if(msgContent[msgContent.length-1] != '\n'){
      msgContent += '\n'
    }
    htmlString = markdown.render(msgContent)
  } else {
    htmlString = markdown.render(msgContent.value)
  }
  
  // #ifndef APP-NVUE
  return htmlString
  // #endif
  
  // nvue模式下将htmlString转成htmlArray,其他情况rich-text内部转
  // 注:本示例项目还没使用nvue编译
  // #ifdef APP-NVUE
  return parseHtml(htmlString)
  // #endif
}
  • 渲染结构显示
<rich-text space="nbsp" :nodes="parseNodes(item.content)" @itemclick="handleItemClick"></rich-text>

005360截图20230625105156152.png

008360截图20230625105142315.png

经过一番测试,已经能很好的支持h5/小程序/App端了。

接下来分享下在uniapp软键盘撑起页面问题。

uniapp导致页面布局撑起

点击input输入框 键盘弹起后会顶跑页面。导致顶部自定义导航栏会不见了

1b35695eba2887b7542481cffc3b2fa2_1289798-20230625084656847-1517998451.png

onMounted(() => {
  nextTick(() => {
    scrollToLast()
  })
  
  // #ifndef H5
  uni.onKeyboardHeightChange(e => {
    keyboardHeight.value = e.height
    // 在dom渲染完毕 滚动到最后一条消息
    nextTick(() => {
      scrollToLast()
    })
  })
  // #endif
})

通过uniapp监听键盘高度变化,赋值给padding-bottom为键盘高度。

const fixPaddingBottom = computed(() => {
  let keyH = keyboardHeight.value > 50 ? keyboardHeight.value - 50 : keyboardHeight.value
  return (keyH || 10) + 'px'
})

目前这样可以解决键盘被弹起后,页面整体上移撑跑问题。

如果小伙伴们有其它解决方法,欢迎下方留言讨论哈~~

image.png