@lidni

Изменение шрифта,цвета, расположения, размера текста в markdown?

Я создал свое меню для редактирования текста выглядит оно таким образом:
spoiler
6603d556c383d880020827.png


пытался реализовать изменение шрифта(жирный, курсив...)
код получился таким (использовал я vuex) :
spoiler
<template>
  <div class="main-menu-edit">
    <div class="section">
      <div class="row">
        <div class="col">
          <div class="first box">
            <form>
              <select id="font-size" name="text-size" @change="handleFontSizeChange">
                <option value="h1">Заголовок 1</option>
                <option value="h2">Заголовок 2</option>
                <option value="h3">Заголовок 3</option>
                <option value="p">Параграф</option>
              </select>
            </form>
          </div>
          <div class="second box">
            <button type="button"
                    @click="handleBoldText">
                    <i class="fa-solid fa-bold"></i>
            </button>
            <button type="button"
                    @click="handleItalicText">
                    <i class="fa-solid fa-italic"></i>            
            </button>
            <button type="button"
                    @click="handleUnderlineText">
                    <i class="fa-solid fa-underline"></i>
            </button>
            <button type="button"
                    @click="handleStrikethroughText">
                    <i class="fa-solid fa-strikethrough"></i>
            </button>
          </div>
          <div class="third box">
            <button type="button"
                    @click="alignLeft">
                    <i class="fa-solid fa-align-left"></i>
            </button>
            <button type="button"
                    @click="alignCenter">
                    <i class="fa-solid fa-align-center"></i>
            </button>
            <button type="button"
                    @click="alignRight">
                    <i class="fa-solid fa-align-right"></i>
            </button>
            <button type="button"
                    @click="alignJustify">
                    <i class="fa-solid fa-align-justify"></i>
            </button> 
          </div>
          <div class="fourth box">
            <button type="button">
                    <i class="fa-solid fa-image"></i>
            </button>
            <button type="button">
                    <i class="fa-solid fa-video"></i>            
            </button>
            <button class="link" type="button">
                    <i class="fa-solid fa-link"></i>            
            </button>
            <button type="button">
                    <i class="fa-solid fa-table"></i>            
            </button>
            <button type="button" @click="applyColor">
            <i class="fa-solid fa-paint-brush"></i>
            </button>
            <input type="color" v-model="newColor">
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex';

export default {
  data() {
    return {
      newColor: '',
    };
  },
  computed: {
    ...mapState(['color']),

  },
  created() {
    this.newColor = this.color; 
  },
  watch: {
    newColor(event) {
      this.updateColor(event); 
    }
  },
  methods: {
    ...mapActions(['updateColor', 'updateSelectedText']),
    insertMarkdownText(textToInsert) {
      const textarea = this.$store.getters.getTextarea;
      const startPos = textarea.selectionStart;
      const endPos = textarea.selectionEnd;
      let text = textarea.value;

      if (this.$store.state.selectedText === "" || this.$store.state.selectedText === " ") {

      }
      else {
        text = text.substring(0, startPos) + textToInsert + text.substring(startPos, endPos) + textToInsert + text.substring(endPos);
        textarea.value = text;
        this.markdownContent = textarea.value;
      }
    },

    handleBoldText() {
      this.insertMarkdownText('**');
    },

    handleItalicText() {
      this.insertMarkdownText('_');
    },
    handleUnderlineText() { 
      const textarea = this.$store.getters.getTextarea;
      const startPos = textarea.selectionStart;
      const endPos = textarea.selectionEnd;
      let text = textarea.value;

      if (this.$store.state.selectedText === "" || this.$store.state.selectedText === " ") {

      }
      else {
        text = text.substring(0, startPos) + '<u>' + text.substring(startPos, endPos) + '</u>' + text.substring(endPos);
        textarea.value = text;
        this.markdownContent = textarea.value;
      }
    },
    handleStrikethroughText() { 
      this.insertMarkdownText('~');
    },
    alignLeft() { 
      this.insertMarkdownText('');
    },
    alignCenter() { 
      const textarea = this.$store.getters.getTextarea;
      const startPos = textarea.selectionStart;
      const endPos = textarea.selectionEnd;
      let text = textarea.value;

      if (this.$store.state.selectedText === "" || this.$store.state.selectedText === " ") {

      }
      else {
        text = text.substring(0, startPos) + '<center>' + text.substring(startPos, endPos) + '</center>' + text.substring(endPos);
        textarea.value = text;
        this.markdownContent = textarea.value;
      }
    },
    alignRight() { 
      const textarea = this.$store.getters.getTextarea;
      const startPos = textarea.selectionStart;
      const endPos = textarea.selectionEnd;
      let text = textarea.value;

      if (this.$store.state.selectedText === "" || this.$store.state.selectedText === " ") {

      }
      else {
        text = text.substring(0, startPos) + '<p align="right">' + text.substring(startPos, endPos) + '</p>' + text.substring(endPos);
        textarea.value = text;
        this.markdownContent = textarea.value;
      }
    },
    alignJustify() { 
      this.insertMarkdownText('|');

    },
    applyColor() {
      this.updateColor(this.newColor);
      this.colorText();

  },
    colorText() {
      const textarea = this.$store.getters.getTextarea;
      const startPos = textarea.selectionStart;
      const endPos = textarea.selectionEnd;
      const selectedText = this.$store.state.selectedText;
      let text = textarea.value;

      if (selectedText === "" || selectedText === " ") {
        return;
      }

      const coloredText = `<font color="${this.color}">${selectedText}</font>`;
      const fontTagRegex = /<font color="#[0-9a-fA-F]{6}">.*?<\/font>/g;
      const existingFontTags = text.match(fontTagRegex);

      if(existingFontTags){
          existingFontTags.forEach((tag) => {
              if(tag.includes(selectedText)){
                  text = text.replace(tag, tag.replace(selectedText, coloredText));
              }
          });
      } else {
          text = text.substring(0, startPos) + coloredText + text.substring(endPos);
      }

      textarea.value = text;
      this.markdownContent = textarea.value;
    },
  }
};
</script>


store.ts
import { Store } from 'vuex';

interface RootState {
  selectedText: string;
  textarea: string;
  setflag: boolean;
  setpreview: boolean;
  selectedTitle: string;
  articleContent: string;
  color: string;
}

const store = new Store<RootState>({
  state: {
    selectedText: '', // Выбранный текст
    textarea: null,
    flag: false,
    preview: false,
    selectedTitle: '',
    color: "#000000",
  },
  mutations: {
    setSelectedText(state, text) {
      state.selectedText = text;
    },
    setTextarea(state, textarea) {
      state.textarea = textarea;
    },
    setflag(state, boolean) { 
      state.flag = boolean;
    },
    setpreview(state, boolean) { 
      state.preview = boolean;
    },
    setSelectedTitle(state, text) { 
      state.selectedTitle = text;
    },
    setArticleContent(state, text) { 
      state.articleContent = text
    },
    setColor(state, text) { 
      state.color = text
    },
    

  },
  actions: {
    updateColor({ commit }, newColor) {
      commit('setColor', newColor);
    },
    updateSelectedText({ commit }, text) {
      commit('setSelectedText', text);
    },
    updateTextarea({ commit }, textarea) {
      commit('setTextarea', textarea);
    },

  },
  getters: {
    getColor: state => state.color,
    getSelectedText: state => state.selectedText,
    getTextarea: state => state.textarea,
  }
});

export default store;


все работает топорно, никак не могу придумать, чтобы сделать с кодом. Помогите оптимизировать и улучшить функционал кода.
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы