Bladeren bron

架子已经搭好

xsh 3 jaren geleden
bovenliggende
commit
e8e747c95d

+ 183 - 85
package-lock.json

@@ -1752,6 +1752,63 @@
           "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
           "dev": true
         },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
         "ssri": {
           "version": "8.0.1",
           "resolved": "https://registry.nlark.com/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1621364668574&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
@@ -1760,6 +1817,28 @@
           "requires": {
             "minipass": "^3.1.1"
           }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "vue-loader-v16": {
+          "version": "npm:vue-loader@16.5.0",
+          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.5.0.tgz",
+          "integrity": "sha512-WXh+7AgFxGTgb5QAkQtFeUcHNIEq3PGVQ8WskY5ZiFbWBkOwcCPRs4w/2tVyTbh2q6TVRlO3xfvIukUtjsu62A==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chalk": "^4.1.0",
+            "hash-sum": "^2.0.0",
+            "loader-utils": "^2.0.0"
+          }
         }
       }
     },
@@ -2314,6 +2393,14 @@
       "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
       "dev": true
     },
+    "async-validator": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
+      "integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
+      "requires": {
+        "babel-runtime": "6.x"
+      }
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
@@ -2353,6 +2440,14 @@
       "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
       "dev": true
     },
+    "axios": {
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+      "requires": {
+        "follow-redirects": "^1.14.0"
+      }
+    },
     "babel-eslint": {
       "version": "10.1.0",
       "resolved": "https://registry.nlark.com/babel-eslint/download/babel-eslint-10.1.0.tgz",
@@ -2367,6 +2462,11 @@
         "resolve": "^1.12.0"
       }
     },
+    "babel-helper-vue-jsx-merge-props": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+      "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
+    },
     "babel-loader": {
       "version": "8.2.2",
       "resolved": "https://registry.nlark.com/babel-loader/download/babel-loader-8.2.2.tgz?cache=0&sync_timestamp=1618847034310&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.2.tgz",
@@ -2418,6 +2518,27 @@
         "@babel/helper-define-polyfill-provider": "^0.2.2"
       }
     },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+          "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
+        },
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        }
+      }
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.2.tgz?cache=0&sync_timestamp=1617714233441&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbalanced-match%2Fdownload%2Fbalanced-match-1.0.2.tgz",
@@ -3398,6 +3519,38 @@
         }
       }
     },
+    "compression-webpack-plugin": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.0.0.tgz",
+      "integrity": "sha512-V2KmQqaUkErPT+ZcUGHa8zWpIw1oTYaC7wjGewJm053GWAoY04GfU5B/NZ/JSz1eFp9MggMdLQpEHe1TJAQY1A==",
+      "dev": true,
+      "requires": {
+        "schema-utils": "^3.1.0",
+        "serialize-javascript": "^6.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.8",
+            "ajv": "^6.12.5",
+            "ajv-keywords": "^3.5.2"
+          }
+        },
+        "serialize-javascript": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+          "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+          "dev": true,
+          "requires": {
+            "randombytes": "^2.1.0"
+          }
+        }
+      }
+    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
@@ -4063,8 +4216,7 @@
     "deepmerge": {
       "version": "1.5.2",
       "resolved": "https://registry.nlark.com/deepmerge/download/deepmerge-1.5.2.tgz",
-      "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M=",
-      "dev": true
+      "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M="
     },
     "default-gateway": {
       "version": "5.0.5",
@@ -4513,6 +4665,19 @@
       "integrity": "sha1-gjy5yY8oxkxnOSDxyQ6jgmWW6vk=",
       "dev": true
     },
