├── public ├── robots.txt ├── favicon.ico ├── img │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── msapplication-icon-144x144.png │ │ └── safari-pinned-tab.svg ├── manifest.json └── index.html ├── .browserslistrc ├── cypress.json ├── vue.config.js ├── postcss.config.js ├── static └── home.jpg ├── src ├── shims-vue.d.ts ├── assets │ └── images │ │ ├── home.jpg │ │ ├── favicon.ico │ │ └── logo.svg ├── modules │ ├── mutation-types.ts │ └── chacha.mutation.ts ├── pages │ ├── page2 │ │ └── Page2.vue │ ├── page3 │ │ └── Page3.vue │ ├── page4 │ │ └── Page4.vue │ ├── home │ │ └── home.vue │ └── page1 │ │ └── Page1.vue ├── action │ └── chacha.action.ts ├── shims-tsx.d.ts ├── store │ └── store.ts ├── main.ts ├── components │ └── common │ │ ├── Container.vue │ │ ├── NavMenu.vue │ │ ├── TopBar.vue │ │ └── style.scss ├── App.vue ├── registerServiceWorker.ts └── router.ts ├── server ├── controller │ └── home.controller.js └── server.js ├── tests ├── e2e │ ├── specs │ │ └── test.js │ ├── support │ │ ├── index.js │ │ └── commands.js │ └── plugins │ │ └── index.js └── unit │ └── example.spec.ts ├── babel.config.js ├── .gitignore ├── tslint.json ├── jest.config.js ├── tsconfig.json ├── package.json └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | // vue.config.js 2 | module.exports = { 3 | // options... 4 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /static/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/static/home.jpg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue'; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/src/assets/images/home.jpg -------------------------------------------------------------------------------- /src/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/src/assets/images/favicon.ico -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /src/modules/mutation-types.ts: -------------------------------------------------------------------------------- 1 | // mutation types 2 | export const INCREMENT = 'INCREMENT'; 3 | export const DECREMENT = 'DECREMENT'; 4 | -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /src/pages/page2/Page2.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/pages/page3/Page3.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/pages/page4/Page4.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chachaxw/vue-element-quick-start/HEAD/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /server/controller/home.controller.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | app.get('/', function(req, res, next){ 3 | res.send('Hello, server is running on the localhost:' + app.get('port')); 4 | }); 5 | }; 6 | -------------------------------------------------------------------------------- /tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe('My First Test', () => { 4 | it('Visits the app root url', () => { 5 | cy.visit('/') 6 | cy.contains('h1', 'Welcome to Your Vue.js + TypeScript App') 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ], 5 | plugins: [ 6 | [ 7 | "component", 8 | { 9 | "libraryName": "element-ui", 10 | "styleLibraryName": "theme-chalk" 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/action/chacha.action.ts: -------------------------------------------------------------------------------- 1 | import * as types from '../modules/mutation-types'; 2 | 3 | export const increment = ({ commit }: any) => { 4 | commit(types.INCREMENT); 5 | }; 6 | 7 | export const decrement = ({ commit }: any) => { 8 | commit(types.DECREMENT); 9 | }; 10 | -------------------------------------------------------------------------------- /src/modules/chacha.mutation.ts: -------------------------------------------------------------------------------- 1 | import * as types from './mutation-types'; 2 | 3 | const state = { 4 | count: 0, 5 | }; 6 | 7 | const mutations = { 8 | [types.INCREMENT](data: any) { 9 | data.count += 1; 10 | }, 11 | [types.DECREMENT](data: any) { 12 | data.count -= 1; 13 | }, 14 | }; 15 | 16 | export default { 17 | state, 18 | mutations, 19 | }; 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/videos/ 6 | /tests/e2e/screenshots/ 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue'; 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/example.spec.ts: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils'; 2 | import HelloWorld from '@/components/HelloWorld.vue'; 3 | 4 | describe('HelloWorld.vue', () => { 5 | it('renders props.msg when passed', () => { 6 | const msg = 'new message'; 7 | const wrapper = shallowMount(HelloWorld, { 8 | propsData: { msg }, 9 | }); 10 | expect(wrapper.text()).toMatch(msg); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/store/store.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | 4 | import * as actions from '../action/chacha.action'; 5 | import mutations from '../modules/chacha.mutation'; 6 | 7 | Vue.use(Vuex); 8 | 9 | export default new Vuex.Store({ 10 | actions, 11 | getters: { 12 | count: (state: any) => state.mutations.count, 13 | }, 14 | modules: { 15 | mutations, 16 | }, 17 | strict: process.env.NODE_ENV !== 'production', 18 | }); 19 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import Element from 'element-ui'; 4 | import 'element-ui/lib/theme-chalk/index.css'; 5 | 6 | import App from './App.vue'; 7 | import store from './store/store'; 8 | import router from './router'; 9 | import './registerServiceWorker'; 10 | 11 | Vue.use(Element); 12 | Vue.use(Vuex); 13 | 14 | Vue.config.productionTip = false; 15 | 16 | new Vue({ 17 | router, 18 | store, 19 | render: (h) => h(App), 20 | }).$mount('#app'); 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "linterOptions": { 7 | "exclude": [ 8 | "node_modules/**" 9 | ] 10 | }, 11 | "rules": { 12 | "quotemark": [true, "single"], 13 | "indent": [true, "spaces", 2], 14 | "interface-name": false, 15 | "no-console": false, 16 | "ordered-imports": false, 17 | "object-literal-sort-keys": false, 18 | "no-consecutive-blank-lines": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/common/Container.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "short_name": "hello-world", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 22 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | hello-world 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue', 7 | 'ts', 8 | 'tsx' 9 | ], 10 | transform: { 11 | '^.+\\.vue$': 'vue-jest', 12 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 13 | '^.+\\.tsx?$': 'ts-jest' 14 | }, 15 | moduleNameMapper: { 16 | '^@/(.*)$': '/src/$1' 17 | }, 18 | snapshotSerializers: [ 19 | 'jest-serializer-vue' 20 | ], 21 | testMatch: [ 22 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 23 | ], 24 | testURL: 'http://localhost/', 25 | globals: { 26 | 'ts-jest': { 27 | babelConfig: true 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/pages/home/home.vue: -------------------------------------------------------------------------------- 1 | 14 | 29 | -------------------------------------------------------------------------------- /tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const fs = require('fs'); 3 | const cors = require('cors'); 4 | const path = require('path'); 5 | const bodyParser = require('body-parser'); 6 | const app = express(); 7 | 8 | app.use(bodyParser.json()); 9 | app.use(bodyParser.urlencoded({ extended: true })); 10 | app.set('port', process.env.PORT || 3000); 11 | 12 | // 允许跨域(调试) 13 | app.use(cors()); 14 | 15 | // 自动require controller文件 16 | const files = fs.readdirSync('server/controller'); 17 | files.forEach(function(file) { 18 | if (file.indexOf('.controller') < 0) return; 19 | require('./controller/' + file)(app); 20 | }); 21 | 22 | app.listen(app.get('port'), function(err) { 23 | if(err) { 24 | console.log(err); 25 | } 26 | console.log('CORS-enabled web server listening on the localhost:'+ app.get('port')); 27 | }); 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "types": [ 15 | "webpack-env", 16 | "jest" 17 | ], 18 | "paths": { 19 | "@/*": [ 20 | "src/*" 21 | ] 22 | }, 23 | "lib": [ 24 | "esnext", 25 | "dom", 26 | "dom.iterable", 27 | "scripthost" 28 | ] 29 | }, 30 | "include": [ 31 | "src/**/*.ts", 32 | "src/**/*.tsx", 33 | "src/**/*.vue", 34 | "tests/**/*.ts", 35 | "tests/**/*.tsx" 36 | ], 37 | "exclude": [ 38 | "node_modules" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | // if you need a custom webpack configuration you can uncomment the following import 4 | // and then use the `file:preprocessor` event 5 | // as explained in the cypress docs 6 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples 7 | 8 | /* eslint-disable import/no-extraneous-dependencies, global-require, arrow-body-style */ 9 | // const webpack = require('@cypress/webpack-preprocessor') 10 | 11 | module.exports = (on, config) => { 12 | // on('file:preprocessor', webpack({ 13 | // webpackOptions: require('@vue/cli-service/webpack.config'), 14 | // watchOptions: {} 15 | // })) 16 | 17 | return Object.assign({}, config, { 18 | fixturesFolder: 'tests/e2e/fixtures', 19 | integrationFolder: 'tests/e2e/specs', 20 | screenshotsFolder: 'tests/e2e/screenshots', 21 | videosFolder: 'tests/e2e/videos', 22 | supportFile: 'tests/e2e/support/index.js' 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /src/components/common/NavMenu.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/registerServiceWorker.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-console */ 2 | 3 | import { register } from 'register-service-worker'; 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | 'App is being served from cache by a service worker.\n' + 10 | 'For more details, visit https://goo.gl/AFskqB', 11 | ); 12 | }, 13 | registered() { 14 | console.log('Service worker has been registered.'); 15 | }, 16 | cached() { 17 | console.log('Content has been cached for offline use.'); 18 | }, 19 | updatefound() { 20 | console.log('New content is downloading.'); 21 | }, 22 | updated() { 23 | console.log('New content is available; please refresh.'); 24 | }, 25 | offline() { 26 | console.log('No internet connection found. App is running in offline mode.'); 27 | }, 28 | error(error) { 29 | console.error('Error during service worker registration:', error); 30 | }, 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /src/router.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from 'vue-router'; 3 | import Home from './pages/home/home.vue'; 4 | 5 | Vue.use(Router); 6 | 7 | export default new Router({ 8 | mode: 'history', 9 | base: process.env.BASE_URL, 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'home', 14 | component: Home, 15 | }, 16 | { 17 | path: '/page1', 18 | name: 'page1', 19 | // route level code-splitting 20 | // this generates a separate chunk (about.[hash].js) for this route 21 | // which is lazy-loaded when the route is visited. 22 | component: () => import(/* webpackChunkName: "page1" */ './pages/page1/Page1.vue'), 23 | }, 24 | { 25 | path: '/page2', 26 | name: 'page2', 27 | component: () => import(/* webpackChunkName: "page2" */ './pages/page2/Page2.vue'), 28 | }, 29 | { 30 | path: '/page3', 31 | name: 'page3', 32 | component: () => import(/* webpackChunkName: "page3" */ './pages/page3/Page3.vue'), 33 | }, 34 | { 35 | path: '/page4', 36 | name: 'page4', 37 | component: () => import(/* webpackChunkName: "page4" */ './pages/page4/Page4.vue'), 38 | }, 39 | ], 40 | }); 41 | -------------------------------------------------------------------------------- /src/components/common/TopBar.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-element-quick-start", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "test:e2e": "vue-cli-service test:e2e", 10 | "test:unit": "vue-cli-service test:unit", 11 | "server": "pm2 start server/server.js" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.20.0", 15 | "body-parser": "^1.19.0", 16 | "element-ui": "^2.12.0", 17 | "express": "^4.17.1", 18 | "register-service-worker": "^1.7.1", 19 | "vue": "^2.6.12", 20 | "vue-class-component": "^7.2.5", 21 | "vue-property-decorator": "^9.0.0", 22 | "vue-router": "^3.4.3", 23 | "vuex": "^3.5.1" 24 | }, 25 | "devDependencies": { 26 | "@types/jest": "^26.0.12", 27 | "@vue/cli-plugin-babel": "^4.5.4", 28 | "@vue/cli-plugin-e2e-cypress": "^4.5.4", 29 | "@vue/cli-plugin-pwa": "^4.5.4", 30 | "@vue/cli-plugin-typescript": "^4.5.4", 31 | "@vue/cli-plugin-unit-jest": "^4.5.4", 32 | "@vue/cli-service": "^4.5.4", 33 | "@vue/test-utils": "^1.0.5", 34 | "babel-core": "7.0.0-bridge.0", 35 | "babel-plugin-component": "^1.1.1", 36 | "node-sass": "^4.14.1", 37 | "sass-loader": "^10.0.1", 38 | "ts-jest": "^26.3.0", 39 | "typescript": "^4.0.2", 40 | "vue-template-compiler": "^2.6.12" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/pages/page1/Page1.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 42 | 43 | 77 | -------------------------------------------------------------------------------- /src/assets/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logo 5 | Created with Sketch. 6 | 7 | 8 | C 9 | HA 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | C 18 | H 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue element ui quick start 2 | 3 | ![Github issues](https://img.shields.io/github/issues/chachaxw/vue-element-quick-start) 4 | ![Github forks](https://img.shields.io/github/forks/chachaxw/vue-element-quick-start) 5 | ![Github stars](https://img.shields.io/github/stars/chachaxw/vue-element-quick-start) 6 | 7 | ## Project setup 8 | 9 | ```Yarn 10 | yarn install 11 | $ yarn global add pm2 12 | ``` 13 | 14 | ### Compiles and hot-reloads for development 15 | 16 | ``` Yarn 17 | yarn run serve 18 | ``` 19 | 20 | ### Compiles and minifies for production 21 | 22 | ```Yarn 23 | yarn run build 24 | ``` 25 | 26 | ### Run your tests 27 | 28 | ```Yarn 29 | yarn run test 30 | ``` 31 | 32 | ### Lints and fixes files 33 | 34 | ```Yarn 35 | yarn run lint 36 | ``` 37 | 38 | ### Run your end-to-end tests 39 | 40 | ```Yarn 41 | yarn run test:e2e 42 | ``` 43 | 44 | ### Run your unit tests 45 | 46 | ```Yarn 47 | yarn run test:unit 48 | ``` 49 | 50 | ### Customize configuration 51 | 52 | See [Configuration Reference](https://cli.vuejs.org/config/). 53 | 54 | ### Element UI offical website 55 | 56 | See [Element UI](https://element.eleme.io/). 57 | 58 | ### Page Screen Shot 59 | 60 | ![Screen Shot](http://7xqacx.com1.z0.glb.clouddn.com/backend_managment.png) 61 | 62 | ### Project Structure 63 | 64 | ``` 65 | . 66 | ├── public/ # public files 67 | │ └── ... 68 | ├── server/ # node server files 69 | │ ├── controller # node controller files 70 | │ └── ... 71 | │ ├── model # node model files or mock data files 72 | │ └── ... 73 | │ └── server.js # node start file 74 | ├── src/ 75 | │ ├── assets/ # other static files 76 | │ │ └── ... 77 | │ ├── actions/ # Vuex actions file 78 | │ │ └── ... 79 | │ ├── modules/ # Vuex modules file 80 | │ │ └── ... 81 | │ ├── store/ # Vuex store file 82 | │ │ └── ... 83 | │ ├── helpers/ # helper files(e.g:Ajax) 84 | │ │ └── ... 85 | │ ├── components/ # component files 86 | │ │ └── ... 87 | │ ├── main.js # app entry file 88 | │ ├── routes.js # app router 89 | │ ├── App.vue # app main component 90 | │ └── ... 91 | ├── static/ # pure static assets (directly copied) 92 | ├── .babel.config.js # babel config 93 | ├── vue.config.js # webpack config 94 | ├── cypress.json # Cypress config 95 | ├── tsconfig.json # Typescript config 96 | ├── tslint.json # Tslint config 97 | └── package.json # build scripts and dependencies 98 | 99 | ``` 100 | -------------------------------------------------------------------------------- /src/components/common/style.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'iconfont'; 3 | src: url('//at.alicdn.com/t/font_1476180127_2466838.eot'); /* IE9*/ 4 | src: url('//at.alicdn.com/t/font_1476180127_2466838.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('//at.alicdn.com/t/font_1476180127_2466838.woff') format('woff'), /* chrome、firefox */ 6 | url('//at.alicdn.com/t/font_1476180127_2466838.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ 7 | url('//at.alicdn.com/t/font_1476180127_2466838.svg#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | .iconfont { 10 | font-family:"iconfont" !important; 11 | font-size:16px; 12 | font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-text-stroke-width: 0.2px; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | #app { 19 | display: flex; 20 | min-width: 1080px; 21 | background-color: #1A191F; 22 | color: #dbdbdb; 23 | } 24 | 25 | body, html { 26 | margin: 0; 27 | padding: 0; 28 | font-family: aileron,微软雅黑,"arial", "sans-serif"; 29 | } 30 | 31 | // 顶栏样式 32 | .top-bar { 33 | height: 60px; 34 | 35 | .top-wrapper { 36 | flex: 1; 37 | margin-right: 64px; 38 | } 39 | 40 | .search-area { 41 | padding: 14px 10px; 42 | height: 100%; 43 | max-width: 320px; 44 | 45 | .el-form-item { 46 | margin: 0; 47 | border-radius: 16px; 48 | box-shadow: 0 5px 20px rgba(0,0,0,.3); 49 | 50 | .el-icon-search { 51 | top: 0; 52 | right: 0; 53 | font-size: 20px; 54 | position: absolute; 55 | z-index: 1; 56 | width: 32px; 57 | line-height: 32px; 58 | border-radius: 16px; 59 | text-align: center; 60 | background-color: #20202A; 61 | } 62 | } 63 | 64 | .el-form-item__content { 65 | line-height: 1; 66 | height: 32px; 67 | } 68 | 69 | .el-input { 70 | height: 32px; 71 | 72 | input { 73 | height: 32px; 74 | border: none; 75 | float: right; 76 | color: #F9FAFC; 77 | opacity: 1; 78 | border-radius: 16px; 79 | background-color: #20202A; 80 | 81 | &::-webkit-input-placeholder { 82 | color: #C0CCDA; 83 | } 84 | &::-moz-placeholder { 85 | color: #C0CCDA; 86 | } 87 | &::-ms-input-placeholder { 88 | color: #C0CCDA; 89 | } 90 | } 91 | } 92 | } 93 | 94 | .user-area { 95 | padding: 14px 10px; 96 | display: inline-block; 97 | position: relative; 98 | 99 | &:hover { 100 | background-color: #20202A; 101 | .drop-menu { 102 | display: block; 103 | } 104 | } 105 | 106 | .user-avatar { 107 | height: 32px; 108 | cursor: pointer; 109 | 110 | .avatar-img { 111 | display: inline-block; 112 | width: 32px; 113 | height: 32px; 114 | border-radius: 16px; 115 | margin-right: 10px; 116 | vertical-align: middle; 117 | background: center no-repeat; 118 | background-size: cover; 119 | background-color: #fff; 120 | } 121 | 122 | .el-icon-arrow-down { 123 | vertical-align: middle; 124 | font-size: 12px; 125 | color: #C0CCDA; 126 | } 127 | } 128 | } 129 | 130 | .drop-menu { 131 | position: absolute; 132 | right: 0; 133 | top: 60px; 134 | display: none; 135 | width: 140px; 136 | z-index: 1; 137 | background-color: #20202A; 138 | box-shadow: 0 5px 20px rgba(0,0,0,.3); 139 | 140 | ul { 141 | list-style: none; 142 | margin: 0; 143 | padding: 0; 144 | } 145 | 146 | li { 147 | padding: 12px 20px; 148 | cursor: pointer; 149 | line-height: 1; 150 | font-size: 14px; 151 | &:hover { 152 | background-color: #2b3035; 153 | } 154 | } 155 | 156 | .iconfont { 157 | font-size: 20px; 158 | margin-right: 10px; 159 | } 160 | } 161 | } 162 | 163 | // 左侧导航栏样式 164 | #nav-menu { 165 | width: 240px; 166 | min-width: 240px; 167 | height: calc(100%-72px); 168 | border-radius: 0; 169 | border-right: 0; 170 | background-color: #20202A; 171 | box-shadow: 5px 0 20px rgba(0,0,0,.3); 172 | 173 | .logo { 174 | width: 240px; 175 | height: 60px; 176 | text-align: center; 177 | background-color: #20202A; 178 | img { 179 | margin-top: 12px; 180 | } 181 | } 182 | 183 | .nav-link { 184 | display: block; 185 | } 186 | 187 | .el-menu { 188 | background-color: #1A191F; 189 | } 190 | 191 | .el-menu-item, 192 | .el-submenu .el-submenu__title { 193 | height: 44px; 194 | line-height: 44px; 195 | color: #dbdbdb; 196 | &:hover { 197 | background-color: #2b3035; 198 | } 199 | } 200 | 201 | .router-link-active { 202 | color: #03a9f4; 203 | } 204 | } 205 | 206 | // 内容区域样式 207 | #container { 208 | min-height: 100vh; 209 | flex: 1 auto; 210 | 211 | .page { 212 | width: 100%; 213 | overflow: hidden; 214 | height: calc(100% - 60px); 215 | } 216 | } 217 | 218 | // 公共样式 219 | .pull-left { 220 | float: left; 221 | } 222 | .pull-right { 223 | float: right; 224 | } 225 | [v-cloak] { 226 | display: none; 227 | } 228 | a { 229 | text-decoration: none; 230 | color: #C0CCDA; 231 | } 232 | 233 | // active link style 234 | .router-link-active { 235 | color: #20a0ff; 236 | } 237 | 238 | /* Enter and leave animations can use different */ 239 | /* durations and timing functions. */ 240 | .slide-fade-enter-active { 241 | animation: animate-in .6s; 242 | } 243 | .slide-fade-leave-active { 244 | animation: animate-out .6s; 245 | } 246 | @keyframes animate-in { 247 | 0% { 248 | opacity: 0; 249 | } 250 | 100% { 251 | opacity: 1; 252 | } 253 | } 254 | @keyframes animate-out { 255 | 0% { 256 | opacity: 1; 257 | } 258 | 100% { 259 | opacity: 0; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | --------------------------------------------------------------------------------