Explore uniapp+vue3 parsing markdown syntax | uniapp keyboard support

Recently, I am trying to use uniapp+vue3 to develop an imitation chatgpt session function.

Insert image description here
As shown above: After testing, markdown syntax parsing is supported on the h5/App side/mini program side . After the keyboard is raised, the entire page and the top custom navigation bar will not be raised.

uniapp markdown parsing and syntax highlighting

markdown-itThe and plug-ins are used highlight.jsto implement markdown syntax parsing and code highlighting.

// 引入uniapp markdown插件
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'

Insert image description here

  • Initialize markdown plugin
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;display: block;border-radius: 5px;"><code>${
      
      html}</code></pre>`;
			htmlCode += '</div>'
		return htmlCode
	}
})
  • Parse markdown syntax
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
}

Call the parseNodes method in the session message.

<rich-text space="nbsp" :nodes="parseNodes(item.content)" @itemclick="handleItemClick"></rich-text>

Components in uniapp rich-textprovide itemclickmethods. Intercept click events (only supports a and img tags) and return the current node information event.detail={node}

// 复制代码
const handleItemClick = (e) => {
    
    
	console.log(e);
	let {
    
    attrs} = e.detail.node
	console.log({
    
    attrs});
	let {
    
    "code-data-index": codeDataIndex, "class": className} = attrs
	if(className == 'copy-btn'){
    
    
		uni.setClipboardData({
    
    
			data:copyCode[codeDataIndex],
			showToast:false,
			success() {
    
    
				uni.showToast({
    
    
					title: '复制成功',
					icon: 'none'
				});
			}
		})
	}
}

At this point, markdown syntax parsing can basically be supported.

Insert image description here

uniapp keyboard holds up the page problem

In uniapp, flex is used to layout a chat page. When the input box pops up with the keyboard, the entire page will be pushed up, causing the top navigation bar to disappear.
I was wondering if I could get the keyboard height when the keyboard pops up, and then add padding to the pop-up div layer. After some attempts, this solution worked~~

Insert image description here
As shown above: Add a view layer to the outer layer of the editor, and set padding-bottom to the keyboard pop-up height.

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

The 70 here can be adjusted according to the actual situation.

Then get the keyboard bounce height in onMounted.

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

Insert image description here
After some debugging, when the keyboard pops up, only the content area is pushed up, but the custom navigation bar at the top will not be pushed up, which perfectly solves the problem of the entire page being pushed up.

If you have other better solutions, please feel free to discuss them together~~

Guess you like

Origin blog.csdn.net/yanxinyun1990/article/details/131349705