版本说明
vue:2.x
katex: 0.11.x
安装
npm install katex
新建渲染的组件AutoKatex.vue
<template>
<div v-html="htmlData" :style="{display: isLineFeed?'block' : 'inline'}">
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import katex from 'katex'
import 'katex/dist/katex.min.css'
import { JSHelperUtil, StringUtil } from 'papio-h5'
@Component
export default class AutoKatex extends Vue {
private name = 'AutoKatex'
// 带有公式的源文本
@Prop({ default: '' }) readonly data!: string;
// 是否占用一行
@Prop({ default: true }) readonly isLineFeed!: boolean;
@Prop({ default: '$$' }) readonly delimiters!: string;
private htmlData = ''
private created () {
this.katexRender()
}
@Watch('data')
private dataChanged () {
this.katexRender()
}
private katexRender () {
const data = this.data
const delimitersLength = this.delimiters.length
if (StringUtil.isEmpty(data)) {
return
}
let pos = data.indexOf(this.delimiters)
const positions = []
while (pos > -1) {
positions.push(pos)
pos = data.indexOf(this.delimiters, pos + delimitersLength)
}
let htmlData = ''
if (positions.length <= 1) {
// 没有公式
htmlData = this.getSpanHtml(data)
} else {
// 存在公式
// 处理index=1
htmlData += this.getSpanHtml(data.substring(0, positions[0]))
// 遍历下标数据
for (let index = 1; index <= positions.length - 1; index++) {
const current = positions[index]
// 下标为奇数 则开始 偶数数为结束
if (index % 2 !== 0) {
const d = katex.renderToString(data.substring(positions[index - 1] + delimitersLength, current), { throwOnError: false })
htmlData += d
} else {
htmlData += this.getSpanHtml(data.substring(positions[index - 1] + delimitersLength, current))
}
}
htmlData += this.getSpanHtml(data.substring(positions[positions.length - 1] + delimitersLength))
}
this.htmlData = htmlData
}
private getSpanHtml (str): string {
// 换行替换为</br>
return `<span>${str}</span>`
}
}
</script>
<style scoped>
</style>
组件参数说明
- data: string 带有公式的源数据 如 P(A)=P(B)=P(C)=$$\dfrac{1}{4}$$
- isLineFeed: bool 是否占用一行
- delimiters: string 公式的标识符号 默认为$$
使用方法
<template xmlns:v-katex="http://www.w3.org/1999/xhtml">
<div>
<input v-model:value="inputValue"/>
<auto-katex :data="inputValue"></auto-katex>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import AutoKatex from '@/components/katex/AutoKatex.vue'
@Component({
components: {
AutoKatex
}
})
export default class CourseTopicEdit extends Vue {
private inputValue: string = ''
}
</script>
<style scoped>
</style>