+    "element-ui": {
+      "version": "2.15.6",
+      "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.6.tgz",
+      "integrity": "sha512-rcYXEKd/j2G0AgficAOk1Zd1AsnHRkhmrK4yLHmNOiimU2JfsywgfKUjMoFuT6pQx0luhovj8lFjpE4Fnt58Iw==",
+      "requires": {
+        "async-validator": "~1.8.1",
+        "babel-helper-vue-jsx-merge-props": "^2.0.0",
+        "deepmerge": "^1.2.0",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0",
+        "throttle-debounce": "^1.0.1"
+      }
+    },
     "elliptic": {
       "version": "6.5.4",
       "resolved": "https://registry.nlark.com/elliptic/download/elliptic-6.5.4.tgz",
@@ -5405,8 +5570,7 @@
     "follow-redirects": {
       "version": "1.14.3",
       "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.3.tgz",
-      "integrity": "sha1-atp4EY2NJMruWVWVrM3ArGq9Ai4=",
-      "dev": true
+      "integrity": "sha1-atp4EY2NJMruWVWVrM3ArGq9Ai4="
     },
     "for-in": {
       "version": "1.0.2",
@@ -7607,6 +7771,11 @@
       "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
       "dev": true
     },
+    "normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+    },
     "npm-run-path": {
       "version": "2.0.2",
       "resolved": "https://registry.nlark.com/npm-run-path/download/npm-run-path-2.0.2.tgz",
@@ -9269,6 +9438,11 @@
       "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
       "dev": true
     },
+    "resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
     "resolve": {
       "version": "1.20.0",
       "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.20.0.tgz",
@@ -10470,6 +10644,11 @@
         "neo-async": "^2.6.0"
       }
     },
+    "throttle-debounce": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
+      "integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg=="
+    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.nlark.com/through/download/through-2.3.8.tgz?cache=0&sync_timestamp=1618847037651&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fthrough%2Fdownload%2Fthrough-2.3.8.tgz",
@@ -11055,87 +11234,6 @@
         }
       }
     },
-    "vue-loader-v16": {
-      "version": "npm:vue-loader@16.5.0",
-      "resolved": "https://registry.nlark.com/vue-loader/download/vue-loader-16.5.0.tgz?cache=0&sync_timestamp=1628666767864&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-loader%2Fdownload%2Fvue-loader-16.5.0.tgz",
-      "integrity": "sha1-CcTgcSRmiZ40uZpoZSTxkWX7KJI=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "chalk": "^4.1.0",
-        "hash-sum": "^2.0.0",
-        "loader-utils": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995588464&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.2.tgz?cache=0&sync_timestamp=1627646655305&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.2.tgz",
-          "integrity": "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.nlark.com/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true,
-          "optional": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.nlark.com/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1626715907927&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
-          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
     "vue-router": {
       "version": "3.5.2",
       "resolved": "https://registry.nlark.com/vue-router/download/vue-router-3.5.2.tgz?cache=0&sync_timestamp=1628495505697&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-router%2Fdownload%2Fvue-router-3.5.2.tgz",

+ 3 - 0
package.json

@@ -8,7 +8,9 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "axios": "^0.21.4",
     "core-js": "^3.6.5",
+    "element-ui": "^2.15.6",
     "vue": "^2.6.11",
     "vue-router": "^3.2.0",
     "vuex": "^3.4.0"
@@ -20,6 +22,7 @@
     "@vue/cli-plugin-vuex": "~4.5.0",
     "@vue/cli-service": "~4.5.0",
     "babel-eslint": "^10.1.0",
+    "compression-webpack-plugin": "^9.0.0",
     "eslint": "^6.7.2",
     "eslint-plugin-vue": "^6.2.2",
     "vue-template-compiler": "^2.6.11"

+ 1 - 1
public/index.html

@@ -7,7 +7,7 @@
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
   </head>
-  <body>
+  <body style="margin: 0; padding: 0;">
     <noscript>
       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
     </noscript>

+ 0 - 19
src/App.vue

@@ -1,9 +1,5 @@
 <template>
   <div id="app">
-    <div id="nav">
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </div>
     <router-view/>
   </div>
 </template>
@@ -13,20 +9,5 @@
   font-family: Avenir, Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-}
-
-#nav {
-  padding: 30px;
-}
-
-#nav a {
-  font-weight: bold;
-  color: #2c3e50;
-}
-
-#nav a.router-link-exact-active {
-  color: #42b983;
 }
 </style>

BIN
src/assets/images/colour.png


BIN
src/assets/images/guanbi.png


