nhatimme
nhatimme

Reputation: 421

Vue Language dropdown show current language

I have a component named: DropdownLanguage.vue

Objective: I want to display the current active language by default at :text="selectedOptionDropdown". Like languages.name (e.g. English). I'm stuck how to manage this.

<template>
  <b-dropdown id="dropdown-buttons" :text="selectedOptionDropdown" class="m-2">
      <template v-for="(item, i) in languages">
        <b-dropdown-item-button class="eslanguage" v-bind:data-lang="item.lang" :key="i" @click="selectedLanguage">{{ item.name }}</b-dropdown-item-button>
    </template>
  </b-dropdown>
</template>

<script>
import i18nService from "@/core/services/i18n.service.js";

export default {
  name: "ESDropdownLanguage",
  data() {
    return {
      languages: i18nService.languages,
      selectedOptionDropdown: ''
    };
  },
  methods: {
    selectedLanguage(e) {
        const el = e.target.closest("eslanguage");
        const lang = el.getAttribute("data-lang");

        i18nService.setActiveLanguage(lang);
    },
    selectedOptionDropdown() {
     // No idea what to do
    }
  },
  computed: {
  }
};
</script>

Other file:

const i18nService = {
  defaultLanguage: "en",

  languages: [
    {
      lang: "en",
      name: "English",
      flag: process.env.BASE_URL + "media/svg/flags/226-united-states.svg"
    },
    {
      lang: "nl",
      name: "Nederlands",
      flag: process.env.BASE_URL + "media/svg/flags/237-netherlands.svg"
    }
  ],

  /**
   * Keep the active language in the localStorage
   * @param lang
   */
  setActiveLanguage(lang) {
    localStorage.setItem("language", lang);
  },

  /**
   * Get the current active language
   * @returns {string | string}
   */
  getActiveLanguage() {
    return localStorage.getItem("language") || this.defaultLanguage;
  }
};

export default i18nService;

Upvotes: 0

Views: 1785

Answers (1)

tauzN
tauzN

Reputation: 7001

Add v-model to the dropdown, and use computed properties.

Here is a working example: Vue SFC Playground

<template>
  <select v-model="language">
      <option :value="item.lang" v-for="(item, i) in languages">
        {{ item.name }}
    </option>
  </select>
</template>

<script>
export default {
  computed: {
    languages() {
      return i18nService.languages
    },
    language: {
      get(){
        return i18nService.getActiveLanguage()
      },
      set(lang){
        i18nService.setActiveLanguage(lang)
      }
    }
  }
};

const i18nService = {
  defaultLanguage: "en",
  languages: [
    {
      lang: "en",
      name: "English",
    },
    {
      lang: "nl",
      name: "Nederlands",
    }
  ],
  setActiveLanguage(lang) {
    localStorage.setItem("language", lang);
  },
  getActiveLanguage() {
    return localStorage.getItem("language") || this.defaultLanguage;
  }
};
</script>

If you need Bootstrap, I would recommend b-form-select instead:

And change your language objects to use value and text

<template>
    <b-form-select v-model="language" :options="languages"></b-form-select>
</template>
<script>
export default {
  computed: {
    languages() {
      return i18nService.languages
    },
    language: {
      get(){
        return i18nService.getActiveLanguage()
      },
      set(lang){
        i18nService.setActiveLanguage(lang)
      }
    }
  }
};

const i18nService = {
  defaultLanguage: "en",
  languages: [
    {
      value: "en",
      text: "English",
    },
    {
      value: "nl",
      text: "Nederlands",
    }
  ],
  setActiveLanguage(lang) {
    localStorage.setItem("language", value);
  },
  getActiveLanguage() {
    return localStorage.getItem("language") || this.defaultLanguage;
  }
};
</script>

Upvotes: 1

Related Questions