guhongwei 3 years ago
parent
commit
abaae4059f

+ 28 - 0
src/assets/css/color-dark.css

@@ -0,0 +1,28 @@
+.header{
+    background-color: #242f42;
+}
+.login-wrap{
+    background: #324157;
+}
+.plugins-tips{
+    background: #eef1f6;
+}
+.plugins-tips a{
+    color: #20a0ff;
+}
+.el-upload--text em {
+    color: #20a0ff;
+}
+.pure-button{
+    background: #20a0ff;
+}
+.tags-li.active {
+    border: 1px solid #409EFF;
+    background-color: #409EFF;
+}
+.message-title{
+    color: #20a0ff;
+}
+.collapse-btn:hover{
+    background: rgb(40,52,70);
+}

+ 4 - 0
src/assets/css/icon.css

@@ -0,0 +1,4 @@
+
+    [class*=" el-icon-lx"], [class^=el-icon-lx] {
+        font-family: lx-iconfont!important;
+    }

+ 177 - 0
src/assets/css/main.css

@@ -0,0 +1,177 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+
+html,
+body,
+#app,
+.wrapper {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+}
+
+body {
+    font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
+}
+
+a {
+    text-decoration: none
+}
+
+
+.content-box {
+    position: absolute;
+    left: 200px;
+    right: 0;
+    top: 60px;
+    bottom: 0;
+    padding-bottom: 30px;
+    -webkit-transition: left .3s ease-in-out;
+    transition: left .3s ease-in-out;
+    background: #f0f0f0;
+}
+
+.content {
+    width: auto;
+    height: 100%;
+    padding: 10px;
+    overflow-y: scroll;
+    box-sizing: border-box;
+}
+
+.content-collapse {
+    left: 65px;
+}
+
+.container {
+    padding: 30px;
+    background: #fff;
+    border: 1px solid #ddd;
+    border-radius: 5px;
+}
+
+.crumbs {
+    margin: 10px 0;
+}
+
+.el-table th {
+    background-color: #f5f7fa !important;
+}
+
+.pagination {
+    margin: 20px 0;
+    text-align: right;
+}
+
+.plugins-tips {
+    padding: 20px 10px;
+    margin-bottom: 20px;
+}
+
+.el-button+.el-tooltip {
+    margin-left: 10px;
+}
+
+.el-table tr:hover {
+    background: #f6faff;
+}
+
+.mgb20 {
+    margin-bottom: 20px;
+}
+
+.move-enter-active,
+.move-leave-active {
+    transition: opacity .5s;
+}
+
+.move-enter,
+.move-leave {
+    opacity: 0;
+}
+
+/*BaseForm*/
+
+.form-box {
+    width: 600px;
+}
+
+.form-box .line {
+    text-align: center;
+}
+
+.el-time-panel__content::after,
+.el-time-panel__content::before {
+    margin-top: -7px;
+}
+
+.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
+    padding-bottom: 0;
+}
+
+/*Upload*/
+
+.pure-button {
+    width: 150px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    color: #fff;
+    border-radius: 3px;
+}
+
+.g-core-image-corp-container .info-aside {
+    height: 45px;
+}
+
+.el-upload--text {
+    background-color: #fff;
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    box-sizing: border-box;
+    width: 360px;
+    height: 180px;
+    text-align: center;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.el-upload--text .el-icon-upload {
+    font-size: 67px;
+    color: #97a8be;
+    margin: 40px 0 16px;
+    line-height: 50px;
+}
+
+.el-upload--text {
+    color: #97a8be;
+    font-size: 14px;
+    text-align: center;
+}
+
+.el-upload--text em {
+    font-style: normal;
+}
+
+/*VueEditor*/
+
+.ql-container {
+    min-height: 400px;
+}
+
+.ql-snow .ql-tooltip {
+    transform: translateX(117.5px) translateY(10px) !important;
+}
+
+.editor-btn {
+    margin-top: 20px;
+}
+
+/*markdown*/
+
+.v-note-wrapper .v-note-panel {
+    min-height: 500px;
+}

+ 29 - 0
src/assets/css/theme-green/color-green.css

@@ -0,0 +1,29 @@
+.header{
+    background-color: #07c4a8;
+}
+.login-wrap{
+    background: rgba(56, 157, 170, 0.82);;
+}
+.plugins-tips{
+    background: #f2f2f2;
+}
+.plugins-tips a{
+    color: #00d1b2;
+}
+.el-upload--text em {
+    color: #00d1b2;
+}
+.pure-button{
+    background: #00d1b2;
+}
+.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus {
+    background-color: #00d1b2 !important;
+    border-color: #00d1b2 !important;
+}
+.tags-li.active {
+    border: 1px solid #00d1b2;
+    background-color: #00d1b2;
+}
+.collapse-btn:hover{
+    background: #00d1b2;
+}

BIN
src/assets/css/theme-green/fonts/element-icons.ttf


BIN
src/assets/css/theme-green/fonts/element-icons.woff


File diff suppressed because it is too large
+ 1 - 0
src/assets/css/theme-green/index.css


BIN
src/assets/img/img.jpg


+ 171 - 0
src/components/admin-frame/Header.vue

@@ -0,0 +1,171 @@
+<template>
+  <div class="header">
+    <!-- 折叠按钮 -->
+    <div class="collapse-btn" @click="collapseChage">
+      <i v-if="!collapse" class="el-icon-s-fold"></i>
+      <i v-else class="el-icon-s-unfold"></i>
+    </div>
+    <div class="logo">管理中心</div>
+    <div class="header-right">
+      <div class="header-user-con">
+        <!-- 全屏显示 -->
+        <div class="btn-fullscreen" @click="handleFullScreen">
+          <el-tooltip effect="dark" :content="fullscreen ? `取消全屏` : `全屏`" placement="bottom">
+            <i class="el-icon-rank"></i>
+          </el-tooltip>
+        </div>
+        <!-- 用户头像 -->
+        <div class="user-avator">
+          <img src="../../assets/img/img.jpg" alt="" />
+        </div>
+        <!-- 用户名下拉菜单 -->
+        <el-dropdown class="user-name" trigger="click" @command="handleCommand">
+          <span class="el-dropdown-link">
+            {{ user.name || '游客' }}
+            <i class="el-icon-caret-bottom"></i>
+          </span>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import bus from './bus';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  data() {
+    return {
+      collapse: false,
+      fullscreen: false,
+    };
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    // 用户名下拉菜单选择事件
+    handleCommand(command) {
+      if (command == 'loginout') {
+        localStorage.removeItem('token');
+        this.$router.push('/login');
+      }
+    },
+    // 侧边栏折叠
+    collapseChage() {
+      this.collapse = !this.collapse;
+      bus.$emit('collapse', this.collapse);
+    },
+    // 全屏事件
+    handleFullScreen() {
+      let element = document.documentElement;
+      if (this.fullscreen) {
+        if (document.exitFullscreen) {
+          document.exitFullscreen();
+        } else if (document.webkitCancelFullScreen) {
+          document.webkitCancelFullScreen();
+        } else if (document.mozCancelFullScreen) {
+          document.mozCancelFullScreen();
+        } else if (document.msExitFullscreen) {
+          document.msExitFullscreen();
+        }
+      } else {
+        if (element.requestFullscreen) {
+          element.requestFullscreen();
+        } else if (element.webkitRequestFullScreen) {
+          element.webkitRequestFullScreen();
+        } else if (element.mozRequestFullScreen) {
+          element.mozRequestFullScreen();
+        } else if (element.msRequestFullscreen) {
+          // IE11
+          element.msRequestFullscreen();
+        }
+      }
+      this.fullscreen = !this.fullscreen;
+    },
+  },
+  mounted() {
+    if (document.body.clientWidth < 1500) {
+      this.collapseChage();
+    }
+  },
+};
+</script>
+<style scoped>
+.header {
+  position: relative;
+  box-sizing: border-box;
+  width: 100%;
+  height: 60px;
+  font-size: 22px;
+  color: #fff;
+}
+.collapse-btn {
+  float: left;
+  padding: 0 21px;
+  cursor: pointer;
+  line-height: 60px;
+}
+.header .logo {
+  float: left;
+  width: 25%;
+  line-height: 60px;
+}
+.header-right {
+  float: right;
+  padding-right: 50px;
+}
+.header-user-con {
+  display: flex;
+  height: 60px;
+  align-items: center;
+}
+.btn-fullscreen {
+  transform: rotate(45deg);
+  margin-right: 5px;
+  font-size: 24px;
+}
+.btn-bell,
+.btn-fullscreen {
+  position: relative;
+  width: 30px;
+  height: 30px;
+  text-align: center;
+  border-radius: 15px;
+  cursor: pointer;
+}
+.btn-bell-badge {
+  position: absolute;
+  right: 0;
+  top: -2px;
+  width: 8px;
+  height: 8px;
+  border-radius: 4px;
+  background: #f56c6c;
+  color: #fff;
+}
+.btn-bell .el-icon-bell {
+  color: #fff;
+}
+.user-name {
+  margin-left: 10px;
+}
+.user-avator {
+  margin-left: 20px;
+}
+.user-avator img {
+  display: block;
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+}
+.el-dropdown-link {
+  color: #fff;
+  cursor: pointer;
+}
+.el-dropdown-menu__item {
+  text-align: center;
+}
+</style>

