Vue+iview项目 使用i18n 插件,无法国际化后端返回动态菜单?

这里是菜单遍历,不知道语法怎么写,用i18n。求大佬指教一二。
i18n我会用来国际化静态页面的数据,像这种动态数据我找遍了也没找合适的方法来国际化
这就是动态的菜单

        <template v-for="item in menuList">        
              <template>
                    <Submenu :name="item.name" :key="item.name">
                        
                      <!-- 父菜单 -->
                      <template slot="title">
                        <Icon :type="item.icon" :size="iconSize"></Icon>
                        <span class="layout-text">{{ itemTitle(item) }}</span>   <!-- {{$t('main.Automaticlogin')}} -->
                      </template>
                      
                      <!-- 子菜单 -->
                     <template v-for="child in item.children">
                        <MenuItem :name="child.name" :key="'menuitem' + child.name">
                          <Icon :type="child.icon" :size="iconSize" :key="'icon' + child.name"></Icon>
                          <span class="layout-text" :key="'title' + child.name">{{ itemTitle(child) }}</span>
                        </MenuItem>
                      </template>
                  
                </Submenu>
              </template>
        </template>

使用的vue组件props 父子组件传值,请问各位大佬,怎么国际化后端传递的数据

<script>
export default {
  name: "sidebarMenu",
  data() {
    return {
      singleOpenName: [],      
    };
  },
  props: {
    menuList: Array,
    iconSize: Number,
    menuTheme: {
      type: String,
      default: "dark"
    },
    openNames: {
      type: Array
    }
  },
  methods: {
    changeMenu(active) {
      this.$emit("on-change", active);
    },
    handleSelect(name) {
      this.$emit("on-select", name);
    },
    itemTitle(item) {
      return item.title;
    },
    getOpenedNamesByActiveName(name) {
      return this.$route.matched
        .map(item => item.name)
        .filter(item => item !== name);
    }
  },
  updated() {
    this.$nextTick(() => {
      if (this.$refs.sideMenu) {
        this.$refs.sideMenu.updateOpened();
      }
    });
  },
  watch: {
    // 监听路由变化
    $route(to, from) {
      this.singleOpenName = [this.$route.matched[0].name];
    }
  },
  mounted() {
    this.singleOpenName = [this.$route.matched[0].name];
  }
};
</script>
阅读 2.4k
2 个回答
新手上路,请多包涵

要么后端直接返回翻译好的语言,要么就是前端本地翻译好,但是加一次东西前端就得翻译一次,多语言真是烦死了image.png

先讲一个最简单无脑的方式,后端返回的动态路由表里面会有 fullpath 或者其他可以作为 key 键的信息。
然后你在国际化的时候就是用这些唯一值作为 key 就行了,当然也可以直接使用中文的。
比如说:

<Submenu :name="item.name" :key="item.name">
  <!-- 父菜单 -->
  <template slot="title">
    <Icon :type="item.icon" :size="iconSize"></Icon>
    <span class="layout-text">{{ $t(`menu-${item.label}`) }}</span>
  </template>
  <!-- 子菜单 -->
  <template v-for="child in item.children">
    <MenuItem :name="child.name" :key="'menuitem' + child.name">
      <Icon :type="child.icon" :size="iconSize" :key="'icon' + child.name"></Icon>
      <span class="layout-text" :key="'title' + child.name">{{ $t(`menu-${child.label}`) }}</span>
    </MenuItem>
  </template>
</Submenu>
// 国际化文件
// zh.json
{
  "menu-用户管理": "用户管理",
  "menu-部门管理": "部门管理",
  ...
}
// en.json
{
  "menu-用户管理": "USER MANAGE",
  "menu-部门管理": "DEPT MANAGE",
  ...
}

相对来说比较优雅并且开发成本也不高的方式,肯定是调整路由管理功能模块,增加一个多语言字段,这样就可以设置双语了。然后在输出菜单的时候获取一下当前的语言环境就行。
比如说:

<template>
  <!-- 只是举个例子 -->
  <Submenu :name="item.name" :key="item.name">
    <!-- 父菜单 -->
    <template slot="title">
      <Icon :type="item.icon" :size="iconSize"></Icon>
      <span class="layout-text">{{ item[lang] }}</span>
    </template>
    <!-- 子菜单 -->
    <template v-for="child in item.children">
      <MenuItem :name="child.name" :key="'menuitem' + child.name">
        <Icon :type="child.icon" :size="iconSize" :key="'icon' + child.name"></Icon>
        <span class="layout-text" :key="'title' + child.name">{{ child[lang] }}</span>
      </MenuItem>
    </template>
  </Submenu>
</template>
<script>
import { mapGetters } from 'vuex'
export defult {
   computed: {
     ...mapGetters(['lang']) // 比如说中文环境是 `zh`,英文环境是 `en`
   }
}
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题