接着之前的笔记,参考源码的布局,增加Size组件大小及i18n的国际化,对比源码有部分改动,没有加入浏览器的判断部分。
Size布局大小
根据element-ui官方的介绍,SIZE的配置可以在初始化中进行,实现思路基本为main.js加载时设置一个默认值,用户配置后暂时放到cookie里或者放到数据库中,官网介绍如下:
完整引入 Element:
import Vue from 'vue';
import Element from 'element-ui';
Vue.use(Element, { size: 'small', zIndex: 3000 });
按需引入 Element:
import Vue from 'vue';
import { Button } from 'element-ui';
Vue.prototype.$ELEMENT = { size: 'small', zIndex: 3000 };
Vue.use(Button);
参考vue-element-admin中源码,使用了全局引入,这里先用按需引入试试。在table的菜单中找了个官网的DEMO作为测试。
在main.js中引入相关组件,并进行全局配置
Vue.prototype.$ELEMENT = { size: Cookies.get("size") || "medium" };
在src>components下新建SizeSelect组件,这里使用了element-UI的dropdown组件来实现下拉的选择。NavBar中使用Tooltip实现鼠标滑过时的文字提示。当选中dropdown的内容后通过回调command属性来配置,同时修改cookie及ELEMENT的全局属性。代码如下:
<template>
<el-dropdown trigger="click" @command="handleSetSize">
<div>
<svg-icon class-name="size-icon" icon-class="size" />
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item of sizeOptions"
:key="item.value"
:disabled="size === item.value"
:command="item.value"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
data() {
return {
sizeOptions: [
{ label: "Default", value: "default" },
{ label: "Medium", value: "medium" },
{ label: "Small", value: "small" },
{ label: "Mini", value: "mini" }
]
};
},
computed: {
size() {
return this.$store.getters.size;
}
},
methods: {
handleSetSize(size) {
this.$ELEMENT.size = size;
this.$store.dispatch("app/setSize", size);
this.$message({
message: "Switch Size Success",
type: "success"
});
}
}
};
</script>
修改size后需要刷新页面,vue-element-admin文档中介绍如下
我本人在公司项目中,现在采取的方案是判断当前点击的菜单路由和当前的路由是否一致,但一致的时候,会先跳转到一个专门 Redirect 的页面,它会将路由重定向到我想去的页面,这样就起到了刷新的效果了。
按照vue-element-admin的实现,需要在route.js中增加/redirect的路由,在views中增加一个redirect的组件用来判断跳转,在sizeselect组件中增加一个刷新的方法。先配置路由。
{
path: "/redirect",
component: Layout,
hidden: true,
children: [
{
path: "/redirect/:path*",
component: () => import("@/views/redirect/index")
}
]
}
在views中增加一个redirect的组件,代码如下
<script>
export default {
created() {
const { params, query } = this.$route;
const { path } = params;
this.$router.replace({ path: "/" + path, query });
},
render: function(h) {
return h();
}
};
</script>
在sizeselect中按照源码增加刷新页面的方法:
<el-dropdown trigger="click" @command="handleSetSize">
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item of sizeOptions"
:key="item.value"
:disabled="size === item.value"
:command="item.value"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
LangSelect 语言选择
实现思路,按照vue-element-admin的实现,需要在vuex及cookie中存放语言选项
i18N国际化这里主要分组件的国际化和自己定义的一些内容,element-ui文档中有详细的介绍只要参考配置就可以
// 按需引入 Element
import Vue from 'vue'
import { Button, Select } from 'element-ui'
import lang from 'element-ui/lib/locale/lang/en'
import locale from 'element-ui/lib/locale'
// 设置语言
locale.use(lang)
// 引入组件
Vue.component(Button.name, Button)
Vue.component(Select.name, Select)
由于涉及自定义的i18n部分,这里使用了vue-i18N的这个组件库,先安装组件库
yarn add vue-i18n
在src下新建locale文件夹用来存放语言包,这里直接复制了vue-element-admin中的src>lang文件夹。其中locale中的index.js如下:
import Vue from "vue";
import VueI18n from "vue-i18n";
import Cookies from "js-cookie";
import elementEnLocale from "element-ui/lib/locale/lang/en"; // element-ui lang
import elementZhLocale from "element-ui/lib/locale/lang/zh-CN"; // element-ui lang
import enLocale from "./en";
import zhLocale from "./zh";
Vue.use(VueI18n);
const messages = {
en: {
...enLocale,
...elementEnLocale
},
zh: {
...zhLocale,
...elementZhLocale
}
};
export function getLanguage() {
const chooseLanguage = Cookies.get("language");
if (chooseLanguage) return chooseLanguage;
return "en";
}
const i18n = new VueI18n({
locale: getLanguage(),
messages
});
export default i18n;
根据element-ui官方的介绍,按需加载的i18n配置如下:
import i18n from "./locale";
ElementLocale.i18n((key, value) => i18n.t(key, value));
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount("#app");
在src>components下新建LangSelect组件,组件功能主要是提供下拉的语言选择,并调用vuex中的app.js将语言选择写入cookie,LangSelect组件代码如下:
<template>
<el-dropdown
trigger="click"
class="international"
@command="handleSetLanguage"
>
<div>
<svg-icon class-name="international-icon" icon-class="language" />
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :disabled="language === 'zh'" command="zh">
中文
</el-dropdown-item>
<el-dropdown-item :disabled="language === 'en'" command="en">
English
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
computed: {
language() {
return this.$store.getters.language;
}
},
methods: {
handleSetLanguage(lang) {
this.$i18n.locale = lang;
this.$store.dispatch("app/setLanguage", lang);
this.$message({
message: "Switch Language Success",
type: "success"
});
}
}
};
</script>
自定义的i18n部分使用$t('xxx')即可