+ 66 - 0
src/components/admin-frame/Home.vue

@@ -0,0 +1,66 @@
+<template>
+  <el-container>
+    <el-header style="padding: 0">
+      <v-head></v-head>
+    </el-header>
+    <el-container>
+      <el-aside width="200px">
+        <v-sidebar></v-sidebar>
+      </el-aside>
+      <el-main>
+        <div class="content-box" :class="{ 'content-collapse': collapse }">
+          <v-tags></v-tags>
+          <div class="content">
+            <transition name="move" mode="out-in">
+              <el-row>
+                <el-col :span="24">
+                  <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+                  <el-col :span="24" class="container">
+                    <router-view></router-view>
+                  </el-col>
+                </el-col>
+              </el-row>
+            </transition>
+            <el-backtop target=".content"></el-backtop>
+          </div>
+        </div>
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script>
+import breadcrumb from './breadcrumb.vue';
+import vHead from './Header.vue';
+import vSidebar from './Sidebar.vue';
+import vTags from './Tags.vue';
+import bus from './bus';
+export default {
+  data() {
+    return {
+      tagsList: [],
+      collapse: false,
+    };
+  },
+  components: {
+    vHead,
+    vSidebar,
+    vTags,
+    breadcrumb,
+  },
+  created() {
+    bus.$on('collapse-content', msg => {
+      this.collapse = msg;
+    });
+
+    // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。
+    bus.$on('tags', msg => {
+      let arr = [];
+      for (let i = 0, len = msg.length; i < len; i++) {
+        msg[i].name && arr.push(msg[i].name);
+      }
+      this.tagsList = arr;
+    });
+  },
+};
+</script>

