修改官网,设置响应式 支持多端

This commit is contained in:
lVAL 2021-01-04 16:13:19 +08:00
parent 5b875e311a
commit 1b75e086e6
49 changed files with 3108 additions and 1202 deletions

104
package-lock.json generated
View File

@ -1120,6 +1120,61 @@
"integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
"dev": true
},
"@nuxt/opencollective": {
"version": "0.3.2",
"resolved": "https://registry.npm.taobao.org/@nuxt/opencollective/download/@nuxt/opencollective-0.3.2.tgz",
"integrity": "sha1-g8twzbK6xfrW+Mk1KeexEYfUnAI=",
"requires": {
"chalk": "^4.1.0",
"consola": "^2.15.0",
"node-fetch": "^2.6.1"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1606792302448&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
"integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz?cache=0&sync_timestamp=1591686984650&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-4.1.0.tgz",
"integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
"integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
"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="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz",
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"@soda/friendly-errors-webpack-plugin": {
"version": "1.7.1",
"resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz",
@ -2865,6 +2920,23 @@
"resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"bootstrap": {
"version": "4.5.3",
"resolved": "https://registry.npm.taobao.org/bootstrap/download/bootstrap-4.5.3.tgz",
"integrity": "sha1-xqcrNVqvMjkgvoACRqbk7zCZf+Y="
},
"bootstrap-vue": {
"version": "2.21.1",
"resolved": "https://registry.npm.taobao.org/bootstrap-vue/download/bootstrap-vue-2.21.1.tgz",
"integrity": "sha1-INPO2WtzWRfYvnG3dxfu50u0DG8=",
"requires": {
"@nuxt/opencollective": "^0.3.2",
"bootstrap": ">=4.5.3 <5.0.0",
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"vue-functional-data-merge": "^3.1.0"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz",
@ -3733,6 +3805,11 @@
"integrity": "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w=",
"dev": true
},
"consola": {
"version": "2.15.0",
"resolved": "https://registry.npm.taobao.org/consola/download/consola-2.15.0.tgz?cache=0&sync_timestamp=1596625700864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsola%2Fdownload%2Fconsola-2.15.0.tgz",
"integrity": "sha1-QPxO76TS+O8uKAYUfwVuogf8wOk="
},
"console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz",
@ -7267,6 +7344,11 @@
"type-check": "~0.3.2"
}
},
"lib-flexible": {
"version": "0.3.2",
"resolved": "https://registry.npm.taobao.org/lib-flexible/download/lib-flexible-0.3.2.tgz",
"integrity": "sha1-BvWnSDIxSi01wSA5vJw8otrqpCY="
},
"lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz",
@ -7965,6 +8047,11 @@
"lower-case": "^1.1.1"
}
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npm.taobao.org/node-fetch/download/node-fetch-2.6.1.tgz?cache=0&sync_timestamp=1599309202591&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-fetch%2Fdownload%2Fnode-fetch-2.6.1.tgz",
"integrity": "sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI="
},
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npm.taobao.org/node-forge/download/node-forge-0.10.0.tgz?cache=0&sync_timestamp=1599010757493&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.10.0.tgz",
@ -8844,6 +8931,16 @@
"ts-pnp": "^1.1.6"
}
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npm.taobao.org/popper.js/download/popper.js-1.16.1.tgz",
"integrity": "sha1-KiI8s9x7YhPXQOQDcr5A3kPmWxs="
},
"portal-vue": {
"version": "2.1.7",
"resolved": "https://registry.npm.taobao.org/portal-vue/download/portal-vue-2.1.7.tgz",
"integrity": "sha1-6ggGmyW2QMoIpbhvZ8YS8V9OStQ="
},
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.28.tgz?cache=0&sync_timestamp=1596019946887&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fportfinder%2Fdownload%2Fportfinder-1.0.28.tgz",
@ -12379,7 +12476,7 @@
},
"vue": {
"version": "2.6.12",
"resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz?cache=0&sync_timestamp=1600441210971&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.12.tgz",
"resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz",
"integrity": "sha1-9evU+mvShpQD4pqJau1JBEVskSM="
},
"vue-clipboard2": {
@ -12416,6 +12513,11 @@
}
}
},
"vue-functional-data-merge": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/vue-functional-data-merge/download/vue-functional-data-merge-3.1.0.tgz",
"integrity": "sha1-CKd5dYO381aAWH+KHVHXKaodxlc="
},
"vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz",

View File

@ -3,14 +3,17 @@
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"animate.css": "^4.1.1",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.21.1",
"core-js": "^3.6.5",
"element-ui": "^2.13.2",
"lib-flexible": "^0.3.2",
"nprogress": "^0.2.0",
"script-ext-html-webpack-plugin": "^2.1.4",
"svg-sprite-loader": "^5.0.0",

View File

@ -6,7 +6,7 @@
<style lang="less">
body {
margin: 0px;
margin: 0;
}
#app {
@ -15,5 +15,6 @@ body {
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
font-size: 62.5%;
}
</style>

View File

