Explora la sintaxis de rebajas de análisis de uniapp+vue3 | compatibilidad con el teclado uniapp

Recientemente, estoy intentando usar uniapp+vue3 para desarrollar una función de sesión de chatgpt de imitación.

Insertar descripción de la imagen aquí
Como se muestra arriba: después de la prueba, el análisis de sintaxis de rebajas es compatible con h5/lado de la aplicación/lado del mini programa . Después de levantar el teclado, no se levantará toda la página ni la barra de navegación personalizada superior.

análisis de rebajas de uniapp y resaltado de sintaxis

markdown-itLos complementos y se utilizan highlight.jspara implementar el análisis de sintaxis de rebajas y el resaltado de código.

// 引入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'

Insertar descripción de la imagen aquí

  • Inicializar el complemento de rebajas
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
	}
})
  • Analizar la sintaxis de rebajas
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
}

Llame al método parseNodes en el mensaje de sesión.

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

Los componentes de uniapp rich-textproporcionan itemclickmétodos. Intercepta eventos de clic (solo admite etiquetas a e img) y devuelve la información del nodo actual 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'
				});
			}
		})
	}
}

En este punto, básicamente se puede admitir el análisis de sintaxis de rebajas.

Insertar descripción de la imagen aquí

El teclado uniapp retrasa el problema de la página.

En uniapp, flex se usa para diseñar una página de chat. Cuando aparece el cuadro de entrada con el teclado, toda la página se empujará hacia arriba, lo que hará que la barra de navegación superior desaparezca.
Me preguntaba si podría obtener la altura del teclado cuando aparezca el teclado y luego agregar relleno a la capa div emergente. Después de algunos intentos, esta solución funcionó ~~

Insertar descripción de la imagen aquí
Como se muestra arriba: agregue una capa de vista a la capa exterior del editor y establezca padding-bottom en la altura de la ventana emergente del teclado.

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

Los 70 aquí se pueden ajustar según la situación real.

Luego obtenga la altura de rebote del teclado en onMounted.

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

Insertar descripción de la imagen aquí
Después de un poco de depuración, cuando aparece el teclado, solo se empuja hacia arriba el área de contenido, pero la barra de navegación personalizada en la parte superior no se empuja hacia arriba, lo que resuelve perfectamente el problema de que se empuje hacia arriba toda la página.

Si tiene otras soluciones mejores, no dude en discutirlas juntos ~~

Supongo que te gusta

Origin blog.csdn.net/yanxinyun1990/article/details/131349705
Recomendado
Clasificación