+ 121 - 0
src/components/admin-frame/Sidebar.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="sidebar">
+    <el-menu
+      class="sidebar-el-menu"
+      :default-active="onRoutes"
+      :collapse="collapse"
+      background-color="#324157"
+      text-color="#bfcbd9"
+      active-text-color="#20a0ff"
+      unique-opened
+      router
+    >
+      <template v-for="item in items">
+        <template v-if="item.subs">
+          <el-submenu class="second" :index="item.index" :key="item.index">
+            <template slot="title">
+              <i :class="item.icon"></i>
+              <span slot="title">{{ item.title }}</span>
+            </template>
+            <template v-for="subItem in item.subs">
+              <el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
+                <template slot="title">{{ subItem.title }}</template>
+                <el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index">{{ threeItem.title }}</el-menu-item>
+              </el-submenu>
+              <el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}</el-menu-item>
+            </template>
+          </el-submenu>
+        </template>
+        <template v-else>
+          <el-menu-item class="first" :index="item.index" :key="item.index">
+            <i :class="item.icon"></i>
+            <span slot="title">{{ item.title }}</span>
+          </el-menu-item>
+        </template>
+      </template>
+    </el-menu>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+import bus from './bus';
+export default {
+  data() {
+    return {
+      collapse: false,
+      items: [
+        {
+          icon: 'el-icon-s-home',
+          index: '/adminCenter/homeIndex',
+          title: '系统首页',
+        },
+      ],
+    };
+  },
+  computed: {
+    ...mapState(['user']),
+    onRoutes() {
+      return this.$route.path.replace('/', '');
+    },
+  },
+  created() {
+    // 通过 Event Bus 进行组件间通信,来折叠侧边栏
+    bus.$on('collapse', (msg) => {
+      this.collapse = msg;
+      bus.$emit('collapse-content', msg);
+    });
+  },
+  methods: {
+    // 分配用户彩带权限
+    async getMenu() {
+      let list = _.cloneDeep(this.items);
+      let data = [
+        {
+          icon: 'el-icon-s-home',
+          index: '/adminCenter/test/index',
+          title: '测试页面',
+        },
+      ];
+      list.push(...data);
+      this.$set(this, `items`, _.uniqBy(list, 'index'));
+    },
+  },
+  watch: {
+    user: {
+      deep: true,
+      immediate: true,
+      handler(val) {
+        this.getMenu();
+      },
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.sidebar {
+  display: block;
+  position: absolute;
+  left: 0;
+  top: 60px;
+  bottom: 0;
+  overflow-y: scroll;
+}
+.sidebar::-webkit-scrollbar {
+  width: 0;
+}
+.sidebar-el-menu:not(.el-menu--collapse) {
+  width: 200px;
+}
+.sidebar > ul {
+  height: 100%;
+}
+// /deep/.first {
+//   padding-left: 0 !important;
+// }
+// /deep/.second .el-submenu__title {
+//   padding-left: 0 !important;
+// }
+</style>

+ 181 - 0
src/components/admin-frame/Tags.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="tags" v-if="showTags">
+    <ul>
+      <li class="tags-li" v-for="(item, index) in tagsList" :class="{ active: isActive(item.path) }" :key="index">
+        <router-link :to="item.path" class="tags-li-title">
+          {{ item.title }}
+        </router-link>
+        <span class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span>
+      </li>
+    </ul>
+    <div class="tags-close-box">
+      <el-dropdown @command="handleTags">
+        <el-button size="mini" type="primary"> 标签选项<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
+        <el-dropdown-menu size="small" slot="dropdown">
+          <el-dropdown-item command="other">关闭其他</el-dropdown-item>
+          <el-dropdown-item command="all">关闭所有</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+  </div>
+</template>
+
+<script>
+import bus from './bus';
+export default {
+  data() {
+    return {
+      tagsList: [],
+    };
+  },
+  methods: {
+    isActive(path) {
+      return path === this.$route.fullPath;
+    },
+    // 关闭单个标签
+    closeTags(index) {
+      const delItem = this.tagsList.splice(index, 1)[0];
+      const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1];
+      if (item) {
+        delItem.path === this.$route.fullPath && this.$router.push(item.path);
+      } else {
+        this.$router.push('/');
+      }
+    },
+    // 关闭全部标签
+    closeAll() {
+      this.tagsList = [];
+      this.$router.push('/');
+    },
+    // 关闭其他标签
+    closeOther() {
+      const curItem = this.tagsList.filter(item => {
+        return item.path === this.$route.fullPath;
+      });
+      this.tagsList = curItem;
+    },
+    // 设置标签
+    setTags(route) {
+      const isExist = this.tagsList.some(item => {
+        return item.path === route.fullPath;
+      });
+      if (!isExist) {
+        if (this.tagsList.length >= 8) {
+          this.tagsList.shift();
+        }
+        this.tagsList.push({
+          title: route.meta.title,
+          path: route.fullPath,
+          name: route.matched[1].components.default.name,
+        });
+      }
+      bus.$emit('tags', this.tagsList);
+    },
+    handleTags(command) {
+      command === 'other' ? this.closeOther() : this.closeAll();
+    },
+  },
+  computed: {
+    showTags() {
+      return this.tagsList.length > 0;
+    },
+  },
+  watch: {
+    $route(newValue, oldValue) {
+      this.setTags(newValue);
+    },
+  },
+  created() {
+    this.setTags(this.$route);
+    // 监听关闭当前页面的标签页
+    bus.$on('close_current_tags', () => {
+      for (let i = 0, len = this.tagsList.length; i < len; i++) {
+        const item = this.tagsList[i];
+        if (item.path === this.$route.fullPath) {
+          if (i < len - 1) {
+            this.$router.push(this.tagsList[i + 1].path);
+          } else if (i > 0) {
+            this.$router.push(this.tagsList[i - 1].path);
+          } else {
+            this.$router.push('/');
+          }
+          this.tagsList.splice(i, 1);
+          break;
+        }
+      }
+    });
+  },
+};
+</script>
+
+<style>
+.tags {
+  position: relative;
+  height: 30px;
+  overflow: hidden;
+  background: #fff;
+  padding-right: 120px;
+  box-shadow: 0 5px 10px #ddd;
+}
+
+.tags ul {
+  box-sizing: border-box;
+  width: 100%;
+  height: 100%;
+}
+
+.tags-li {
+  float: left;
+  margin: 3px 5px 2px 3px;
+  border-radius: 3px;
+  font-size: 12px;
+  overflow: hidden;
+  cursor: pointer;
+  height: 23px;
+  line-height: 23px;
+  border: 1px solid #e9eaec;
+  background: #fff;
+  padding: 0 5px 0 12px;
+  vertical-align: middle;
+  color: #666;
+  -webkit-transition: all 0.3s ease-in;
+  -moz-transition: all 0.3s ease-in;
+  transition: all 0.3s ease-in;
+}
+
+.tags-li:not(.active):hover {
+  background: #f8f8f8;
+}
+
+.tags-li.active {
+  color: #fff;
+}
+
+.tags-li-title {
+  float: left;
+  max-width: 80px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  margin-right: 5px;
+  color: #666;
+}
+
+.tags-li.active .tags-li-title {
+  color: #fff;
+}
+
+.tags-close-box {
+  position: absolute;
+  right: 0;
+  top: 0;
+  box-sizing: border-box;
+  padding-top: 1px;
+  text-align: center;
+  width: 110px;
+  height: 30px;
+  background: #fff;
+  box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
+  z-index: 10;
+}
+</style>

+ 33 - 0
src/components/admin-frame/breadcrumb.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="breadcrumb">
+    <el-row>
+      <el-col :span="24" class="crumbs">
+        <el-breadcrumb separator="/">
+          <el-breadcrumb-item> <i class="el-icon-s-grid"></i> {{ breadcrumbTitle }} </el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  metaInfo: {},
+  name: 'breadcrumb',
+  props: {
+    breadcrumbTitle: { type: String },
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 6 - 0
src/components/admin-frame/bus.js

@@ -0,0 +1,6 @@
+import Vue from 'vue';
+
+// 使用 Event Bus
+const bus = new Vue();
+
+export default bus;

+ 79 - 0
src/components/admin-frame/directives.js

@@ -0,0 +1,79 @@
+import Vue from 'vue';
+
+// v-dialogDrag: 弹窗拖拽属性
+Vue.directive('dialogDrag', {
+  bind(el, binding, vnode, oldVnode) {
+    const dialogHeaderEl = el.querySelector('.el-dialog__header');
+    const dragDom = el.querySelector('.el-dialog');
+
+    dialogHeaderEl.style.cssText += ';cursor:move;';
+    dragDom.style.cssText += ';top:0px;';
+
+    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
+    const sty = (() => {
+      if (window.document.currentStyle) {
+        return (dom, attr) => dom.currentStyle[attr];
+      } else {
+        return (dom, attr) => getComputedStyle(dom, false)[attr];
+      }
+    })();
+
+    dialogHeaderEl.onmousedown = (e) => {
+      // 鼠标按下,计算当前元素距离可视区的距离
+      const disX = e.clientX - dialogHeaderEl.offsetLeft;
+      const disY = e.clientY - dialogHeaderEl.offsetTop;
+
+      const screenWidth = document.body.clientWidth; // body当前宽度
+      const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)
+
+      const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
+      const dragDomheight = dragDom.offsetHeight; // 对话框高度
+
+      const minDragDomLeft = dragDom.offsetLeft;
+      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
+
+      const minDragDomTop = dragDom.offsetTop;
+      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
+
+      // 获取到的值带px 正则匹配替换
+      let styL = sty(dragDom, 'left');
+      let styT = sty(dragDom, 'top');
+
+      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
+      if (styL.includes('%')) {
+        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
+        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
+      } else {
+        styL = +styL.replace(/\px/g, '');
+        styT = +styT.replace(/\px/g, '');
+      }
+
+      document.onmousemove = function (e) {
+        // 通过事件委托,计算移动的距离
+        let left = e.clientX - disX;
+        let top = e.clientY - disY;
+
+        // 边界处理
+        if (-left > minDragDomLeft) {
+          left = -minDragDomLeft;
+        } else if (left > maxDragDomLeft) {
+          left = maxDragDomLeft;
+        }
+
+        if (-top > minDragDomTop) {
+          top = -minDragDomTop;
+        } else if (top > maxDragDomTop) {
+          top = maxDragDomTop;
+        }
+
+        // 移动当前元素
+        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
+      };
+
+      document.onmouseup = function (e) {
+        document.onmousemove = null;
+        document.onmouseup = null;
+      };
+    };
+  },
+});

+ 30 - 0
src/components/admin-frame/i18n.js

@@ -0,0 +1,30 @@
+export const messages = {
+  zh: {
+    i18n: {
+      breadcrumb: '国际化产品',
+      tips: '通过切换语言按钮,来改变当前内容的语言。',
+      btn: '切换英文',
+      title1: '常用用法',
+      p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。',
+      p2: '没有什么比信念更能支撑我们度过艰难的时光了。',
+      p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。',
+      title2: '组件插值',
+      info: 'Element组件需要国际化,请参考 {action}。',
+      value: '文档',
+    },
+  },
+  en: {
+    i18n: {
+      breadcrumb: 'International Products',
+      tips: 'Click on the button to change the current language. ',
+      btn: 'Switch Chinese',
+      title1: 'Common usage',
+      p1: 'If you reveal your secrets to the wind you should not blame the wind for  revealing them to the trees.',
+      p2: 'Nothing can help us endure dark times better than our faith. ',
+      p3: "If you can do what you do best and be happy, you're further along in life  than most people.",
+      title2: 'Component interpolation',
+      info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.',
+      value: 'documentation',
+    },
+  },
+};