BIN
src/assets/images/home.png


+ 219 - 0
src/components/HeaderElement.vue

@@ -0,0 +1,219 @@
+<template>
+  <div class="headers" :style="{backgroundColor: color}">
+    <el-row :gutter="20" style="height: 100%">
+      <el-col :span="1" style="height: 100%">
+        <div class="logo"></div>
+      </el-col>
+      <el-col :span="4" style="height: 100%">
+        <span class="title">数智牧场管理系统</span>
+      </el-col>
+      <el-col :span="4" :offset="15" style="height: 100%">
+        <div class="flex">
+          <div class="user">
+            <div>
+              <i class="el-icon-user-solid" style="font-size: 28px"></i>
+            </div>
+            <div>
+              <el-popover
+                  placement="bottom"
+                  width="400"
+                  trigger="hover">
+                  <div style="padding: 10px">
+                    <div style="width: 100%;">
+                      <span style="color: #BBBBBB;">账户信息</span>
+                      <span class="user-right">账户设置</span>
+                    </div>
+                    <el-divider></el-divider>
+                    <ul>
+                      <li>职位: <span class="user-color">厂长</span></li>
+                      <li>本次登录: <span class="user-color">厂长</span></li>
+                      <li>本次登录: <span class="user-color">厂长</span></li>
+                      <li>上次登录: <span class="user-color">厂长</span></li>
+                    </ul>
+                  </div>
+                <span slot="reference">admin</span>
+              </el-popover>
+            </div>
+          </div>
+          <el-divider direction="vertical"></el-divider>
+          <div class="user">
+            <div style="width: 100%; text-align: center">
+              <i class="home" title="首页"></i>
+            </div>
+          </div>
+          <el-divider direction="vertical"></el-divider>
+          <div class="user">
+            <div style="width: 100%; text-align: center">
+              <el-popover
+                  placement="bottom"
+                  width="400"
+                  trigger="hover">
+                <div class="color_flex">
+                  <div v-for="item in colorList" :style="{backgroundColor: item.color}" :key="item.id" class="box" @click="cut(item.color)">
+                    <span>点击换肤</span>
+                  </div>
+                </div>
+                <i slot="reference" class="colour"></i>
+              </el-popover>
+            </div>
+          </div>
+          <el-divider direction="vertical"></el-divider>
+          <div class="user">
+            <div style="width: 100%; text-align: center">
+              <i class="guanbi" title="退出登录"></i>
+            </div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex'
+export default {
+  name: "HeaderElement",
+  computed: {
+    ...mapState(['color'])
+  },
+  data() {
+    return {
+      colorList: [
+        {
+          id: 1,
+          color: '#31C3A6'
+        },
+        {
+          id: 2,
+          color: '#3498DB'
+        },
+        {
+          id: 3,
+          color: '#ED6E4D'
+        },
+        {
+          id: 4,
+          color: '#FABB3D'
+        },
+        {
+          id: 5,
+          color: '#AA7AB3'
+        },
+        {
+          id: 6,
+          color: '#9AD0B9'
+        },
+        {
+          id: 7,
+          color: '#EA94BE'
+        },
+        {
+          id: 8,
+          color: '#C1374A'
+        },
+      ]
+    }
+  },
+  methods: {
+    ...mapMutations(['setColor']),
+    cut(data) {
+      this.setColor(data)
+    }
+  }
+}
+</script>
+
+<style scoped>
+p {
+  margin: 0;
+  display: inline-block;
+  position: relative;
+}
+/deep/.el-divider--vertical {
+  margin: 0 15px;
+}
+.headers {
+  width: 100%;
+  height: 50px;
+}
+.logo {
+  width: 50px;
+  height: 50px;
+  margin: 0 auto;
+  background-image: url("../assets/logo.png");
+  background-size: 100% 100%;
+}
+.title {
+  font-size: 18px;
+  font-weight: 700;
+  line-height: 50px;
+  color: #fff;
+}
+.flex {
+  width: 100%;
+  height: 50px;
+  color: #fff;
+  display: flex;
+  align-items: center;
+}
+.user {
+  width: 80px;
+  height: 50px;
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+}
+.user-right {
+  float: right;
+  margin-right: 10px;
+  cursor: pointer;
+  color: #31C3A6;
+}
+li {
+  margin-bottom: 10px;
+  color: #BBBBBB;
+}
+.user-color {
+  color: #000
+}
+.colour {
+  display: inline-block;
+  width: 32px;
+  height: 32px;
+  background-image: url("../assets/images/colour.png");
+  background-size: 100% 100%;
+}
+.color_flex {
+  width: 100%;
+  height: 200px;
+  padding: 10px;
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  grid-template-rows: repeat(2, 1fr);
+  grid-column-gap: 10px;
+  grid-row-gap: 10px;
+}
+.box {
+  cursor: pointer;
+  text-align: center;
+  color: #fff;
+  line-height: 100px;
+}
+.box:hover {
+  content: '点击换肤';
+}
+.guanbi {
+  display: inline-block;
+  width: 32px;
+  height: 32px;
+  background-image: url("../assets/images/guanbi.png");
+  background-size: 100% 100%;
+}
+.home {
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url("../assets/images/home.png");
+  background-size: 100% 100%;
+}
+</style>

