0

I tried to implement a very simple Markdown formatter directive (just bold, emphasize, and strike-trough) to be a bit more independent from vue-18n formatting. The current directive looks like this:

    import _Vue from 'vue';
    
    const emphasize = (str: string) => {
      const matched = /(\*|_)(.*?)(\*|_)/gm;
      return str.replace(matched, '<em>$2</em>');
    };
    
    const strong = (str: string) => {
      const matched = /(\*\*|__)(.*?)(\*\*|__)/gm;
      return str.replace(matched, '<strong>$2</strong>');
    };
    
    const strikeThrough = (str: string) => {
      const matched = /~~(.*?)~~/gm;
      return str.replace(matched, '<s>$2</s>');
    };
    
    const fromMd = (str: string) => strikeThrough(emphasize(strong(str)));
    
    export default {
      install: (Vue: typeof _Vue): void => {
        /* eslint-disable no-param-reassign */
        Vue.directive('tmd', {
          bind(el: HTMLElement) {
            el.innerHTML = fromMd(el.innerHTML);
          },
          inserted(el: HTMLElement) {
            el.innerHTML = fromMd(el.innerHTML);
          },
          update(el: HTMLElement) {
            el.innerHTML = fromMd(el.innerHTML);
          },
        });
      },
    };

I use it like this:

<p v-tmd >{{ $t('path-to-translation', ) }}</p>

So far it works fine, BUT the problem is, that when I change the language, the directive seems not to be updated. It receives the updated event, but the el.innerHTML is not updated, so it renders the old one. What would be the best practice here to achieve this behavior?

1 Answer 1

1

I'm not sure why parsing el.innerHTML doesn't work, but you can parse the vnode text instead:

export default {
  install: Vue => {
    const childrenTextToMd = (el, binding, vnode) => {
      if (vnode.children) {
        el.innerHTML = vnode.children
          .map(child => fromMd(child.text))
          .join('')
      }
    }

    Vue.directive('tmd', {
      inserted: childrenTextToMd,
      update: childrenTextToMd
    })
  }
}

Side note: strikeThrough() has a replacement for $2, but there's only one capture group, so it should be $1.

demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.