@ -27,28 +27,28 @@ export default {
<style lang="scss" scoped>
a {
margin: 0 15px;
margin: 0 1.5em;
text-decoration: none;
color: #333333;
}
.btn-group {
margin-top: 20px;
margin-top: 2em;
position: relproduct;
display: inline-block;
vertical-align: middle;
.btn-rect {
padding: 0 30px;
min-width: 140px;
height: 40px !important;
line-height: 40px !important;
padding: 0 3em;
min-width: 14em;
height: 4em !important;
line-height: 4em !important;
text-align: center;
border: 1px solid #d1d1d1;
border: 0.1em solid #d1d1d1;
display: inline-block;
color: #111;
padding-left: 20px;
padding-right: 20px;
font-size: 16px;
padding-left: 2em;
padding-right: 2em;
font-size: 1.6em;
background: #efefef;
&:hover {
color: #fff;

View File

@ -3,7 +3,7 @@
<div class="image-box">
<div class="mask" />
<picture>
<el-image style="height: 100%;width: 100%" :src="source" />
<b-img style="height: 100%;width: 100%" :src="source" />
</picture>
</div>
<div class="text-box">
@ -44,7 +44,7 @@ export default {
<style lang="scss" scoped>
.card {
&:hover {
.el-image {
.b-img {
transition: all 0.5s;
transform: scale(1.05);
}
@ -85,9 +85,9 @@ export default {
text-align: left;
transition: all 0.5s;
z-index: 4;
padding: 25px 30px;
font-size: 20px;
bottom: -50px;
padding: 2.5em 3em;
font-size: 2em;
bottom: -5em;
box-sizing: border-box;
&:hover {
@ -109,7 +109,7 @@ export default {
.text {
font-size: 0.875em;
display: block;
margin-bottom: 12px;
margin-bottom: 1.7em;
line-height: 1.8em;
opacity: 0.7;
}
@ -139,7 +139,7 @@ export default {
vertical-align: middle;
float: left;
&:hover {
transform: translateX(5px);
transform: translateX(0.5em);
}
}
}

View File

@ -13,7 +13,7 @@
<div class="card" v-if="active">
<ul>
<li v-for="(el, i) in menus" :key="i" @click="onClick(el, i)">
<i :class="el.icon" style="margin-right: 10px;font-size: 18px" />
<i :class="el.icon" style="margin-right: 1em;font-size: 1.8em" />
<span>{{ el.name }}</span>
</li>
</ul>
@ -60,18 +60,18 @@ export default {
position: relative;
display: flex;
justify-content: center;
height: 40px;
height: 4em;
.block {
display: flex;
align-items: center;
justify-content: center;
i {
font-size: 26px;
font-size: 2.6em;
}
.arrow {
font-size: 14px;
font-size: 1.4em;
}
}
@ -82,20 +82,20 @@ export default {
ul {
padding: 0;
margin: 0;
transform: translateY(59px);
transform: translateY(6em);
background: #fff;
list-style: none;
display: flex;
flex-direction: column;
justify-content: flex-start;
min-width: 180px;
min-width: 18em;
width: auto;
li {
border: 1px solid #d4d4d4;
border: 0.1em solid #d4d4d4;
border-top: 0;
height: 42px;
line-height: 42px;
padding-left: 26px;
height: 4.2em;
line-height: 4.2em;
padding-left: 2.6em;
background: #fff;
color: #777;
text-align: left;

View File

@ -0,0 +1,11 @@
import directive from './src/directive';
import service from './src/index';
export default {
install(Vue) {
Vue.use(directive);
Vue.prototype.$loading = service;
},
directive,
service
};

View File

@ -0,0 +1,133 @@
import Vue from 'vue';
import Loading from './loading.vue';
import { addClass, removeClass, getStyle } from '../utils/dom';
import { PopupManager } from '../utils/popup';
import afterLeave from '../utils/after-leave';
const Mask = Vue.extend(Loading);
const loadingDirective = {};
loadingDirective.install = Vue => {
if (Vue.prototype.$isServer) return;
const toggleLoading = (el, binding) => {
if (binding.value) {
Vue.nextTick(() => {
if (binding.modifiers.fullscreen) {
el.originalPosition = getStyle(document.body, 'position');
el.originalOverflow = getStyle(document.body, 'overflow');
el.maskStyle.zIndex = PopupManager.nextZIndex();
addClass(el.mask, 'is-fullscreen');
insertDom(document.body, el, binding);
} else {
removeClass(el.mask, 'is-fullscreen');
if (binding.modifiers.body) {
el.originalPosition = getStyle(document.body, 'position');
['top', 'left'].forEach(property => {
const scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
el.maskStyle[property] = el.getBoundingClientRect()[property] +
document.body[scroll] +
document.documentElement[scroll] -
parseInt(getStyle(document.body, `margin-${ property }`), 10) +
'px';
});
['height', 'width'].forEach(property => {
el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
});
insertDom(document.body, el, binding);
} else {
el.originalPosition = getStyle(el, 'position');
insertDom(el, el, binding);
}
}
});
} else {
afterLeave(el.instance, _ => {
if (!el.instance.hiding) return;
el.domVisible = false;
const target = binding.modifiers.fullscreen || binding.modifiers.body
? document.body
: el;
removeClass(target, 'el-loading-parent--relative');
removeClass(target, 'el-loading-parent--hidden');
el.instance.hiding = false;
}, 300, true);
el.instance.visible = false;
el.instance.hiding = true;
}
};
const insertDom = (parent, el, binding) => {
if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
Object.keys(el.maskStyle).forEach(property => {
el.mask.style[property] = el.maskStyle[property];
});
if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
addClass(parent, 'el-loading-parent--relative');
}
if (binding.modifiers.fullscreen && binding.modifiers.lock) {
addClass(parent, 'el-loading-parent--hidden');
}
el.domVisible = true;
parent.appendChild(el.mask);
Vue.nextTick(() => {
if (el.instance.hiding) {
el.instance.$emit('after-leave');
} else {
el.instance.visible = true;
}
});
el.domInserted = true;
} else if (el.domVisible && el.instance.hiding === true) {
el.instance.visible = true;
el.instance.hiding = false;
}
};
Vue.directive('loading', {
bind: function(el, binding, vnode) {
const textExr = el.getAttribute('element-loading-text');
const spinnerExr = el.getAttribute('element-loading-spinner');
const backgroundExr = el.getAttribute('element-loading-background');
const customClassExr = el.getAttribute('element-loading-custom-class');
const vm = vnode.context;
const mask = new Mask({
el: document.createElement('div'),
data: {
text: vm && vm[textExr] || textExr,
spinner: vm && vm[spinnerExr] || spinnerExr,
background: vm && vm[backgroundExr] || backgroundExr,
customClass: vm && vm[customClassExr] || customClassExr,
fullscreen: !!binding.modifiers.fullscreen
}
});
el.instance = mask;
el.mask = mask.$el;
el.maskStyle = {};
binding.value && toggleLoading(el, binding);
},
update: function(el, binding) {
el.instance.setText(el.getAttribute('element-loading-text'));
if (binding.oldValue !== binding.value) {
toggleLoading(el, binding);
}
},
unbind: function(el, binding) {
if (el.domInserted) {
el.mask &&
el.mask.parentNode &&
el.mask.parentNode.removeChild(el.mask);
toggleLoading(el, { value: false, modifiers: binding.modifiers });
}
el.instance && el.instance.$destroy();
}
});
};
export default loadingDirective;

View File

@ -0,0 +1,106 @@
import Vue from 'vue';
import loadingVue from './loading.vue';
import { addClass, removeClass, getStyle } from '../utils/dom';
import { PopupManager } from '../utils/popup';
import afterLeave from '../utils/after-leave';
import merge from '../utils/merge';
const LoadingConstructor = Vue.extend(loadingVue);
const defaults = {
text: null,
fullscreen: true,
body: false,
lock: false,
customClass: ''
};
let fullscreenLoading;
LoadingConstructor.prototype.originalPosition = '';
LoadingConstructor.prototype.originalOverflow = '';
LoadingConstructor.prototype.close = function() {
if (this.fullscreen) {
fullscreenLoading = undefined;
}
afterLeave(this, _ => {
const target = this.fullscreen || this.body
? document.body
: this.target;
removeClass(target, 'el-loading-parent--relative');
removeClass(target, 'el-loading-parent--hidden');
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
this.$destroy();
}, 300);
this.visible = false;
};
const addStyle = (options, parent, instance) => {
let maskStyle = {};
if (options.fullscreen) {
instance.originalPosition = getStyle(document.body, 'position');
instance.originalOverflow = getStyle(document.body, 'overflow');
maskStyle.zIndex = PopupManager.nextZIndex();
} else if (options.body) {
instance.originalPosition = getStyle(document.body, 'position');
['top', 'left'].forEach(property => {
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
maskStyle[property] = options.target.getBoundingClientRect()[property] +
document.body[scroll] +
document.documentElement[scroll] +
'px';
});
['height', 'width'].forEach(property => {
maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
});
} else {
instance.originalPosition = getStyle(parent, 'position');
}
Object.keys(maskStyle).forEach(property => {
instance.$el.style[property] = maskStyle[property];
});
};
const Loading = (options = {}) => {
if (Vue.prototype.$isServer) return;
options = merge({}, defaults, options);
if (typeof options.target === 'string') {
options.target = document.querySelector(options.target);
}
options.target = options.target || document.body;
if (options.target !== document.body) {
options.fullscreen = false;
} else {
options.body = true;
}
if (options.fullscreen && fullscreenLoading) {
return fullscreenLoading;
}
let parent = options.body ? document.body : options.target;
let instance = new LoadingConstructor({
el: document.createElement('div'),
data: options
});
addStyle(options, parent, instance);
if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed') {
addClass(parent, 'el-loading-parent--relative');
}
if (options.fullscreen && options.lock) {
addClass(parent, 'el-loading-parent--hidden');
}
parent.appendChild(instance.$el);
Vue.nextTick(() => {
instance.visible = true;
});
if (options.fullscreen) {
fullscreenLoading = instance;
}
return instance;
};
export default Loading;

View File

@ -0,0 +1,41 @@
<template>
<transition name="el-loading-fade" @after-leave="handleAfterLeave">
<div
v-show="visible"
class="el-loading-mask"
:style="{ backgroundColor: background || '' }"
:class="[customClass, { 'is-fullscreen': fullscreen }]">
<div class="el-loading-spinner">
<svg v-if="!spinner" class="circular" viewBox="25 25 50 50">
<circle class="path" cx="50" cy="50" r="20" fill="none"/>
</svg>
<i v-else :class="spinner"></i>
<p v-if="text" class="el-loading-text">{{ text }}</p>
</div>
</div>
</transition>
</template>
<script>
export default {
data() {
return {
text: null,
spinner: null,
background: null,
fullscreen: true,
visible: false,
customClass: ''
};
},
methods: {
handleAfterLeave() {
this.$emit('after-leave');
},
setText(text) {
this.text = text;
}
}
};
</script>

View File

@ -0,0 +1,27 @@
/**
* Bind after-leave event for vue instance. Make sure after-leave is called in any browsers.
*
* @param {Vue} instance Vue instance.
* @param {Function} callback callback of after-leave event
* @param {Number} speed the speed of transition, default value is 300ms
* @param {Boolean} once weather bind after-leave once. default value is false.
*/
export default function(instance, callback, speed = 300, once = false) {
if (!instance || !callback) throw new Error('instance & callback is required');
let called = false;
const afterLeaveCallback = function() {
if (called) return;
called = true;
if (callback) {
callback.apply(null, arguments);
}
};
if (once) {
instance.$once('after-leave', afterLeaveCallback);
} else {
instance.$on('after-leave', afterLeaveCallback);
}
setTimeout(() => {
afterLeaveCallback();
}, speed + 100);
};

View File

@ -0,0 +1,227 @@
/* istanbul ignore next */
import Vue from 'vue';
const isServer = Vue.prototype.$isServer;
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
const ieVersion = isServer ? 0 : Number(document.documentMode);
/* istanbul ignore next */
const trim = function(string) {
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
};
/* istanbul ignore next */
const camelCase = function(name) {
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).replace(MOZ_HACK_REGEXP, 'Moz$1');
};
/* istanbul ignore next */
export const on = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const off = (function() {
if (!isServer && document.removeEventListener) {
return function(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const once = function(el, event, fn) {
var listener = function() {
if (fn) {
fn.apply(this, arguments);
}
off(el, event, listener);
};
on(el, event, listener);
};
/* istanbul ignore next */
export function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
};
/* istanbul ignore next */
export function addClass(el, cls) {
if (!el) return;
var curClass = el.className;
var classes = (cls || '').split(' ');
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else if (!hasClass(el, clsName)) {
curClass += ' ' + clsName;
}
}
if (!el.classList) {
el.className = curClass;
}
};
/* istanbul ignore next */
export function removeClass(el, cls) {
if (!el || !cls) return;
var classes = cls.split(' ');
var curClass = ' ' + el.className + ' ';
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ');
}
}
if (!el.classList) {
el.className = trim(curClass);
}
};
/* istanbul ignore next */
export const getStyle = ieVersion < 9 ? function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'styleFloat';
}
try {
switch (styleName) {
case 'opacity':
try {
return element.filters.item('alpha').opacity / 100;
} catch (e) {
return 1.0;
}
default:
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
}
} catch (e) {
return element.style[styleName];
}
} : function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
return element.style[styleName];
}
};
/* istanbul ignore next */
export function setStyle(element, styleName, value) {
if (!element || !styleName) return;
if (typeof styleName === 'object') {
for (var prop in styleName) {
if (styleName.hasOwnProperty(prop)) {
setStyle(element, prop, styleName[prop]);
}
}
} else {
styleName = camelCase(styleName);
if (styleName === 'opacity' && ieVersion < 9) {
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')';
} else {
element.style[styleName] = value;
}
}
};
export const isScroll = (el, vertical) => {
if (isServer) return;
const determinedDirection = vertical !== null || vertical !== undefined;
const overflow = determinedDirection
? vertical
? getStyle(el, 'overflow-y')
: getStyle(el, 'overflow-x')
: getStyle(el, 'overflow');
return overflow.match(/(scroll|auto)/);
};
export const getScrollContainer = (el, vertical) => {
if (isServer) return;
let parent = el;
while (parent) {
if ([window, document, document.documentElement].includes(parent)) {
return window;
}
if (isScroll(parent, vertical)) {
return parent;
}
parent = parent.parentNode;
}
return parent;
};
export const isInContainer = (el, container) => {
if (isServer || !el || !container) return false;
const elRect = el.getBoundingClientRect();
let containerRect;
if ([window, document, document.documentElement, null, undefined].includes(container)) {
containerRect = {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0
};
} else {
containerRect = container.getBoundingClientRect();
}
return elRect.top < containerRect.bottom &&
elRect.bottom > containerRect.top &&
elRect.right > containerRect.left &&
elRect.left < containerRect.right;
};

View File

@ -0,0 +1,15 @@
export default function(target) {
for (let i = 1, j = arguments.length; i < j; i++) {
let source = arguments[i] || {};
for (let prop in source) {
if (source.hasOwnProperty(prop)) {
let value = source[prop];
if (value !== undefined) {
target[prop] = value;
}
}
}
}
return target;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,218 @@
import Vue from 'vue';
import merge from 'element-ui/src/utils/merge';
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
import getScrollBarWidth from '../scrollbar-width';
import { getStyle, addClass, removeClass, hasClass } from '../dom';
let idSeed = 1;
let scrollBarWidth;
export default {
props: {
visible: {
type: Boolean,
default: false
},
openDelay: {},
closeDelay: {},
zIndex: {},
modal: {
type: Boolean,
default: false
},
modalFade: {
type: Boolean,
default: true
},
modalClass: {},
modalAppendToBody: {
type: Boolean,
default: false
},
lockScroll: {
type: Boolean,
default: true
},
closeOnPressEscape: {
type: Boolean,
default: false
},
closeOnClickModal: {
type: Boolean,
default: false
}
},
beforeMount() {
this._popupId = 'popup-' + idSeed++;
PopupManager.register(this._popupId, this);
},
beforeDestroy() {
PopupManager.deregister(this._popupId);
PopupManager.closeModal(this._popupId);
this.restoreBodyStyle();
},
data() {
return {
opened: false,
bodyPaddingRight: null,
computedBodyPaddingRight: 0,
withoutHiddenClass: true,
rendered: false
};
},
watch: {
visible(val) {
if (val) {
if (this._opening) return;
if (!this.rendered) {
this.rendered = true;
Vue.nextTick(() => {
this.open();
});
} else {
this.open();
}
} else {
this.close();
}
}
},
methods: {
open(options) {
if (!this.rendered) {
this.rendered = true;
}
const props = merge({}, this.$props || this, options);
if (this._closeTimer) {
clearTimeout(this._closeTimer);
this._closeTimer = null;
}
clearTimeout(this._openTimer);
const openDelay = Number(props.openDelay);
if (openDelay > 0) {
this._openTimer = setTimeout(() => {
this._openTimer = null;
this.doOpen(props);
}, openDelay);
} else {
this.doOpen(props);
}
},
doOpen(props) {
if (this.$isServer) return;
if (this.willOpen && !this.willOpen()) return;
if (this.opened) return;
this._opening = true;
const dom = this.$el;
const modal = props.modal;
const zIndex = props.zIndex;
if (zIndex) {
PopupManager.zIndex = zIndex;
}
if (modal) {
if (this._closing) {
PopupManager.closeModal(this._popupId);
this._closing = false;
}
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade);
if (props.lockScroll) {
this.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden');
if (this.withoutHiddenClass) {
this.bodyPaddingRight = document.body.style.paddingRight;
this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10);
}
scrollBarWidth = getScrollBarWidth();
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
let bodyOverflowY = getStyle(document.body, 'overflowY');
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) {
document.body.style.paddingRight = (this.computedBodyPaddingRight + scrollBarWidth)/10 + 'em';
}
addClass(document.body, 'el-popup-parent--hidden');
}
}
if (getComputedStyle(dom).position === 'static') {
dom.style.position = 'absolute';
}
dom.style.zIndex = PopupManager.nextZIndex();
this.opened = true;
this.onOpen && this.onOpen();
this.doAfterOpen();
},
doAfterOpen() {
this._opening = false;
},
close() {
if (this.willClose && !this.willClose()) return;
if (this._openTimer !== null) {
clearTimeout(this._openTimer);
this._openTimer = null;
}
clearTimeout(this._closeTimer);
const closeDelay = Number(this.closeDelay);
if (closeDelay > 0) {
this._closeTimer = setTimeout(() => {
this._closeTimer = null;
this.doClose();
}, closeDelay);
} else {
this.doClose();
}
},
doClose() {
this._closing = true;
this.onClose && this.onClose();
if (this.lockScroll) {
setTimeout(this.restoreBodyStyle, 200);
}
this.opened = false;
this.doAfterClose();
},
doAfterClose() {
PopupManager.closeModal(this._popupId);
this._closing = false;
},
restoreBodyStyle() {
if (this.modal && this.withoutHiddenClass) {
document.body.style.paddingRight = this.bodyPaddingRight;
removeClass(document.body, 'el-popup-parent--hidden');
}
this.withoutHiddenClass = true;
}
}
};
export {
PopupManager
};

View File

@ -0,0 +1,194 @@
import Vue from 'vue';
import { addClass, removeClass } from 'element-ui/src/utils/dom';
let hasModal = false;
let hasInitZIndex = false;
let zIndex;
const getModal = function() {
if (Vue.prototype.$isServer) return;
let modalDom = PopupManager.modalDom;
if (modalDom) {
hasModal = true;
} else {
hasModal = false;
modalDom = document.createElement('div');
PopupManager.modalDom = modalDom;
modalDom.addEventListener('touchmove', function(event) {
event.preventDefault();
event.stopPropagation();
});
modalDom.addEventListener('click', function() {
PopupManager.doOnModalClick && PopupManager.doOnModalClick();
});
}
return modalDom;
};
const instances = {};
const PopupManager = {
modalFade: true,
getInstance: function(id) {
return instances[id];
},
register: function(id, instance) {
if (id && instance) {
instances[id] = instance;
}
},
deregister: function(id) {
if (id) {
instances[id] = null;
delete instances[id];
}
},
nextZIndex: function() {
return PopupManager.zIndex++;
},
modalStack: [],
doOnModalClick: function() {
const topItem = PopupManager.modalStack[PopupManager.modalStack.length - 1];
if (!topItem) return;
const instance = PopupManager.getInstance(topItem.id);
if (instance && instance.closeOnClickModal) {
instance.close();
}
},
openModal: function(id, zIndex, dom, modalClass, modalFade) {
if (Vue.prototype.$isServer) return;
if (!id || zIndex === undefined) return;
this.modalFade = modalFade;
const modalStack = this.modalStack;
for (let i = 0, j = modalStack.length; i < j; i++) {
const item = modalStack[i];
if (item.id === id) {
return;
}
}
const modalDom = getModal();
addClass(modalDom, 'v-modal');
if (this.modalFade && !hasModal) {
addClass(modalDom, 'v-modal-enter');
}
if (modalClass) {
let classArr = modalClass.trim().split(/\s+/);
classArr.forEach(item => addClass(modalDom, item));
}
setTimeout(() => {
removeClass(modalDom, 'v-modal-enter');
}, 200);
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {
dom.parentNode.appendChild(modalDom);
} else {
document.body.appendChild(modalDom);
}
if (zIndex) {
modalDom.style.zIndex = zIndex;
}
modalDom.tabIndex = 0;
modalDom.style.display = '';
this.modalStack.push({ id: id, zIndex: zIndex, modalClass: modalClass });
},
closeModal: function(id) {
const modalStack = this.modalStack;
const modalDom = getModal();
if (modalStack.length > 0) {
const topItem = modalStack[modalStack.length - 1];
if (topItem.id === id) {
if (topItem.modalClass) {
let classArr = topItem.modalClass.trim().split(/\s+/);
classArr.forEach(item => removeClass(modalDom, item));
}
modalStack.pop();
if (modalStack.length > 0) {
modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex;
}
} else {
for (let i = modalStack.length - 1; i >= 0; i--) {
if (modalStack[i].id === id) {
modalStack.splice(i, 1);
break;
}
}
}
}
if (modalStack.length === 0) {
if (this.modalFade) {
addClass(modalDom, 'v-modal-leave');
}
setTimeout(() => {
if (modalStack.length === 0) {
if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom);
modalDom.style.display = 'none';
PopupManager.modalDom = undefined;
}
removeClass(modalDom, 'v-modal-leave');
}, 200);
}
}
};
Object.defineProperty(PopupManager, 'zIndex', {
configurable: true,
get() {
if (!hasInitZIndex) {
zIndex = zIndex || (Vue.prototype.$ELEMENT || {}).zIndex || 2000;
hasInitZIndex = true;
}
return zIndex;
},
set(value) {
zIndex = value;
}
});
const getTopPopup = function() {
if (Vue.prototype.$isServer) return;
if (PopupManager.modalStack.length > 0) {
const topPopup = PopupManager.modalStack[PopupManager.modalStack.length - 1];
if (!topPopup) return;
const instance = PopupManager.getInstance(topPopup.id);
return instance;
}
};
if (!Vue.prototype.$isServer) {
// handle `esc` key when the popup is shown
window.addEventListener('keydown', function(event) {
if (event.keyCode === 27) {
const topPopup = getTopPopup();
if (topPopup && topPopup.closeOnPressEscape) {
topPopup.handleClose
? topPopup.handleClose()
: (topPopup.handleAction ? topPopup.handleAction('cancel') : topPopup.close());
}
}
});
}
export default PopupManager;

View File

@ -0,0 +1,29 @@
import Vue from 'vue';
let scrollBarWidth;
export default function() {
if (Vue.prototype.$isServer) return 0;
if (scrollBarWidth !== undefined) return scrollBarWidth;
const outer = document.createElement('div');
outer.className = 'el-scrollbar__wrap';
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
scrollBarWidth = widthNoScroll - widthWithScroll;
return scrollBarWidth;
};

View File

@ -1,40 +0,0 @@
<template>
<router-link :to="home" class="logo">
<el-image style="width:40px; height:40px" :src="logo" />
<h2>北京玖琏科技有限公司</h2>
</router-link>
</template>
<script>
import logo from "@/assets/logo.png";
export default {
props: {
home: {
type: String,
default: "/home"
}
},
computed: {
logo() {
return logo;
}
}
};
</script>
<style lang="scss">
a {
text-decoration: none;
color: #333333;
}
.logo {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
h2 {
padding: 0 10px;
}
}
</style>

View File

@ -67,8 +67,8 @@ export default {
},
loadFile(url) {
this.loading = true;
let loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise
let pdfTask = pdfjsLib.getDocument(url);
pdfTask.promise
.then(pdf => {
this.pdfDoc = pdf;
this.numPages = this.pdfDoc.numPages;
@ -107,8 +107,8 @@ export default {
if (canvas) {
canvas.width = width * ratio;
canvas.height = height * ratio;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.style.width = width/10 + "em";
canvas.style.height = height/10 + "em";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
let renderTask = page.render({

View File

@ -3,11 +3,11 @@
<transition name="el-fade-in">
<el-input
v-show="show"
style="width:430px"
style="width:43em"
placeholder="请输入关键词"
v-model="search"
>
<el-button slot="append" icon="el-icon-search" @click="onSearch" />
<b-button slot="append" icon="el-icon-search" @click="onSearch" />
</el-input>
</transition>
<transition name="el-fade-in">
@ -15,7 +15,7 @@
<a
class="el-icon-close"
@click="onHide"
style="font-size: 26px;margin-left: 10px"
style="font-size: 2.6em;margin-left: 1em"
/>
</div>
<div v-else class="flex">
@ -23,7 +23,7 @@
<a
class="el-icon-search"
@click="onShow"
style="font-size: 26px;margin-left: 10px"
style="font-size: 2.6em;margin-left: 1em"
/>
<slot name="after" />
</div>

View File

@ -91,25 +91,25 @@ export default {
<style lang="scss" scoped>
@media screen and (min-width: 576px) {
.video {
max-width: 540px;
max-width: 54em;
}
}
@media screen and (min-width: 768px) {
.video {
max-width: 720px;
max-width: 72em;
}
}
@media screen and (min-width: 992px) {
.video {
max-width: 960px;
max-width: 96em;
}
}
@media screen and (min-width: 1200px) {
.video {
max-width: 1140px;
max-width: 114em;
}
}

View File

@ -1,17 +1,17 @@
<template>
<div class="copy">
<template v-for="(el, i) in copys">
<router-link :key="i" v-if="el.href" :to="el.href">
{{ el.name }}
</router-link>
<span :key="i" v-else> {{ el.name }} </span>
</template>
<div class="line" />
<ul class="list-unstyled">
<li v-for="(el, i) in links" :key="i">
<router-link :to="el.href"> {{ el.name }}</router-link>
</li>
</ul>
<div class="container">
<div v-for="(el, i) in copys" :key="i">
<b-link v-if="el.href" :href="el.href">
{{ el.name }}
</b-link>
<span v-else> {{ el.name }} </span>
</div>
<div class="line" />
<div v-for="(el, i) in links" :key="copys.length+i">
<b-link :href="el.href"> {{ el.name }}</b-link>
</div>
</div>
</div>
</template>
@ -46,35 +46,26 @@ export default {
</script>
<style lang="scss" scoped>
.list-unstyled {
list-style: none;
}
a {
text-decoration: none;
color: #595757;
}
.copy {
width: 100%;
position: absolute;
left: 0;
overflow: hidden;
background-color: #e6e6e6;
text-align: center;
margin-top: 40px;
height: 50px;
line-height: 50px;
padding: 0;
font-size: 15px;
color: #666;
display: flex;
justify-content: center;
align-items: center;
a,
span {
margin: 0 10px;
}
ul {
display: inline-flex;
padding: 0px;
.container {
width: 100%;
height: 5em;
display: flex;
justify-content: center;
align-items: center;
}
.line {

View File

@ -1,56 +1,45 @@
<template>
<div class="custom">
<div class="footer-nav">
<div
class="col-md"
<b-row>
<b-col
v-for="(it, i) in abouts"
:key="i"
:style="{ 'text-align': i == abouts.length - 1 ? 'center' : '' }"
style="min-width:20em"
>
<h3 class="collapsed">
<h5>
{{ it.name }}
<span class="iconfont icon-arrow-down hidden-md hidden-lg"></span>
</h3>
<div class="collapse navbar-collapse row">
<ul
class="list-unstyled col-md"
v-for="(el, j) in it.children"
:key="j"
>
<li>
<router-link v-if="el.href" :to="el.href">
{{ el.name }}
</router-link>
<el-popover
v-else-if="el.src"
placement="top"
width="200"
trigger="hover"
>
<el-image style="width:100%;height:100%;" :src="el.src" />
<el-image
slot="reference"
style="width:80px;height:80px"
:src="el.src"
/>
</el-popover>
</li>
</ul>
</div>
</div>
</div>
<div class="footer-link">
<div class="title">合作方</div>
<ul class="list-unstyled share">
<li v-for="(el, i) in images" :key="i">
<el-tooltip placement="top" :content="el.name" effect="light">
<el-image style="width:80px;height:80px;" :src="el.src" />
</el-tooltip>
</li>
</ul>
</div>
</h5>
<ul
class="col-md"
v-for="(el, j) in it.children"
:key="j"
>
<li>
<b-link v-if="el.href" :href="el.href">
<h6> {{ el.name }} </h6>
</b-link>
<b-img
v-else-if="el.src"
style="width:14em;height:14em"
:src="el.src"
/>
</li>
</ul>
</b-col>
</b-row>
<b-row style="margin-top:3em;padding-bottom:3em">
<b-col>
<h5>合作方</h5>
<ul>
<li>
<template v-for="(el, i) in images" >
<b-img :key="i" v-b-tooltip.hover :title="el.name" style="width:8em;height:8em;margin-right:17px" :src="el.src" />
</template>
</li>
</ul>
</b-col>
</b-row>
</div>
</template>
@ -146,75 +135,20 @@ export default {
};
</script>
<style lang="scss" scoped>
.list-unstyled {
list-style: none;
}
.title {
font-size: 15px;
line-height: 22px;
color: #595757;
}
a {
text-decoration: none;
color: #595757;
}
ul,li {
list-style: none;
padding: 0;
margin: 0;
}
.custom {
position: relative;
width: 85.652%;
max-width: 1430.016px;
margin-right: auto;
margin-left: auto;
.footer-nav {
display: flex;
justify-content: space-between;
padding: 20px 0;
border-bottom: 1px solid #e2e2e2;
margin-bottom: 38px;
h3 {
font-size: 18px;
}
ul {
border: none;
padding: 0;
margin-bottom: 15px;
font-size: 15px;
line-height: 22px;
color: #595757;
}
}
.footer-link {
.title {
margin-bottom: 28px;
}
.share {
display: flex;
justify-content: flex-start;
padding: 0;
width: 90%;
margin: auto;
li {
display: inline-block;
margin: 0 8px;
vertical-align: middle;
i {
font-size: 42px;
color: #3f3f3f;
&:hover {
color: #000;
}
}
}
}
}
}
</style>

View File

@ -20,10 +20,10 @@ export default {
<style lang="scss" scoped>
.footer {
background-color: #f1f1f1;
position: relative;
bottom: 0;
.container {
background-color: #f1f1f1;
overflow: hidden;
text-align: left;
}

View File

@ -0,0 +1,48 @@
<template>
<div @mouseenter.stop="onMouseEnter" @mouseleave.stop="onMouseLeave">
<template v-if="hasChildren">
<b-navbar-nav>
<b-nav-item-dropdown :text="node.meta.name" right style="font-size:16px">
<template v-for="(el, j) in node.children" >
<e-menu-item :key="j" :node="el" />
</template>
</b-nav-item-dropdown>
</b-navbar-nav>
</template>
<template v-else>
<b-nav-item :href="node.redirect||node.path" style="font-size:16px">
{{ node.meta.name }}
</b-nav-item>
</template>
</div>
</template>
<script>
export default {
name: "eMenuItem",
props: {
node: {
type: Object,
required: true
}
},
data() {
return {
show: false
};
},
computed: {
hasChildren() {
return this.node.children&&this.node.children.length
}
},
methods: {
onMouseEnter() {
this.show = true;
},
onMouseLeave() {
this.show = false;
}
}
};
</script>

View File

@ -0,0 +1,37 @@
<template>
<b-navbar-nav class="flex">
<template v-for="(node, i) in routes">
<e-menu-item v-if="!node.hidden"
:key="i"
:node="node"/>
</template>
</b-navbar-nav>
</template>
<script>
import eMenuItem from './eMenuItem';
export default {
components: {
eMenuItem
},
props: {
routes: {
type: Array,
required: true
}
},
data() {
return {
};
}
};
</script>
<style lang="scss" scoped>
.flex {
display: flex;
justify-content: center;
align-items: center;
}
</style>

View File

@ -0,0 +1,89 @@
<template>
<header class="header">
<b-navbar class="sticky" toggleable="lg" type="light" variant="light">
<b-navbar-brand href="#">
<b-img :src="logo" fluid alt="logo" style="width:2em; height:2em" />
<span style="margin: 0 0.6em">北京玖琏科技有限公司</span>
</b-navbar-brand>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<e-menu-list class="center" :routes="routes"/>
<!-- <b-navbar-nav class="ml-auto">
<b-nav-item-dropdown text="语言" right>
<b-dropdown-item href="#">CH</b-dropdown-item>
<b-dropdown-item href="#">EN</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item-dropdown right>
<template #button-content>
<em>用户</em>
</template>
<b-dropdown-item href="#">信息</b-dropdown-item>
<b-dropdown-item href="#">登出</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav> -->
</b-collapse>
</b-navbar>
</header>
</template>
<script>
import logo from "@/assets/logo.png";
import eMenuList from "./eMenuList.vue";
import router from '@/router/index';
export default {
components: {
eMenuList
},
data() {
return {
scrollT: 0,
logo: logo,
routes: router.options.routes[0].children,
};
},
mounted() {
window.addEventListener("scroll", this.onScroll);
},
destroyed() {
window.removeEventListener("scroll", this.onScroll);
},
methods: {
onScroll(e) {
let headerEl = document.querySelector(".header");
let stickyEl = document.querySelector(".sticky");
let stickyT = stickyEl.offsetTop;
let scrollT = e.target.scrollingElement.scrollTop;
let diff = scrollT - this.scrollT;
if (scrollT < 160) {
if (scrollT > stickyT) {
headerEl.classList.add("fixed-top");
} else {
headerEl.classList.remove("fixed-top");
}
} else {
if (diff > 0) {
headerEl.style.top = "-7.8em";
} else {
headerEl.style.top = "0";
}
}
this.scrollT = scrollT;
}
}
};
</script>
<style lang="scss" scoped>
.fixed-top {
background: #fff;
position: fixed;
top: 0;
transition: top 0.5s;
z-index: 99;
width: 100%;
overflow: hidden;
}
</style>

25
src/layout/index.vue Normal file
View File

@ -0,0 +1,25 @@
<template>
<div class="layout">
<e-header />
<transition name="fade" mode="out-in">
<router-view />
</transition>
<e-footer />
</div>
</template>
<script>
import eHeader from "./eHeader/index";
import eFooter from "./eFooter/index";
export default {
components: {
eHeader,
eFooter
}
};
</script>
<style lang="scss" scoped>
.layout {
min-height: 100vh;
}
</style>

View File

@ -1,14 +1,15 @@
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import ElementUI from "element-ui";
import VueVideoPlayer from "vue-video-player";
import VueClipboard from "vue-clipboard2";
import Animated from "animate.css";
import Loading from '@/components/eLoading/index';
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import "./permission";
import "element-ui/lib/theme-chalk/index.css";
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import "video.js/dist/video-js.css";
import "vue-video-player/src/custom-theme.css";
import "videojs-flash";
@ -20,13 +21,14 @@ import "@/style/iconfont.css";
window.router = router;
Vue.config.productionTip = false;
Vue.use(ElementUI);
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)
Vue.use(VueVideoPlayer);
Vue.use(VueClipboard);
Vue.use(Animated);
Vue.use(Loading);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");

View File

@ -1,7 +1,7 @@
import Vue from "vue";
import VueRouter from "vue-router";
import Layout from "../views/Layout/index.vue";
import Home from "../views/Home/index.vue";
import Layout from "@/layout/index.vue";
import Home from "@/views/Home/index.vue";
Vue.use(VueRouter);
@ -15,20 +15,17 @@ const routes = [
path: "/",
component: Layout,
children: [
{
path: "/home",
name: "Home",
component: Home
},
{
path: "/preview/pdf",
name: "PreviewPdf",
hidden: true,
component: () =>
import(/* webpackChunkName: "pdf" */ "../views/PreviewPdf/index.vue")
},
{
path: "/preview/image",
name: "PreviewImage",
hidden: true,
component: () =>
import(
/* webpackChunkName: "image" */ "../views/PreviewImage/index.vue"
@ -37,20 +34,51 @@ const routes = [
{
path: "/preview/player",
name: "PreviewPlayer",
hidden: true,
component: () =>
import(
/* webpackChunkName: "player" */ "../views/PreviewPlayer/index.vue"
)
},
{
path: "/home",
name: "Home",
meta: {
name: '首页'
},
component: Home
},
{
path: "/honor",
name: "Honor",
meta: {
name: '我们的产品'
},
component: () =>
import(/* webpackChunkName: "honor" */ "../views/Honor/index.vue")
import(/* webpackChunkName: "honor" */ "../views/Exhibition/index.vue")
},
{
path: "/exhibition",
name: "Exhibition",
meta: {
name: '经典案例'
},
children: [
{
path: '/',
redirect: "/preview/pdf?src=西安铁路职业技术学院.pdf",
meta: {
name: "西安铁路职业技术学院",
}
},
{
path: '/',
redirect: "/preview/pdf?src=贵州装备制造职业学院机电技术专业实训室建设.pdf",
meta: {
name: "贵州装备制造职业学院",
}
}
],
component: () =>
import(
/* webpackChunkName: "exhibition" */ "../views/Exhibition/index.vue"
@ -59,12 +87,18 @@ const routes = [
{
path: "/about",
name: "About",
meta: {
name: '关于玖琏'
},
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
},
{
path: "/relation",
name: "Relation",
meta: {
name: '联系我们'
},
component: () =>
import(/* webpackChunkName: "relation" */ "../views/Relation.vue")
}

View File

@ -1,11 +0,0 @@
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {}
});

View File

@ -9,7 +9,7 @@
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-size: 1.6em;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

View File

@ -2,7 +2,7 @@
<div class="main">
<div class="container">
<article id="introduce">
<h3>公司简介</h3>
<h6>公司简介</h6>
<p>
北京玖琏科技有限公司成立于2017年1月3日公司总部位于首都北京在古都西安设有研发中心公司致力服务于轨道交通行业化学化工行业电力电厂行业等
针对各个行业需求及痛点提供一体化培训解决方案我公司自主研发的行业数字孪生云平台力求站在行业内城市轨道交通的最前沿集云计算真实系统逻辑及日常
@ -11,24 +11,17 @@
铁路职业技术学院等多所高校合作完成相关培训中心和实验室建设等
</p>
<div class="images">
<el-image class="world" style="width:50%;height:auto" :src="world" />
<b-img class="world" style="width:50%;height:auto" :src="world" />
<div class="group" style="width:50%;height:auto">
<template v-for="(el, i) in imageList">
<el-tooltip
placement="top"
:content="el.name"
:key="i"
effect="light"
>
<el-image style="width:30%;height:30%" :src="el.src" />
</el-tooltip>
<b-img :key="i" v-b-tooltip.hover :title="el.name" style="width:30%;height:30%" :src="el.src" />
</template>
</div>
</div>
</article>
<article id="proxy">
<h3>招商及代理</h3>
<h6>招商及代理</h6>
<p>
为进一步加快行业职教互联网化进程提高职业教育的教学水平提升个人能力的共享实训平台我公司长期面向社会寻求代理合作
代理商主要负责市场推广及商务交流项目招投标等内容详情咨询
@ -37,17 +30,14 @@
</p>
</article>
<article id="join" style="padding-top: 360px">
<div class="image-box">
<el-image class="image" :src="offer" />
<h3>加入玖琏</h3>
<p>
你的加入可以给我们带来新的活力我们同样也可以赠你无限的发展空间世界那么大你不来谁知道你牛逼多一份了解多一份选择
选择不对努力白费寻找合伙人寻找最优秀的你欢迎将你的简历投递至
<strong><em>henry@joylink.club</em></strong>
</p>
</div>
<article id="join">
<b-img style="width:100%;height:auto" :src="offer" />
<h6>加入玖琏</h6>
<p>
你的加入可以给我们带来新的活力我们同样也可以赠你无限的发展空间世界那么大你不来谁知道你牛逼多一份了解多一份选择
选择不对努力白费寻找合伙人寻找最优秀的你欢迎将你的简历投递至
<strong><em>henry@joylink.club</em></strong>
</p>
</article>
</div>
</div>
@ -97,27 +87,23 @@ export default {
.main {
text-align: left;
background: #f7f7f9;
padding: 10px;
padding: 1em;
.container {
width: 50%;
width: 80%;
margin: auto;
background: #fff;
padding: 80px;
padding: 4.8em;
article {
position: relative;
margin-bottom: 70px;
padding-bottom: 7em;
p {
text-indent: 2em;
}
.image-box {
position: absolute;
left: calc(-80px - 2.5%);
right: -80px;
top: 0;
h3 {
h6 {
position: absolute;
top: 25%;
left: 28%;
@ -138,7 +124,6 @@ export default {
display: flex;
align-items: center;
justify-content: space-around;
height: 420px;
.world {
width: 49%;
height: auto;

View File

@ -1,8 +1,8 @@
<template>
<div class="errPage-container">
<el-button icon="arrow-left" class="pan-back-btn" @click="back">
<b-button icon="arrow-left" class="pan-back-btn" @click="back">
返回
</el-button>
</b-button>
<el-row>
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">
@ -68,7 +68,7 @@ export default {
<style lang="scss" scoped>
.errPage-container {
width: 800px;
width: 80em;
max-width: 100%;
margin: 100px auto;

View File

@ -1,30 +1,28 @@
<template>
<div class="main">
<div class="container">
<el-card shadow="never">
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
style="width: 100%;"
>
<el-table-column prop="platform" label="平台" width="200" />
<el-table-column prop="name" label="系统名称" />
<el-table-column prop="href" label="系统入口">
<template slot-scope="{ row }">
<i
v-clipboard:copy="row.href"
v-clipboard:success="onCopy"
v-clipboard:error="onError"
class="el-icon-document-copy"
/>
<a style="margin-left: 10px" target="_blank" :href="row.href">
{{ row.href }}
</a>
</template>
</el-table-column>
</el-table>
</el-card>
<b-table
sticky-header
striped
bordered
hover
:items="items"
:fields="fields"
style="margin-top:5em;min-height:100vh"
outlined
>
<template #cell(href)="data">
<i
v-clipboard:copy="data.item.href"
v-clipboard:success="onCopy"
v-clipboard:error="onError"
class="el-icon-document-copy"
/>
<a style="margin-left: 10px" target="_blank" :href="data.item.href">
{{ data.item.href }}
</a>
</template>
</b-table>
</div>
</div>
</template>
@ -34,7 +32,23 @@ export default {
return {};
},
computed: {
tableData() {
fields() {
return [
{
key: 'platform',
label: '平台',
},
{
key: 'name',
label: '系统名称',
},
{
key: 'href',
label: '系统入口'
}
]
},
items() {
return [
{
platform: "轨道交通",
@ -42,12 +56,12 @@ export default {
href: "https://joylink.club/cbtc"
},
{
platform: "",
platform: "轨道交通",
name: "城轨设计平台",
href: "https://joylink.club/cbtc/design"
},
{
platform: "",
platform: "轨道交通",
name: "国赛备战版",
href: "https://joylink.club/cbtc/login?project=drts"
},
@ -65,20 +79,6 @@ export default {
}
},
methods: {
objectSpanMethod({ rowIndex, columnIndex }) {
const sum = 3;
if (columnIndex === 0) {
if (rowIndex < sum) {
if (rowIndex % sum == 0) {
return { rowspan: sum, colspan: 1 };
} else {
return { rowspan: 0, colspan: 0 };
}
} else {
return { rowspan: 1, colspan: 1 };
}
}
},
onCopy() {
this.$message.success("复制成功");
},
@ -90,35 +90,11 @@ export default {
</script>
<style lang="scss" scoped>
.main {
background: #f7f7f9;
background: #fff;
width: 100%;
.container {
padding: 10px;
width: 70%;
max-width: 1430.016px;
width: 100%;
margin: auto;
text-align: left;
padding-bottom: 200px;
/deep/ {
.el-card__body {
padding: 80px;
}
tr {
pointer-events: none;
}
}
i,
a {
display: inline-block;
line-height: 32px;
color: #373737;
pointer-events: auto;
&:hover {
font-weight: bold;
}
}
}
}
</style>

View File

@ -30,10 +30,9 @@ export default {
<style lang="scss" scoped>
.main {
display: inline-block;
width: 100%;
.container {
width: 70%;
width: 100%;
margin: auto;
}
}

View File

@ -1,27 +1,33 @@
<template>
<div class="container">
<div class="title-box">
<h2>{{ title }}</h2>
<h3>{{ title }}</h3>
</div>
<el-card shadow="always">
<el-carousel
class="carousel"
type="card"
:interval="5000"
arrow="always"
height="480px"
>
<el-carousel-item v-for="(el, i) in imageList" :key="i">
<router-link to="/honor">
<el-image
style="width:auto;height:100%"
:src="buildUrl(el.src)"
></el-image>
</router-link>
</el-carousel-item>
</el-carousel>
</el-card>
<e-button-group :buttonList="buttonList" />
<b-card>
<b-link href="/honor">
<b-carousel
id="carousel-1"
v-model="slide"
:interval="4000"
controls
indicators
background="#ababab"
img-width="1024"
img-height="480"
style="text-shadow: 1px 1px 2px #333;"
@sliding-start="onSlideStart"
@sliding-end="onSlideEnd"
>
<b-carousel-slide
v-for="(el, i) in imageList" :key="i"
caption=""
text=""
:img-src="buildUrl(el.src)"
></b-carousel-slide>
</b-carousel>
</b-link>
</b-card>
<b-button-group :buttonList="buttonList" />
</div>
</template>
@ -35,7 +41,10 @@ export default {
eButtonGroup
},
data() {
return {};
return {
slide: 0,
sliding: null
};
},
computed: {
title() {
@ -49,43 +58,45 @@ export default {
},
buttonList() {
return [
// {
// name: "",
// href: "/honor"
// }
];
}
},
methods: {}
methods: {
onSlideStart(slide) {
this.sliding = true
},
onSlideEnd(slide) {
this.sliding = false
}
}
};
</script>
<style lang="scss" scoped>
.container {
margin-bottom: 80px !important;
margin-bottom: 5em !important;
.title-box {
margin-bottom: 50px !important;
h2 {
margin-bottom: 3em !important;
h3 {
color: #333;
text-align: center;
position: relative;
padding: 0;
padding-bottom: 8px;
padding-bottom: 0.8em;
display: inline-block;
margin: 0;
float: none !important;
max-width: 80%;
font-size: 1.9em;
&::after {
content: "";
width: 100%;
height: 7px;
height: 0.5em;
background-color: red;
position: absolute;
left: 0;
margin-left: 0px;
bottom: 0;
min-width: 35px;
min-width: 3.5em;
}
}
}

View File

@ -1,37 +1,28 @@
<template>
<div class="product-layer">
<div class="title-box">
<h2 class="title">
{{ title }}
</h2>
<h3> {{ title }} </h3>
</div>
<el-card shadow="naver">
<div class="container">
<div
class="product card"
v-for="(el, i) in productList"
:key="i"
@click="goLinkPage(el, i)"
>
<el-image :src="el.src" style="width:100%;height:auto;" fit="cover" />
<div
class="type"
:style="{
background: `linear-gradient(45deg, ${el.type}, transparent)`
}"
<b-card>
<b-row>
<b-col v-for="(el, i) in productList" :key="i" style="min-width:20em">
<b-card
:title="el.name"
:img-src="el.src"
img-alt="Image"
img-top
tag="article"
class="mb-2"
>
{{ el.name }}
</div>
<div class="textbox" />
<div class="context" style="overflow-wrap: break-word;">
<div class="describe">
<div>
{{ el.describe }}
</div>
</div>
</div>
</div>
</el-card>
<e-button-group :buttonList="buttonList" />
<b-button :href="el.href" variant="primary">详情</b-button>
</b-card>
</b-col >
</b-row>
</b-card>
<b-button-group :buttonList="buttonList" />
</div>
</template>
@ -82,10 +73,6 @@ export default {
},
buttonList() {
return [
// {
// name: "",
// href: "/honor"
// }
];
}
},
@ -106,142 +93,30 @@ a {
.product-layer {
text-align: center;
position: relative;
margin-bottom: 80px !important;
margin-bottom: 5em !important;
.title-box {
margin-bottom: 50px !important;
h2 {
margin-bottom: 3em !important;
h3 {
color: #333;
text-align: center;
position: relative;
padding: 0;
padding-bottom: 8px;
padding-bottom: 0.8em;
display: inline-block;
margin: 0;
float: none !important;
max-width: 80%;
font-size: 1.9em;
&::after {
content: "";
width: 100%;
height: 7px;
height: 0.5em;
background-color: brown;
position: absolute;
left: 0;
margin-left: 0px;
margin-left: 0;
bottom: 0;
min-width: 35px;
}
}
}
.container {
display: grid;
margin-bottom: 30px;
grid-template-columns: repeat(3, 33.33%);
grid-gap: 20px 20px;
.card {
position: relative;
cursor: pointer;
border: 1px solid #e4e7ed;
&:hover {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
}
.product {
.type {
top: 0;
left: 0px;
position: absolute;
padding: 7px 20px;
text-align: center;
max-width: 90%;
color: #fff;
opacity: 0.5;
font-size: 14px;
z-index: 8;
border-radius: 3px;
}
.textbox {
position: absolute;
left: 0;
bottom: 0;
height: 80px;
width: 100%;
box-sizing: border-box;
text-align: left;
background: #3a68c2;
opacity: 0.8;
}
.context {
position: absolute;
box-sizing: border-box;
left: 0;
bottom: 0;
height: 80px;
width: 100%;
padding: 20px;
text-align: left;
color: #fff;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
.describe {
display: block;
overflow: hidden;
height: auto;
margin-bottom: 0;
font-size: 16px;
clear: both;
}
}
.layer {
padding: 20px;
background: #f1f1f1;
overflow-y: auto;
border: 1px solid #d1d1d1;
height: 485px;
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-track {
background: rgb(239, 239, 239);
border-radius: 2px;
}
&::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #666;
}
&::-webkit-scrollbar-corner {
background: #fff;
}
li {
list-style: none;
text-align: left;
cursor: pointer;
h4 {
margin-bottom: 0;
word-break: break-word;
overflow: auto;
}
&:hover {
color: #000;
}
}
min-width: 3.5em;
}
}
}

View File

@ -1,12 +1,28 @@
<template>
<div class="main">
<el-carousel height="640px">
<el-carousel-item v-for="(el, i) in imageList" :key="i">
<el-image style="height:100%;width:100%" :src="el.src" />
</el-carousel-item>
</el-carousel>
<b-carousel
id="carousel-1"
v-model="slide"
:interval="4000"
controls
indicators
background="#ababab"
img-width="1024"
img-height="480"
style="text-shadow: 1px 1px 2px #333;"
@sliding-start="onSlideStart"
@sliding-end="onSlideEnd"
>
<b-carousel-slide
v-for="(el, i) in imageList"
:key="i"
caption=""
text=""
:img-src="el.src">
</b-carousel-slide>
</b-carousel>
<div class="content">
<e-button-group :buttonList="buttonList" />
<b-button-group :buttonList="buttonList" />
</div>
</div>
</template>
@ -20,7 +36,10 @@ export default {
eButtonGroup
},
data() {
return {};
return {
slide: 0,
sliding: null
};
},
computed: {
imageList() {
@ -33,30 +52,33 @@ export default {
},
buttonList() {
return [
// {
// name: "",
// href: "/honor"
// }
];
}
},
methods: {
onSlideStart(slide) {
this.sliding = true
},
onSlideEnd(slide) {
this.sliding = false
}
}
};
</script>
<style lang="scss" scoped>
.main {
max-width: 1920px;
margin-left: auto;
margin-right: auto;
position: relative;
overflow: hidden;
margin-bottom: 80px !important;
margin-bottom: 0.5em !important;
.content {
position: absolute;
display: inline-block;
vertical-align: middle;
bottom: 140px;
left: 360px;
bottom: 14em;
left: 36em;
}
}
</style>

View File

@ -1,27 +1,17 @@
<template>
<div class="recommend">
<div class="title-box">
<h2>{{ title }}</h2>
<h3>{{ title }}</h3>
</div>
<div class="container">
<el-card shadow="never" style="margin-bottom:30px">
<div slot="header" class="clearfix" style="text-align:left">
<span>精彩视频</span>
</div>
<div class="flex">
<div
class="item"
style="flex:1;min-width:460px"
v-for="(el, i) in videoList"
:key="i"
@click="goLinkPage"
:style="{
'grid-column-start': el.start,
'grid-column-end': el.end
}"
>
<b-card style="margin-bottom:3em" header-tag="header">
<template #header>
<h6 style="display:flex">精彩视频</h6>
</template>
<b-row>
<b-col v-for="(el, i) in videoList" :key="i" style="width:30em">
<iframe
style="width:calc(100% - 10px);height:420px"
style="position: relative;left: -1.3em;"
:src="el.source"
scrolling="no"
border="0"
@ -29,26 +19,27 @@
framespacing="0"
allowfullscreen="true"
/>
</div>
</div>
</el-card>
<el-card shadow="never">
<div slot="header" class="clearfix" style="text-align:left">
<span>精彩图集</span>
</div>
<div class="grid">
<div v-for="(el, i) in imagesList" :key="i" class="item">
<div class="info-box">
<h3>{{ el.name }}</h3>
</div>
<router-link :to="`/preview/image?id=${i}`">
<el-image lazy style="width:100%;height:auto" :src="el.src" />
</router-link>
</div>
</div>
</el-card>
</b-col>
</b-row>
</b-card>
<b-card header-tag="header">
<template #header>
<h6 style="display:flex">精彩图集</h6>
</template>
<b-row>
<b-col v-for="(el, i) in imageList" :key="i" style="min-width:30em">
<b-link :href="`/preview/image?id=${i}`">
<b-card class="text-center" :img-src="el.src" :img-alt="el.name">
<template>
<h6 class="mb-0">{{ el.name }}</h6>
</template>
</b-card>
</b-link>
</b-col>
</b-row>
</b-card>
</div>
<e-button-group :buttonList="buttonList" />
<b-button-group :buttonList="buttonList" />
</div>
</template>
@ -89,140 +80,133 @@ export default {
}
];
},
imagesList() {
imageList() {
return Object.values(images);
},
buttonList() {
return [
// {
// name: "",
// href: "/preview/player?id=0"
// },
// {
// name: "",
// href: "/preview/image?id=0"
// }
];
}
},
methods: {
check(el, type) {
return el.type == type;
},
goLinkPage() {}
}
}
};
</script>
<style lang="scss" scoped>
a {
text-decoration: none;
font-size: 14px;
color: #666;
&:hover {
color: #3f3f3f;
}
}
.title {
color: #111;
font-weight: 500;
font-size: 20px;
margin-bottom: 10px;
cursor: pointer;
}
.notes {
color: #111;
text-align: left;
padding: 10px 0;
display: block;
width: 100%;
overflow: hidden;
font-size: 15px;
font-weight: 400;
line-height: 22px;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
&:hover {
color: #ff5c38;
}
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px 20px;
.item {
width: 100%;
}
}
.flex {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
box-sizing: border-box;
.item {
margin-bottom: 20px;
}
}
.recommend {
margin: auto;
margin-bottom: 80px !important;
.el-image {
&:hover {
/deep/ img {
transform: scale(1.1);
transition: all 0.5s;
}
}
}
margin-bottom: 5em !important;
.title-box {
margin-bottom: 50px !important;
h2 {
margin-bottom: 3em !important;
h3 {
color: #333;
text-align: center;
position: relative;
padding: 0;
padding-bottom: 8px;
padding-bottom: 0.5em;
display: inline-block;
margin: 0;
float: none !important;
max-width: 80%;
font-size: 1.9em;
&::after {
content: "";
width: 100%;
height: 7px;
height: 0.5em;
background-color: navy;
position: absolute;
left: 0;
margin-left: 0px;
margin-left: 0;
bottom: 0;
min-width: 35px;
min-width: 3.5em;
}
}
}
.container {
margin: auto;
}
.info-box {
position: relative;
top: 0;
text-align: left;
color: #fff;
background: linear-gradient(45deg, crimson, transparent);
left: 0;
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 2em 2em;
}
h3 {
margin: 0;
padding: 5px 10px;
}
}
.component {
width: 200px;
background: #ff0000;
font-size: 30px;
}
@media (min-width: 320px) {
.component {
width: 300px;
background: #00ffff;
font-size: 23px;
}
}
@media (min-width: 375px) {
.component {
width: 360px;
background: #0000ff;
font-size: 26px;
}
}
@media (min-width: 375px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
background: #6666ff;
}
}
@media (max-width: 480px) {
.component {
background: #00ff00;
}
}
@media (max-width: 767px) {
.component {
background: #00ff00;
}
}
@media (min-width: 768px) and (max-width: 979px) {
.component {
width: 600px;
background: #00ff00;
font-size: 30px;
}
}
@media (max-width: 979px) {
.component {
background: #00fff0;
}
}
@media (min-width: 980px) {
.component {
width: 900px;
background: #00ff00;
font-size: 35px;
}
}
@media (min-width: 1200px) {
.component {
width: 1000px;
background: #00ff00;
}
}
</style>

View File

@ -4,31 +4,29 @@
<article id="knowledge">
<h2 style="background:yellowgreen;">知识产权</h2>
<div class="flex">
<el-card
<b-card
class="image"
shadow="hover"
v-for="(el, i) in pdfList"
:key="i"
>
<a target="_blank" :href="buildUrl(el.src)">
<el-image :src="buildUrl(el.src)" class="image-knowledge" />
<b-img :src="buildUrl(el.src)" class="image-knowledge" />
</a>
</el-card>
</b-card>
</div>
</article>
<article id="honor">
<h2 style="background:crimson;">&ensp;&ensp;</h2>
<div class="flex">
<el-card
<b-card
class="image"
shadow="hover"
v-for="(el, i) in imgList"
:key="i"
>
<a target="_blank" :href="buildUrl(el.src)">
<el-image :src="buildUrl(el.src)" lazy class="image-honor" />
<b-img :src="buildUrl(el.src)" lazy class="image-honor" />
</a>
</el-card>
</b-card>
</div>
</article>
</div>
@ -78,8 +76,6 @@ export default {
.container {
background: #fff;
padding-left: 80px;
padding-right: 80px;
padding-bottom: 120px;
padding-top: 30px;
height: 100%;
@ -105,14 +101,16 @@ export default {
&-knowledge {
display: block;
width: 415px !important;
height: 564px !important;
max-width: 520px !important;
width: 100% !important;
height: auto !important;
}
&-honor {
display: block;
width: 415px !important;
height: 293px !important;
max-width: 520px !important;
width: 100% !important;
height: auto !important;
}
}
}

View File

@ -1,83 +0,0 @@
<template>
<li class="menu-item" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
<div class="title" @click.self="goLinkPage(node)">{{ node.name }}</div>
<ul class="list" v-if="show && node.children && node.children.length">
<e-menu-item
v-for="(el, i) in node.children"
:key="i"
:node="el"
@index="onClick"
@close="onClose"
/>
</ul>
</li>
</template>
<script>
export default {
name: "eMenuItem",
props: {
node: {
type: Object,
required: true
}
},
data() {
return {
show: false
};
},
methods: {
onMouseEnter() {
this.show = true;
},
onMouseLeave() {
this.show = false;
},
onClick() {
this.$emit("index");
},
onClose() {
this.show = false;
this.$emit("close");
},
goLinkPage(node) {
if (node.href) {
this.$router.push({ path: node.href });
this.onClick();
this.onClose();
}
}
}
};
</script>
<style lang="scss" scoped>
.menu-item {
padding: 0px 20px;
line-height: 42px;
position: relative;
text-align: left;
min-width: 100px;
font-size: 16px;
color: #333333;
background-color: #fff;
border: 1px solid #d4d4d4;
border-top: 0;
&:hover {
color: slateblue;
}
ul {
padding: 0;
list-style: none;
position: absolute;
left: 100%;
margin-top: -43px;
background-color: #fff;
border: 1px solid #ebeef5;
border-radius: 2px;
}
}
</style>

View File

@ -1,137 +0,0 @@
<template>
<div class="list">
<div
class="menu"
v-for="(node, i) in options"
:key="i"
@mouseenter="onMouseEnter(i + 1)"
@mouseleave="onMouseLeave(0)"
>
<a
v-if="node.href"
@click="goLinkPage(node, i)"
:style="{
background: index == i ? '#f1f4f6' : '#fff'
}"
>{{ node.name }}
</a>
<a
v-else
:style="{
background: index == i ? '#f1f4f6' : '#fff'
}"
>{{ node.name }}</a
>
<div
class="context"
v-if="node.children"
:class="active == i + 1 ? 'open' : 'close'"
>
<ul v-for="(el, j) in node.children" :key="j">
<e-menu-item :node="el" @close="active = -1" @index="onClick(i)" />
</ul>
</div>
</div>
</div>
</template>
<script>
import eMenuItem from "./eMenuItem";
export default {
components: {
eMenuItem
},
props: {
options: {
type: Array,
required: true
}
},
data() {
return {
index: -1,
active: -1
};
},
methods: {
onClick(index) {
this.index = index;
},
onMouseEnter(active) {
setTimeout(() => {
this.active = active;
}, 100);
},
onMouseLeave(active) {
this.active = active;
},
goLinkPage(node, index) {
this.onClick(index);
this.$router.push({ path: node.href });
}
}
};
</script>
<style lang="scss" scoped>
.list {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: auto;
.menu {
position: relative;
display: inline-block;
float: none;
margin: 0;
color: #333;
text-align: center;
cursor: pointer;
a {
padding: 0 30px;
text-decoration: none;
color: #333333;
display: block;
line-height: 78px;
height: 78px;
}
&:hover {
background: #ebeef5;
}
.context {
display: block;
position: fixed;
z-index: 99;
border-top: 1px solid #ebeef5;
ul {
position: relative;
padding: 0;
margin: 0;
border-radius: 2px;
list-style: none;
background-color: #fff;
box-sizing: content-box;
}
}
}
}
.open {
opacity: 1;
transition: opacity 0.5s;
visibility: "";
}
.close {
opacity: 0;
transition: opacity 0.5s;
visibility: hidden;
}
</style>

View File

@ -1,161 +0,0 @@
<template>
<header class="header">
<div class="navbar sticky">
<div class="container">
<div class="left">
<e-logo />
</div>
<transition name="el-zoom-in-center">
<e-menu-list class="center" :options="menus" v-if="show" />
</transition>
<div class="right" />
</div>
</div>
</header>
</template>
<script>
import eLogo from "@/components/eLogo/index.vue";
import eMenuList from "./eMenuList.vue";
export default {
components: {
eLogo,
eMenuList
},
data() {
return {
scrollT: 0,
show: true
};
},
computed: {
menus() {
return [
{
name: "首页",
href: "/home"
},
{
name: "我们的产品",
href: "/exhibition"
},
{
name: "经典案例",
children: [
{
name: "西安铁路职业技术学院",
href: "/preview/pdf?src=西安铁路职业技术学院.pdf"
},
{
name: "贵州装备制造职业学院",
href:
"/preview/pdf?src=贵州装备制造职业学院机电技术专业实训室建设.pdf"
}
]
},
{
name: "关于玖琏",
href: "/about"
},
{
name: "联系方式",
href: "/relation"
}
];
},
buyList() {
return [
{
icon: "el-icon-wallet",
name: "商城",
click: this.goLinkPage()
}
];
}
},
mounted() {
window.addEventListener("scroll", this.onScroll);
},
destroyed() {
window.removeEventListener("scroll", this.onScroll);
},
methods: {
onScroll(e) {
let headerEl = document.querySelector(".header");
let stickyEl = document.querySelector(".sticky");
let stickyT = stickyEl.offsetTop;
let scrollT = e.target.scrollingElement.scrollTop;
let diff = scrollT - this.scrollT;
if (scrollT < 160) {
if (scrollT > stickyT) {
headerEl.classList.add("fixed-top");
} else {
headerEl.classList.remove("fixed-top");
}
} else {
if (diff > 0) {
headerEl.style.top = "-78px";
} else {
headerEl.style.top = "0";
}
}
this.scrollT = scrollT;
},
goLinkPage() {}
}
};
</script>
<style lang="scss" scoped>
.navbar {
position: relative;
margin-bottom: 0;
border-radius: 0;
border: 1px solid #e6e6e6;
.container {
position: relative;
width: 93.705%;
max-width: 1799.136px;
margin: auto;
padding-left: 15px;
padding-right: 15px;
min-height: 78px;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.left {
border: none;
float: left;
font-size: 0.9375em;
display: flex;
align-items: center;
width: 300px;
height: 100%;
}
.center {
}
}
}
.fixed-top {
position: fixed;
top: 0;
transition: top 0.5s;
width: 100%;
z-index: 99;
background: #fff;
}
.card-open {
transition: opacity 0.65s;
opacity: 1;
}
</style>

View File

@ -1,44 +0,0 @@
<template>
<div class="layout">
<e-header />
<el-scrollbar wrap-class="scrollbar-wrapper">
<transition name="fade" mode="out-in">
<router-view />
</transition>
</el-scrollbar>
<e-footer />
<el-backtop>
<div
style="{
height: 100%;
width: 100%;
z-index: 1000;
background-color: #f2f5f6;
box-shadow: 0 0 6px rgba(0,0,0, .12);
text-align: center;
line-height: 40px;
color: #1989fa;
}"
>
UP
</div>
</el-backtop>
</div>
</template>
<script>
import eHeader from "./eHeader/index";
import eFooter from "./eFooter/index";
export default {
components: {
eHeader,
eFooter
}
};
</script>
<style lang="scss" scoped>
.scrollbar-wrapper {
overflow: scroll;
height: 100%;
}
</style>

View File

@ -3,11 +3,11 @@
<div
v-for="(el, i) in list"
:key="i"
class="card"
class="item"
:style="{ color: index == i ? '#ff6428' : '#666' }"
@click="onPlayVideo(el, i)"
>
<h4>{{ i + 1 }}.&ensp;{{ el.name }}</h4>
<h6>{{ i + 1 }}.&ensp;{{ el.name }}</h6>
</div>
</div>
</template>
@ -33,20 +33,41 @@ export default {
</script>
<style lang="scss">
.list {
position: absolute;
text-align: left;
height: 100%;
width: 100%;
.card {
height: calc(100vh - 60px);
position: relative;
overflow-y: auto;
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-track {
background: rgb(239, 239, 239);
border-radius: 2px;
}
&::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #666;
}
&::-webkit-scrollbar-corner {
background: #fff;
}
.item {
display: flex;
align-items: center;
width: 100%;
h4 {
h6 {
margin: 5px 10px;
cursor: pointer;
&:hover {
color: #fff;
color:blue;
}
}
}

View File

@ -1,22 +1,22 @@
<template>
<div class="pre-image">
<div class="container">
<div class="layer">
<div class="main">
<el-carousel trigger="click" height="calc(100%)">
<el-carousel-item
v-for="(img, i) in model.sources"
:key="i"
style="width:100%;height:100%"
>
<el-image :src="buildUrl(img)" />
</el-carousel-item>
</el-carousel>
</div>
<div class="side">
<e-list :list="imageList" @play="onPreview" :index="index" />
</div>
</div>
<b-carousel
v-model="slide"
:interval="4000"
controls
indicators
background="#ababab"
style="text-shadow: 1px 1px 2px #333;"
@sliding-start="onSlideStart"
@sliding-end="onSlideEnd"
>
<b-carousel-slide v-for="(img, i) in model.sources" :key="i" :img-src="buildUrl(img)"></b-carousel-slide>
</b-carousel>
<b-button class="btn" v-b-toggle.sidebar-right>菜单</b-button>
<b-sidebar id="sidebar-right" shown title="" right shadow>
<e-list :list="imageList" @play="onPreview" :index="index" />
</b-sidebar>
</div>
</div>
</template>
@ -33,7 +33,9 @@ export default {
data() {
return {
model: {},
index: 0
index: 0,
slide: 0,
sliding: null
};
},
computed: {
@ -55,65 +57,28 @@ export default {
onPreview(el, i) {
this.model = el;
this.index = i;
},
onSlideStart(slide) {
this.sliding = true
},
onSlideEnd(slide) {
this.sliding = false
}
}
};
</script>
<style lang="scss">
.pre-image {
position: relative;
height: 100vh;
width: 100%;
.container {
position: absolute;
top: 0;
background: #fff;
width: 100%;
height: calc(100% - 80px);
.layer {
min-width: 1400px;
width: 70%;
height: 100%;
margin: auto;
.btn {
display: flex;
justify-content: center;
margin: auto;
.main {
flex: 1;
height: 100%;
.el-carousel {
height: 100%;
.el-image {
width: 100%;
height: 100%;
}
}
}
.side {
width: 320px;
position: relative;
overflow-y: auto;
background: #111;
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-track {
background: rgb(239, 239, 239);
border-radius: 2px;
}
&::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #666;
}
&::-webkit-scrollbar-corner {
background: #fff;
}
}
}
img {
max-height: calc(100vh - 105px);
}
}
}

View File

@ -6,7 +6,7 @@
<p><span v-html="`&ensp;&ensp;`" />henry@joylink.club</p>
<p><span v-html="`&ensp;&ensp;`" /></p>
<div class="picture">
<el-image :src="wxcode" />
<b-img class="image" :src="wxcode" />
</div>
</address>
</div>
@ -27,19 +27,21 @@ export default {
<style lang="scss" scoped>
.page {
background: #f7f7f9;
height: calc(100vh - 66px);
.container {
width: 50%;
margin: auto;
padding: 30px 50px;
padding: 4.8em;
background: #fff;
text-align: left;
.picture {
width: 100%;
text-align: center;
.el-image {
width: 400px;
border: 1px solid #eee;
.image {
width:100%;
max-width: 40em;
height:auto;
border: 0.1em solid #eee;
}
}
}

View File

@ -16,10 +16,11 @@ module.exports = {
productionSourceMap: false,
devServer: {
port: port,
hotOnly: true,
open: false,
overlay: {
warnings: false,
errors: true
warnings: false,
errors: true
}
},
configureWebpack: {