+ 0 - 60
src/components/HelloWorld.vue

@@ -1,60 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br>
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
-      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
-      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
-      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
-      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'HelloWorld',
-  props: {
-    msg: String
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
-</style>

+ 220 - 0
src/components/SideMenu.vue

@@ -0,0 +1,220 @@
+<template>
+  <div class="sidemenu">
+    <el-menu
+        :style="{width: width + 'px', display: 'inline-block', height: '100%'}"
+        background-color="#464C5B"
+        text-color="#fff"
+        :default-active="activeName"
+        :active-text-color="color">
+      <el-menu-item
+          v-for="(item) in menuList"
+          :class="[item.menuName === activeName && activeName!=='首页' ? 'menuSet' : '']"
+          :index="item.menuName"
+          :key="item.id"
+          @click="jump(item)">
+        <template slot="title">
+          <span>{{item.menuName}}</span>
+        </template>
+      </el-menu-item>
+    </el-menu>
+    <div v-show="isShow" class="subsidemenu">
+      <div class="menu-header">{{selectItem.menuName}}</div>
+      <ul class="menu-item-children">
+        <li
+            v-for="item in selectItem.children"
+            class="menuChildren"
+            :style="{color: item.url == activeUrl ? color : '#999'}"
+            @click="go(item)"
+            :key="item.id">{{item.menuName}}</li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+export default {
+  name: "SideMenu",
+  computed: {
+    ...mapState(['color'])
+  },
+  data() {
+    return {
+      menuList: [
+        {
+          id: 1,
+          menuName: '首页',
+          parentId: 0,
+          sort: 1,
+          url: 'dashboard',
+          children: [],
+        },
+        {
+          id: 2,
+          menuName: '生物安全',
+          parentId: 0,
+          sort: 2,
+          url: '',
+          children: [
+            {
+              id: 9,
+              menuName: "人员管理",
+              parentId: 8,
+              sort: 1,
+              url: "userAdmin",
+            },
+            {
+              children: [],
+              id: 10,
+              menuName: "车辆管理",
+              parentId: 8,
+              sort: 2,
+              url: "carAdmin",
+            }
+          ]
+        }
+      ],
+      width: 249,
+      isShow: false,
+      selectItem: {},
+      activeUrl: '',
+      activeName: '首页',
+    }
+  },
+  watch: {
+    $route(newVal) {
+      let parentName = newVal.meta.parentName;
+      let routerName = newVal.meta.permission;
+      this.activeName = parentName;
+      this.activeUrl = routerName
+      var that = this;
+      this.$nextTick(() => {
+        that.selectItem = that.getFilter(that.menuList, parentName)[0];
+        if (that.selectItem.children.length > 0) {
+          that.isShow = true;
+        } else {
+          that.isShow = false;
+        }
+      })
+    },
+    isShow(newVal) {
+      if(newVal) {
+        this.width = 100;
+      } else {
+        this.width = 249;
+      }
+    },
+  },
+  methods: {
+    jump(item) {
+      this.activeName = item.menuName;
+      if(item.children.length > 0) {
+        // this.width = 100;
+        this.isShow = true;
+        this.selectItem = item;
+      } else {
+        // this.width = 249;
+        this.isShow = false;
+        this.$router.push({
+          path: '/' + item.url
+        })
+      }
+    },
+    go(item) {
+      this.activeUrl = item.url;
+      this.$router.push({
+        path: '/' + item.url
+      })
+    },
+    // 过滤找到自己上级
+    getFilter(list, name) {
+     let childrenList = [];
+     const targetList = list.filter((item) => {
+        if(item.menuName == name) {
+            return true
+        } else if(item.children && item.children.length) {
+          childrenList = childrenList.concat(this.getFilter(item.children, name));
+          return false
+        } else {
+          return false;
+        }
+     })
+      return targetList.concat(childrenList);
+    }
+  },
+  mounted() {
+    // 路由地址
+    let routerName = this.$route.meta.permission;
+    // 上级菜单名字
+    let parentName = this.$route.meta.parentName;
+    this.selectItem = this.getFilter(this.menuList, parentName)[0];
+    if (this.selectItem.children.length > 0) {
+      this.isShow = true;
+    } else {
+      this.isShow = false;
+    }
+    this.activeUrl = routerName;
+    this.activeName = parentName;
+  }
+}
+</script>
+
+<style scoped>
+.sidemenu {
+  height: calc(100vh - 75px);
+  overflow-y: auto;
+  position: relative;
+  padding: 0;
+  margin: 0;
+}
+.subsidemenu {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 149px;
+  height: calc(100vh - 75px);
+  float: right;
+  border-right: 1px solid #ddd;
+}
+.menu-header {
+  width: 100%;
+  height: 50px;
+  line-height: 50px;
+  font-size: 16px;
+  color: #999;
+  text-align: center;
+  border-bottom: 1px solid #ddd;
+  background-color: rgb(242, 242, 242);
+}
+.menu-item-children {
+  width: 100%;
+  height: calc(100% - 52px);
+  background-color: #EAEDF1;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+.menuChildren {
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  border-bottom: 1px solid #ddd;
+  font-size: 14px;
+  cursor: pointer;
+  color: #BCBCBC;
+}
+.menuSet {
+  position: relative;
+}
+.menuSet:after {
+  content: '';
+  position: absolute;
+  width: 18px;
+  height: 18px;
+  top: 20px;
+  right: -10px;
+  transform: rotate(45deg);
+  background-color: #EAEDF1;
+
+}
+</style>

+ 3 - 1
src/main.js

@@ -2,8 +2,10 @@ import Vue from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
-
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css';
 Vue.config.productionTip = false
+Vue.use(ElementUI);
 
 new Vue({
   router,

+ 51 - 0
src/router/ChildrenRouters.js

@@ -0,0 +1,51 @@
+const childrenRouters = [
+  /* 首页 */
+  {
+    path: '/',
+    name: 'Dashboard',
+    component: () => import('../views/dashboard/dashboard.vue'),
+    meta: {
+      title: '首页',
+      permission: 'dashboard',
+      parentName: '首页',
+    },
+  },
+  {
+    path: '/dashboard',
+    name: 'Dashboard',
+    component: () => import('../views/dashboard/dashboard.vue'),
+    meta: {
+      title: '首页',
+      permission: 'dashboard',
+      parentName: '首页',
+    },
+  },
+  /*
+    生物安全
+   */
+
+  /* 人员管理 */
+  {
+    path: '/userAdmin',
+    name: 'UserAdmin',
+    component: () => import('../views/BioSafety/UserAdmin.vue'),
+    meta: {
+      title: '人员管理',
+      permission: 'userAdmin',
+      parentName: '生物安全',
+    }
+  },
+  /* 车辆管理 */
+  {
+    path: '/carAdmin',
+    name: 'CarAdmin',
+    component: () => import('../views/BioSafety/CarAdmin.vue'),
+    meta: {
+      title: '车辆管理',
+      permission: 'carAdmin',
+      parentName: '生物安全',
+    }
+  },
+]
+
+export default childrenRouters;

+ 7 - 11
src/router/index.js

@@ -1,22 +1,18 @@
 import Vue from 'vue'
 import VueRouter from 'vue-router'
-import Home from '../views/Home.vue'
+import ChildrenRouters from './ChildrenRouters.js'
 
 Vue.use(VueRouter)
 
+let mainRouterChildren = [];
+mainRouterChildren = mainRouterChildren.concat(ChildrenRouters)
+
 const routes = [
   {
     path: '/',
-    name: 'Home',
-    component: Home
-  },
-  {
-    path: '/about',
-    name: 'About',
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
+    name: 'MainLayout',
+    component: () => import('../views/MainLayout.vue'),
+    children: mainRouterChildren
   }
 ]
 

+ 4 - 0
src/store/index.js

@@ -5,8 +5,12 @@ Vue.use(Vuex)
 
 export default new Vuex.Store({
   state: {
+    color: '#31C3A6'
   },
   mutations: {
+    setColor(state, data) {
+      state.color = data
+    }
   },
   actions: {
   },

+ 0 - 5
src/views/About.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>

+ 13 - 0
src/views/BioSafety/CarAdmin.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>这是车辆管理</div>
+</template>
+
+<script>
+export default {
+  name: "CarAdmin"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 13 - 0
src/views/BioSafety/UserAdmin.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>这是人员管理</div>
+</template>
+
+<script>
+export default {
+  name: "UserAdmin"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 18
src/views/Home.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="home">
-    <img alt="Vue logo" src="../assets/logo.png">
-    <HelloWorld msg="Welcome to Your Vue.js App"/>
-  </div>
-</template>
-
-<script>
-// @ is an alias to /src
-import HelloWorld from '@/components/HelloWorld.vue'
-
-export default {
-  name: 'Home',
-  components: {
-    HelloWorld
-  }
-}
-</script>

+ 38 - 0
src/views/MainLayout.vue

@@ -0,0 +1,38 @@
+<template>
+  <el-container>
+    <el-header style="height: 50px">
+      <header-element></header-element>
+    </el-header>
+    <el-container>
+      <el-aside width="250px">
+        <side-menu></side-menu>
+      </el-aside>
+      <el-main>
+        <router-view></router-view>
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script>
+import HeaderElement from "../components/HeaderElement";
+import SideMenu from "../components/SideMenu";
+export default {
+  name: "MainLayout",
+  components: {
+    HeaderElement,
+    SideMenu
+  },
+  data() {
+    return {}
+  },
+  methods: {},
+}
+</script>
+
+<style scoped>
+ /deep/.el-header{
+   padding: 0;
+   margin: 0;
+ }
+</style>

+ 13 - 0
src/views/dashboard/dashboard.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>这是首页</div>
+</template>
+
+<script>
+export default {
+  name: "dashboard"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 30 - 0
vue.config.js

@@ -0,0 +1,30 @@
+const CompressionWebpackPlugin = require("compression-webpack-plugin");
+const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
+module.exports = {
+  publicPath: './', // 相对于 HTML 页面(目录相同)
+  configureWebpack: config => {
+    if(process.env.NODE_ENV === 'production') {
+      config.plugins.push(
+        new CompressionWebpackPlugin({
+          /* [file]被替换为原始资产文件名。
+             [path]替换为原始资产的路径。
+             [dir]替换为原始资产的目录。
+             [name]被替换为原始资产的文件名。
+             [ext]替换为原始资产的扩展名。
+             [query]被查询替换。*/
+          filename: '[path].gz[query]',
+          //压缩算法
+          algorithm: 'gzip',
+          //匹配文件
+          test: productionGzipExtensions,
+          //压缩超过此大小的文件,以字节为单位
+          threshold: 10240,
+          minRatio: 0.8,
+          //删除原始文件只保留压缩后的文件
+          //deleteOriginalAssets: false
+        })
+      )
+    }
+
+  },
+};