Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a smaple of VUE3+VITE5+TS , it works, I spend 48H , pls enjoy... #2191

Open
digitalboy opened this issue Dec 4, 2023 · 1 comment
Open

Comments

@digitalboy
Copy link

<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 { }
}
@hsellik
Copy link
Contributor

hsellik commented Dec 8, 2023

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants