mathlive
mathlive copied to clipboard
a smaple of VUE3+VITE5+TS , it works, I spend 48H , pls enjoy...
<template>
<div ref="mathfieldContainer"></div>
</template>
<script lang="ts">
import '../../node_modules/mathlive/dist/mathlive-fonts.css';
import { ref, onMounted } from 'vue';
import { MathfieldElement } from 'mathlive';
export default {
setup() {
const mathfieldContainer = ref<HTMLElement | null>(null);
const mathfield = ref<MathfieldElement | null>(null);
onMounted(() => {
mathfield.value = new MathfieldElement();
if (mathfieldContainer.value) {
mathfieldContainer.value.appendChild(mathfield.value as Node);
}
});
return {
mathfieldContainer,
mathfield
};
},
};
</script>
// src/types/mathlive.d.ts
import { MathfieldElement as MathfieldElementBase } from 'mathlive';
declare module 'mathlive' {
export class MathfieldElement extends MathfieldElementBase { }
}
Here is an alternative solution:
<template>
<math-field :id="id" v-model="modelValue" @input="handleChange">
{{ modelValue }}
</math-field>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { MathfieldOptions } from 'mathlive/dist/types/options';
import MathfieldElement from 'mathlive/dist/types/mathfield-element';
interface MathFieldProps {
id: string;
modelValue: string;
options?: Partial<MathfieldOptions>;
}
const props = defineProps<MathFieldProps>();
// Safe to delete when not using methods from the element
const mathfield = ref<MathfieldElement | null>(null);
const emit = defineEmits(['update:modelValue']);
const modelValue = ref(props.modelValue);
watch(
() => props.modelValue,
() => {
if (props.modelValue !== modelValue.value) {
modelValue.value = props.modelValue;
}
},
);
// Safe to delete when not using methods from the element
onMounted(() => {
mathfield.value = document.getElementById(props.id) as MathfieldElement;
});
const handleChange = (event: InputEvent): void => {
const target = event.target as MathfieldElement;
emit('update:modelValue', target.getValue());
};
// Safe to delete when not using methods from the element
function getValue(): string | undefined {
return mathfield.value?.getValue();
}
</script>
Usage:
<VueMathField id="field-1" v-model="formula" />
<p>Value: {{ formula }}</p>
To access the original math-field methods, you create additional functions in the VueMathfield component and use ref:
<template>
<VueMathfield ref="mathfieldRef" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
import VueMathfield from "@/location/to/VueMathfield.vue";
// declare a ref to hold the element reference
// the name must match template ref value
const mathfieldRef = ref(null)
onMounted(() => {
mathfieldRef.value.getValue()
})
</script>
Additional approach could be getting the element by id in the parent, but the child component might dissapear, so it's not as robust.
@digitalboy , could you elaborate on how to use the declare module feature? Perhaps it's better than using ref?