0

I'm writing a webpage which requires localisation. So I need to put paragraphs into variables:

index.vue

      <div class="descrip">
        <p class="dTitle">{{$t('message.instructionTitle')}}</p>
        <p>{{$t('message.instructionFirst')}}</p>
        <p>{{$t('message.instructionSecond')}}</p>
        <p>{{$t('message.instructionThird')}}</p>
        <p>{{$t('message.instructionForth')}}</p>
        <p>{{$t('message.instructionFifth')}}</p>
      </div>

index.js

const messages = {
  en: {
    message: {
      instructionFirst: "Hello, world!",
      instructionSecond: "...",
      //...
    },
  },
  jp: {
    message: {
      //...
    },
  },
  //..
};
export default messages;

If I want to add some style (e.g. color=red) to some words within the paragraph (e.g. message.instructionFirst), what should I do besides separate those words from message.instructionFirst?


Edit:

For example, instructionFirst is like:

Hello, world!

I want:

Hello, <mark style="color:red;">world</mark>!
tony19
  • 125,647
  • 18
  • 229
  • 307
TaihouKai
  • 133
  • 11
  • @LawrenceCherone It's only a way to show that "world" is red here. I don't know how to give it a color in Stack Overflow... – TaihouKai May 23 '21 at 15:56
  • 2
    once you work out why/how the word *world* will be hightlighted you can then use js, then use `v-html="highlight($t('message.instructionFirst'), $t('message.instructionFirstWord'))"` to render it, instructionFirstWord *or similar* being the word in the specific lang, see: https://stackoverflow.com/questions/8644428/how-to-highlight-text-using-javascript make a method/mixin/component etc – Lawrence Cherone May 23 '21 at 19:10

2 Answers2

1

As suggested in a comment, you could use a component method to wrap the target words with the styled markup, and use v-html to apply the results:

  1. Create a method (named "highlight") that searches a given string for a word, and returns HTML that surrounds the target words with the desired markup:

    export default {
      methods: {
        highlight(searchWord, input) {
          return input.replace(new RegExp(searchWord, 'ig'), w => `<mark style="color:red">${w}</mark>`)
        }
      }
    }
    
  2. In your template, use the v-html directive to bind the result of highlight() for each translation to a p's innerHTML:

    <p v-html="highlight($t('message.instructionFirstHighlight'), $t('message.instructionFirst'))"></p>
    

demo

tony19
  • 125,647
  • 18
  • 229
  • 307
0

I have an idea, how about the following lines:

const messages = {
  redKeys: ['instructionFirst'],
  en: {
    message: {
      //...
    },
  },
  jp: {
    message: {
      //...
    },
  },
  //..
};
export default messages;

then, replace your vue templates with the following lines:

     <div class="descrip">
        <p 
           v-for="(value, key, index) in message"
           v-key="index"
           :class="{
             dTitle: key === 'message.instructionTitle'
             red: redKeys.includes[key],
           }"
        >{{$t(value)}}</p>
      </div>
Dharman
  • 30,962
  • 25
  • 85
  • 135
newbie
  • 66
  • 2
  • I am sorry that you might misunderstood what I meant. I want **some words within** `instructionFirst` to be red, not the whole `instructionFirst` to be red. (See updated question) – TaihouKai May 23 '21 at 15:50