first
This commit is contained in:
188
examples/pages/template/changelog.tpl
Normal file
188
examples/pages/template/changelog.tpl
Normal file
@@ -0,0 +1,188 @@
|
||||
<style>
|
||||
.page-changelog {
|
||||
padding-bottom: 100px;
|
||||
|
||||
.fr {
|
||||
float: right;
|
||||
padding: 0;
|
||||
|
||||
&.el-button {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&:hover a {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-size: 24px;
|
||||
margin-bottom: 60px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
padding: 0;
|
||||
padding-bottom: 10px;
|
||||
position: relative;
|
||||
color: #5e6d82;
|
||||
|
||||
> li {
|
||||
position: relative;
|
||||
padding-bottom: 15px;
|
||||
list-style: none;
|
||||
line-height: 1.8;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 30px 30px 15px;
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
padding-top: 5px;
|
||||
padding-left: 27px;
|
||||
|
||||
li {
|
||||
padding-left: 0;
|
||||
color: #555;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
li::before {
|
||||
content: '';
|
||||
circle: 4px #fff;
|
||||
border: solid 1px #333;
|
||||
margin-right: -12px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li li {
|
||||
font-size: 16px;
|
||||
list-style: none;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 5px;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
circle: 6px #333;
|
||||
transform: translateX(-20px);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin:0;
|
||||
padding: 15px 30px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
|
||||
a {
|
||||
opacity: 1;
|
||||
font-size: 20px;
|
||||
float: none;
|
||||
margin-left: 0;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
margin-bottom: -10px;
|
||||
font-size: 18px;
|
||||
padding-left: 54px;
|
||||
padding-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
em {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
font-style: normal;
|
||||
top: 23px;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-changelog">
|
||||
<div class="heading">
|
||||
<el-button class="fr">
|
||||
<a href="https://github.com/ElemeFE/element/releases" target="_blank">GitHub Releases</a>
|
||||
</el-button>
|
||||
<%= 1 >
|
||||
</div>
|
||||
<ul class="timeline" ref="timeline">
|
||||
</ul>
|
||||
<change-log ref="changeLog"></change-log>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ChangeLog from '../../../CHANGELOG.<%= 2 >.md';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ChangeLog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
count: 3
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const changeLog = this.$refs.changeLog;
|
||||
const changeLogNodes = changeLog.$el.children;
|
||||
let a = changeLogNodes[1].querySelector('a');
|
||||
a && a.remove();
|
||||
let release = changeLogNodes[1].textContent.trim();
|
||||
let fragments = `<li><h3><a href="https://github.com/ElemeFE/element/releases/tag/v${release}" target="_blank">${release}</a></h3>`;
|
||||
|
||||
for (let len = changeLogNodes.length, i = 2; i < len; i++) {
|
||||
let node = changeLogNodes[i];
|
||||
a = changeLogNodes[i].querySelector('a');
|
||||
a && a.getAttribute('class') === 'header-anchor' && a.remove();
|
||||
if (node.tagName !== 'H3') {
|
||||
fragments += changeLogNodes[i].outerHTML;
|
||||
} else {
|
||||
release = changeLogNodes[i].textContent.trim();
|
||||
fragments += `</li><li><h3><a href="https://github.com/ElemeFE/element/releases/tag/v${release}" target="_blank">${release}</a></h3>`;
|
||||
}
|
||||
}
|
||||
fragments = fragments.replace(/#(\d+)/g, '<a href="https://github.com/ElemeFE/element/issues/$1" target="_blank">#$1</a>');
|
||||
fragments = fragments.replace(/@([\w-]+)/g, '<a href="https://github.com/$1" target="_blank">@$1</a>');
|
||||
this.$refs.timeline.innerHTML = `${fragments}</li>`;
|
||||
|
||||
changeLog.$el.remove();
|
||||
}
|
||||
};
|
||||
</script>
|
255
examples/pages/template/component.tpl
Normal file
255
examples/pages/template/component.tpl
Normal file
@@ -0,0 +1,255 @@
|
||||
<style>
|
||||
.page-component__scroll {
|
||||
height: calc(100% - 80px);
|
||||
margin-top: 80px;
|
||||
|
||||
> .el-scrollbar__wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.page-component {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
|
||||
&.page-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page-component__nav {
|
||||
width: 240px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin-top: 80px;
|
||||
transition: padding-top .3s;
|
||||
|
||||
> .el-scrollbar__wrap {
|
||||
height: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
&.is-extended {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.side-nav {
|
||||
height: 100%;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
padding-right: 0;
|
||||
|
||||
& > ul {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-component__content {
|
||||
padding-left: 270px;
|
||||
padding-bottom: 100px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 50px;
|
||||
|
||||
> {
|
||||
h3 {
|
||||
margin: 55px 0 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
margin-bottom: 45px;
|
||||
line-height: 1.5em;
|
||||
|
||||
strong {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
color: #909399;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
td {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
th:first-child, td:first-child {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
ul:not(.timeline) {
|
||||
margin: 10px 0;
|
||||
padding: 0 0 0 20px;
|
||||
font-size: 14px;
|
||||
color: #5e6d82;
|
||||
line-height: 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-component {
|
||||
.page-component__nav {
|
||||
width: 100%;
|
||||
position: static;
|
||||
margin-top: 0;
|
||||
}
|
||||
.side-nav {
|
||||
padding-top: 0;
|
||||
padding-left: 50px;
|
||||
}
|
||||
.page-component__content {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.content {
|
||||
padding-top: 0;
|
||||
}
|
||||
.content > table {
|
||||
overflow: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-scrollbar class="page-component__scroll" ref="componentScrollBar">
|
||||
<div class="page-container page-component">
|
||||
<el-scrollbar class="page-component__nav">
|
||||
<side-nav :data="navsData[lang]" :base="`/${ lang }/component`"></side-nav>
|
||||
</el-scrollbar>
|
||||
<div class="page-component__content">
|
||||
<router-view class="content"></router-view>
|
||||
<footer-nav></footer-nav>
|
||||
</div>
|
||||
<el-backtop
|
||||
v-if="showBackToTop"
|
||||
target=".page-component__scroll .el-scrollbar__wrap"
|
||||
:right="100"
|
||||
:bottom="150"
|
||||
></el-backtop>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<script>
|
||||
import bus from '../../bus';
|
||||
import navsData from '../../nav.config.json';
|
||||
import throttle from 'throttle-debounce/throttle';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lang: this.$route.meta.lang,
|
||||
navsData,
|
||||
scrollTop: 0,
|
||||
showHeader: true,
|
||||
componentScrollBar: null,
|
||||
componentScrollBoxElement: null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$route.path'() {
|
||||
// 触发伪滚动条更新
|
||||
this.componentScrollBox.scrollTop = 0;
|
||||
this.$nextTick(() => {
|
||||
this.componentScrollBar.update();
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
renderAnchorHref() {
|
||||
if (/changelog/g.test(location.href)) return;
|
||||
const anchors = document.querySelectorAll('h2 a,h3 a,h4 a,h5 a');
|
||||
const basePath = location.href.split('#').splice(0, 2).join('#');
|
||||
|
||||
[].slice.call(anchors).forEach(a => {
|
||||
const href = a.getAttribute('href');
|
||||
a.href = basePath + href;
|
||||
});
|
||||
},
|
||||
|
||||
goAnchor() {
|
||||
if (location.href.match(/#/g).length > 1) {
|
||||
const anchor = location.href.match(/#[^#]+$/g);
|
||||
if (!anchor) return;
|
||||
const elm = document.querySelector(anchor[0]);
|
||||
if (!elm) return;
|
||||
|
||||
setTimeout(_ => {
|
||||
this.componentScrollBox.scrollTop = elm.offsetTop;
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
|
||||
handleScroll() {
|
||||
const scrollTop = this.componentScrollBox.scrollTop;
|
||||
if (this.showHeader !== this.scrollTop > scrollTop) {
|
||||
this.showHeader = this.scrollTop > scrollTop;
|
||||
}
|
||||
if (scrollTop === 0) {
|
||||
this.showHeader = true;
|
||||
}
|
||||
if (!this.navFaded) {
|
||||
bus.$emit('fadeNav');
|
||||
}
|
||||
this.scrollTop = scrollTop;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showBackToTop() {
|
||||
return !this.$route.path.match(/backtop/);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
bus.$on('navFade', val => {
|
||||
this.navFaded = val;
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.componentScrollBar = this.$refs.componentScrollBar;
|
||||
this.componentScrollBox = this.componentScrollBar.$el.querySelector('.el-scrollbar__wrap');
|
||||
this.throttledScrollHandler = throttle(300, this.handleScroll);
|
||||
this.componentScrollBox.addEventListener('scroll', this.throttledScrollHandler);
|
||||
this.renderAnchorHref();
|
||||
this.goAnchor();
|
||||
document.body.classList.add('is-component');
|
||||
},
|
||||
destroyed() {
|
||||
document.body.classList.remove('is-component');
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.componentScrollBox.removeEventListener('scroll', this.throttledScrollHandler);
|
||||
},
|
||||
beforeRouteUpdate(to, from, next) {
|
||||
next();
|
||||
setTimeout(() => {
|
||||
const toPath = to.path;
|
||||
const fromPath = from.path;
|
||||
if (toPath === fromPath && to.hash) {
|
||||
this.goAnchor();
|
||||
}
|
||||
if (toPath !== fromPath) {
|
||||
document.documentElement.scrollTop = document.body.scrollTop = 0;
|
||||
this.renderAnchorHref();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
</script>
|
82
examples/pages/template/design.tpl
Normal file
82
examples/pages/template/design.tpl
Normal file
@@ -0,0 +1,82 @@
|
||||
<style scoped>
|
||||
.cards {
|
||||
margin: 30px 0 70px;
|
||||
}
|
||||
.card {
|
||||
background: #fbfcfd;
|
||||
height: 204px;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
margin: 40px auto 25px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
h4 {
|
||||
font-size: 18px;
|
||||
color: #1f2d3d;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #99a9bf;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<h2><%= 1 ></h2>
|
||||
<el-row :gutter="14" class="cards">
|
||||
<el-col :xs="12" :sm="6">
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/consistency.png" alt="Consistency">
|
||||
<h4><%= 2 ></h4>
|
||||
<span><%= 3 ></span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="6">
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/feedback.png" alt="Feedback">
|
||||
<h4><%= 4 ></h4>
|
||||
<span><%= 5 ></span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="6">
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/efficiency.png" alt="Efficiency">
|
||||
<h4><%= 6 ></h4>
|
||||
<span><%= 7 ></span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="6">
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/controllability.png" alt="Controllability">
|
||||
<h4><%= 8 ></h4>
|
||||
<span><%= 9 ></span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<h3><%= 10 ></h3>
|
||||
<ul>
|
||||
<li><strong><%= 11 ></strong><%= 12 ></li>
|
||||
<li><strong><%= 13 ></strong><%= 14 ></li>
|
||||
</ul>
|
||||
<h3><%= 15 ></h3>
|
||||
<ul>
|
||||
<li><strong><%= 16 ></strong><%= 17 ></li>
|
||||
<li><strong><%= 18 ></strong><%= 19 ></li>
|
||||
</ul>
|
||||
<h3><%= 20 ></h3>
|
||||
<ul>
|
||||
<li><strong><%= 21 ></strong><%= 22 ></li>
|
||||
<li><strong><%= 23 ></strong><%= 24 ></li>
|
||||
<li><strong><%= 25 ></strong><%= 26 ></li>
|
||||
</ul>
|
||||
<h3><%= 27 ></h3>
|
||||
<ul>
|
||||
<li><strong><%= 28 ></strong><%= 29 ></li>
|
||||
<li><strong><%= 30 ></strong><%= 31 ></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
91
examples/pages/template/guide.tpl
Normal file
91
examples/pages/template/guide.tpl
Normal file
@@ -0,0 +1,91 @@
|
||||
<style>
|
||||
.page-guide {
|
||||
padding: 55px 30px 95px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.content {
|
||||
padding-left: 25px;
|
||||
margin-left: -1px;
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 22px;
|
||||
font-weight: normal;
|
||||
margin: 0 0 30px;
|
||||
color: #1f2d3d;
|
||||
}
|
||||
p {
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
color: #5e6d82;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 50px;
|
||||
padding-left: 0;
|
||||
}
|
||||
li {
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
color: #99a9bf;
|
||||
list-style: none;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
background-color: #5e6d82;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: #5e6d82;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-guide {
|
||||
.content {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-container page-guide">
|
||||
<el-row>
|
||||
<el-col :xs="24" :sm="5">
|
||||
<side-nav :data="navsData" :base="`/${ lang }/guide`"></side-nav>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="19">
|
||||
<router-view class="content"></router-view>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lang: this.$route.meta.lang,
|
||||
navsData: [
|
||||
{
|
||||
path: '/design',
|
||||
name: '<%= 1 >'
|
||||
},
|
||||
{
|
||||
path: '/nav',
|
||||
name: '<%= 2 >'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
388
examples/pages/template/index.tpl
Normal file
388
examples/pages/template/index.tpl
Normal file
@@ -0,0 +1,388 @@
|
||||
<style scoped>
|
||||
.banner {
|
||||
text-align: center;
|
||||
}
|
||||
.banner-desc {
|
||||
padding-top: 50px;
|
||||
|
||||
h1 {
|
||||
font-size: <%= titleSize >px;
|
||||
margin: 0;
|
||||
line-height: 48px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: <%= paraSize >px;
|
||||
line-height: 28px;
|
||||
color: #888;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
}
|
||||
.sponsors {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.sponsor {
|
||||
margin: 0 20px 50px;
|
||||
display: inline-flex;
|
||||
width: 300px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
line-height: 1.8;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.jumbotron {
|
||||
width: 890px;
|
||||
margin: 30px auto;
|
||||
position: relative;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
.jumbotron-red {
|
||||
transition: height .1s;
|
||||
background: #FFF;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top:0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.cards {
|
||||
margin: 0 auto 110px;
|
||||
width: 1140px;
|
||||
|
||||
.container {
|
||||
padding: 0;
|
||||
margin: 0 -11px;
|
||||
width: auto;
|
||||
&::before, &::after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
&::after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
li {
|
||||
width: 25%;
|
||||
padding: 0 19px;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 160px;
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
.card {
|
||||
height: 430px;
|
||||
width: 100%;
|
||||
background:#ffffff;
|
||||
border:1px solid #eaeefb;
|
||||
border-radius:5px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
transition: all .3s ease-in-out;
|
||||
bottom: 0;
|
||||
|
||||
img {
|
||||
margin: 66px auto 60px;
|
||||
}
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
color: #1f2f3d;
|
||||
font-weight: normal;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #99a9bf;
|
||||
padding: 0 25px;
|
||||
line-height: 20px;
|
||||
}
|
||||
a {
|
||||
height: 53px;
|
||||
line-height: 52px;
|
||||
font-size: 14px;
|
||||
color: #409EFF;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
border-top: 1px solid #eaeefb;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 5px 5px;
|
||||
transition: all .3s;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background: #409EFF;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
bottom: 6px;
|
||||
box-shadow: 0 6px 18px 0 rgba(232,237,250,0.50);
|
||||
}
|
||||
}
|
||||
@media (max-width: 1140px) {
|
||||
.cards {
|
||||
width: 100%;
|
||||
.container {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.banner .container {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.banner img {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.banner .container {
|
||||
img {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.jumbotron {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cards {
|
||||
li {
|
||||
width: 80%;
|
||||
margin: 0 auto 20px;
|
||||
float: none;
|
||||
}
|
||||
.card {
|
||||
height: auto;
|
||||
padding-bottom: 54px;
|
||||
}
|
||||
}
|
||||
.banner-stars {
|
||||
display: none;
|
||||
}
|
||||
.banner-desc {
|
||||
#line2 {
|
||||
display: none;
|
||||
}
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
}
|
||||
p {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
.theme-intro-b {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 200;
|
||||
.intro-banner {
|
||||
position: absolute
|
||||
}
|
||||
img {
|
||||
width: 300px;
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.theme-intro-a {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 200;
|
||||
.mask{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: #000;
|
||||
opacity: .5;
|
||||
}
|
||||
.intro-banner {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: fixed;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
z-index: 100;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
.intro-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 48px;
|
||||
font-weight: bold;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<div class="banner">
|
||||
<div class="banner-desc">
|
||||
<h1><%= 1 ></h1>
|
||||
<p><%= 2 ></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jumbotron" ref="indexMainImg">
|
||||
<img src="~examples/assets/images/theme-index-blue.png" alt="">
|
||||
<div class="jumbotron-red" :style="{
|
||||
height: mainImgOffset + 'px'
|
||||
}">
|
||||
<img src="~examples/assets/images/theme-index-red.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="cards">
|
||||
<ul class="container">
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/guide.png" alt="">
|
||||
<h3><%= 3 ></h3>
|
||||
<p><%= 4 ></p>
|
||||
<router-link
|
||||
active-class="active"
|
||||
to="/<%= lang >/guide/design"
|
||||
exact><%= 5 >
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/component.png" alt="">
|
||||
<h3><%= 6 ></h3>
|
||||
<p><%= 7 ></p>
|
||||
<router-link
|
||||
active-class="active"
|
||||
to="/<%= lang >/component/layout"
|
||||
exact><%= 5 >
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/theme-index-icon.svg" alt="">
|
||||
<h3><%= 10 ></h3>
|
||||
<p><%= 11 ></p>
|
||||
<router-link
|
||||
active-class="active"
|
||||
to="/<%= lang >/theme"
|
||||
exact><%= 5 >
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/resource.png" alt="">
|
||||
<h3><%= 8 ></h3>
|
||||
<p><%= 9 ></p>
|
||||
<router-link
|
||||
active-class="active"
|
||||
to="/<%= lang >/resource"
|
||||
exact><%= 5 >
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import throttle from 'throttle-debounce/throttle';
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.throttledHandleScroll = throttle(10, true, index => {
|
||||
this.handleScroll(index);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleScroll(index) {
|
||||
const ele = this.$refs.indexMainImg;
|
||||
const rect = ele.getBoundingClientRect();
|
||||
const eleHeight = ele.clientHeight + 55;
|
||||
let calHeight = (180 - rect.top) * 2;
|
||||
if (calHeight < 0) calHeight = 0;
|
||||
if (calHeight > eleHeight) calHeight = eleHeight;
|
||||
this.mainImgOffset = calHeight;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lang: this.$route.meta.lang,
|
||||
mainImgOffset: 0
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.throttledHandleScroll);
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.throttledHandleScroll);
|
||||
}
|
||||
};
|
||||
</script>
|
166
examples/pages/template/nav.tpl
Normal file
166
examples/pages/template/nav.tpl
Normal file
@@ -0,0 +1,166 @@
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.block {
|
||||
margin-bottom: 55px;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
.nav-demos {
|
||||
p {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
h5 {
|
||||
margin: 0;
|
||||
}
|
||||
img {
|
||||
padding: 15px;
|
||||
background-color: #F9FAFC;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.dialog-img {
|
||||
position: fixed;
|
||||
overflow: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
|
||||
.imgWrap {
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
top: 100px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: #373737;
|
||||
background-color: rgba(55, 55, 55, 0.6);
|
||||
height: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
.zoom-enter-active,
|
||||
.zoom-leave-active {
|
||||
transition: transform .3s cubic-bezier(0.78, 0.14, 0.15, 0.86), opacity .3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
}
|
||||
.zoom-enter,
|
||||
.zoom-leave-active {
|
||||
transform: scale(0.3);
|
||||
opacity: 0;
|
||||
}
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity .3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
}
|
||||
.fade-enter,
|
||||
.fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<h2><%= 1 ></h2>
|
||||
<div class="block">
|
||||
<p><%= 2 ></p>
|
||||
</div>
|
||||
<div class="block">
|
||||
<h3><%= 3 ></h3>
|
||||
<p><%= 4 ></p>
|
||||
</div>
|
||||
<div class="block">
|
||||
<h3><%= 5 ></h3>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="9">
|
||||
<p><%= 6 ></p>
|
||||
</el-col>
|
||||
<el-col :span="15" class="nav-demos">
|
||||
<img src="~examples/assets/images/navbar_1.png" alt="<%= 7 >" @click="enlarge(846, $event)">
|
||||
<h5><%= 7 ></h5>
|
||||
<p><%= 8 ></p>
|
||||
<img src="~examples/assets/images/navbar_2.png" alt="<%= 9 >" @click="enlarge(846, $event)">
|
||||
<h5><%= 9 ></h5>
|
||||
<p><%= 10 ></p>
|
||||
<img src="~examples/assets/images/navbar_3.png" alt="<%= 11 >" @click="enlarge(846, $event)">
|
||||
<h5><%= 11 ></h5>
|
||||
<p><%= 12 ></p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="block">
|
||||
<h3><%= 13 ></h3>
|
||||
<el-row>
|
||||
<el-col :span="10">
|
||||
<p><%= 14 ></p>
|
||||
</el-col>
|
||||
<el-col :span="14" class="nav-demos">
|
||||
<img src="~examples/assets/images/navbar_0.png" alt="" @click="enlarge(846, $event)">
|
||||
<p><%= 15 ></p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div class="mask" v-show="showDialog" @click="showDialog = false"></div>
|
||||
</transition>
|
||||
<transition name="zoom">
|
||||
<div class="dialog-img" :style='imgWrapStyle' v-show="showDialog" @click="showDialog = false">
|
||||
<div class="imgWrap" :style="imgStyle">
|
||||
<img :src="imgUrl" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
imgUrl: '',
|
||||
imgBound: {},
|
||||
showDialog: false,
|
||||
imgStyle: {},
|
||||
imgWrapStyle: {}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
showDialog(val) {
|
||||
document.body.style.overflow = val ? 'hidden' : '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enlarge(imgWidth, ev) {
|
||||
var imgNode = ev.target;
|
||||
// var bound = imgNode.getBoundingClientRect();
|
||||
var offset = {};
|
||||
var doc = document;
|
||||
|
||||
offset.left = (doc.body.scrollWidth - imgWidth) / 2;
|
||||
offset.top = 100;
|
||||
|
||||
this.imgUrl = imgNode.src;
|
||||
this.imgBound = imgNode.getBoundingClientRect();
|
||||
|
||||
this.imgWrapStyle.transformOrigin = `${ev.clientX}px ${ev.clientY}px`;
|
||||
// this.imgStyle.transformOrigin = `${ev.clientX}px ${ev.clientY}px`;
|
||||
this.imgStyle.width = imgWidth + 'px';
|
||||
this.showDialog = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
173
examples/pages/template/resource.tpl
Normal file
173
examples/pages/template/resource.tpl
Normal file
@@ -0,0 +1,173 @@
|
||||
<style scoped>
|
||||
.page-resource {
|
||||
padding-top: 55px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.resource-placeholder {
|
||||
margin: 50px auto 100px;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 20px 0 16px;
|
||||
font-size: 16px;
|
||||
color: #1f2f3d;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #99a9bf;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cards {
|
||||
margin: 35px auto 110px;
|
||||
|
||||
.container {
|
||||
&::before, &::after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
&::after {
|
||||
clear: both;
|
||||
}
|
||||
padding: 0;
|
||||
margin: 0 -11px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
li {
|
||||
width: 33.33333%;
|
||||
padding: 0 11px;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
margin: 0;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #5e6d82;
|
||||
}
|
||||
.card {
|
||||
height: 394px;
|
||||
width: 100%;
|
||||
background:#ffffff;
|
||||
border:1px solid #eaeefb;
|
||||
border-radius:5px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
transition: bottom .3s;
|
||||
bottom: 0;
|
||||
|
||||
img {
|
||||
margin: 75px auto 35px;
|
||||
height: 87px;
|
||||
}
|
||||
h3 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 18px;
|
||||
color: #1f2f3d;
|
||||
font-weight: normal;
|
||||
height: 22px;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #99a9bf;
|
||||
padding: 0 30px;
|
||||
margin: 0;
|
||||
word-break: break-all;
|
||||
line-height: <%= paraHeight >;
|
||||
}
|
||||
a {
|
||||
height: 42px;
|
||||
width: 190px;
|
||||
display: inline-block;
|
||||
line-height: 42px;
|
||||
font-size: 14px;
|
||||
background-color: #409EFF;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
transition: all .3s;
|
||||
text-decoration: none;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 850px) {
|
||||
.cards {
|
||||
li {
|
||||
max-width: 500px;
|
||||
float: none;
|
||||
margin: 10px auto 30px;
|
||||
width: 80%;
|
||||
.card {
|
||||
height: auto;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-container page-resource">
|
||||
<h2><%= 1 ></h2>
|
||||
<!--<div class="resource-placeholder">-->
|
||||
<!--<img src="~examples/assets/images/resource-placeholder.svg" alt="">-->
|
||||
<!--<h4><%= placeholder1 ></h4>-->
|
||||
<!--<p><%= placeholder2 ></p>-->
|
||||
<!--</div>-->
|
||||
|
||||
<p><%= placeholder2 ></p>
|
||||
<div class="cards">
|
||||
<ul class="container">
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/Axure-Components.svg" alt="">
|
||||
<h3><%= 3 ></h3>
|
||||
<p><%= 4 ></p>
|
||||
<a
|
||||
onclick="ga('send', 'event', 'ResourceDownload', 'Download', 'Axure');"
|
||||
href="https://github.com/ElementUI/Resources/raw/master/Element_Components_v2.1.0.rplib"
|
||||
><%= 5 ></a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="card">
|
||||
<img src="~examples/assets/images/Sketch-Template.svg" alt="">
|
||||
<h3><%= 6 ></h3>
|
||||
<p><%= 7 ></p>
|
||||
<a
|
||||
onclick="ga('send', 'event', 'ResourceDownload', 'Download', 'Sketch');"
|
||||
href="https://github.com/ElementUI/Resources/raw/master/Element%20UI%20Kit_v2.0.sketch"
|
||||
><%= 5 ></a>
|
||||
</div>
|
||||
</li>
|
||||
<!--<li>-->
|
||||
<!--<div class="card">-->
|
||||
<!--<img src="~examples/assets/images/Module.svg" alt="">-->
|
||||
<!--<h3><%= 8 ></h3>-->
|
||||
<!--<p><%= 9 ></p>-->
|
||||
<!--<a href="https://github.com/ElementUI/Resources/raw/master/Element%20Components%20Documentation.zip"><%= 5 ></a>-->
|
||||
<!--</div>-->
|
||||
<!--</li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
3
examples/pages/template/theme-nav.tpl
Normal file
3
examples/pages/template/theme-nav.tpl
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
196
examples/pages/template/theme-preview.tpl
Normal file
196
examples/pages/template/theme-preview.tpl
Normal file
@@ -0,0 +1,196 @@
|
||||
<style lang="scss">
|
||||
.page-container.page-theme-preview {
|
||||
padding-top: 30px;
|
||||
.display {
|
||||
width: 75%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
h3 {
|
||||
font-size: 28px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
}
|
||||
.side {
|
||||
display: inline-block;
|
||||
width: 25%;
|
||||
.editor {
|
||||
overflow: hidden;
|
||||
background: #f5f7fa;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
&.fixed {
|
||||
position: fixed;
|
||||
width: 285px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-container page-theme-preview" ref="themePreview">
|
||||
<section class="display">
|
||||
<el-button type="text" icon="el-icon-back" @click="navBack">
|
||||
<%= 1 >
|
||||
</el-button>
|
||||
<h3>{{previewConfig.name}}</h3>
|
||||
<basic-tokens-preview>
|
||||
</basic-tokens-preview>
|
||||
<components-preview>
|
||||
</components-preview>
|
||||
</section>
|
||||
<aside class="side">
|
||||
<section class="editor" :style="{top: `${editorTop}px`, height: `${editorHeight}px`}" :class="{'fixed': isFixed}">
|
||||
<theme-configurator
|
||||
:isOfficial="isOfficial"
|
||||
:themeConfig="themeConfig"
|
||||
:previewConfig="previewConfig"
|
||||
:onUserConfigUpdate="onUserConfigUpdate"
|
||||
>
|
||||
</theme-configurator>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import bus from '../../bus.js';
|
||||
import ThemeConfigurator from '../../components/theme-configurator';
|
||||
import ComponentsPreview from '../../components/theme/components-preview';
|
||||
import BasicTokensPreview from '../../components/theme/basic-tokens-preview';
|
||||
import {
|
||||
loadPreviewFromLocal,
|
||||
loadUserThemeFromLocal,
|
||||
saveUserThemeToLocal
|
||||
} from '../../components/theme/localstorage';
|
||||
import {
|
||||
getThemeConfigObject
|
||||
} from '../../components/theme/utils';
|
||||
import {
|
||||
ACTION_APPLY_THEME
|
||||
} from '../../components/theme/constant.js';
|
||||
import throttle from 'throttle-debounce/throttle';
|
||||
import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
|
||||
|
||||
const maxUserTheme = 8;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ThemeConfigurator,
|
||||
BasicTokensPreview,
|
||||
ComponentsPreview
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewConfig: {},
|
||||
themeConfig: {},
|
||||
userTheme: [],
|
||||
editorTop: 0,
|
||||
editorHeight: 1000,
|
||||
isFixed: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isOfficial() {
|
||||
return this.previewConfig.type === 'official';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.throttledHandleScroll = throttle(10, true, index => {
|
||||
this.handleScroll(index);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
navBack() {
|
||||
this.$router.go(-1);
|
||||
this.$nextTick(() => {
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
},
|
||||
getNewUserThemeName(originName) {
|
||||
let n = 1;
|
||||
let name;
|
||||
while (true) {
|
||||
name = `${originName}-${n}`;
|
||||
if (this.userTheme.filter(theme => (theme.name === name)).length === 0) {
|
||||
break;
|
||||
}
|
||||
n += 1;
|
||||
}
|
||||
return name;
|
||||
},
|
||||
onUserConfigUpdate(userConfig) {
|
||||
const themeConfig = JSON.stringify(userConfig);
|
||||
const { type, name } = this.previewConfig;
|
||||
if (this.isOfficial) {
|
||||
if (this.userTheme.length >= maxUserTheme) {
|
||||
this.$message.error(getActionDisplayName('max-user-theme'));
|
||||
return;
|
||||
}
|
||||
const autoUserName = this.getNewUserThemeName(name);
|
||||
this.previewConfig.name = autoUserName;
|
||||
this.previewConfig.type = 'user';
|
||||
this.userTheme.push({
|
||||
update: Date.now(),
|
||||
name: autoUserName,
|
||||
theme: themeConfig
|
||||
});
|
||||
saveUserThemeToLocal(this.userTheme);
|
||||
return;
|
||||
}
|
||||
if (type === 'user') {
|
||||
this.userTheme.forEach((config) => {
|
||||
if (config.name === name) {
|
||||
config.update = Date.now();
|
||||
config.theme = themeConfig;
|
||||
}
|
||||
});
|
||||
saveUserThemeToLocal(this.userTheme);
|
||||
}
|
||||
},
|
||||
handleScroll() {
|
||||
const rect = this.$refs.themePreview.getBoundingClientRect();
|
||||
let offsetTop = rect.top;
|
||||
let offsetBottom = rect.bottom;
|
||||
const calHeight = this.editorHeight + 30 + 20;
|
||||
if (offsetTop < 0) {
|
||||
this.isFixed = true;
|
||||
if (offsetBottom < calHeight) {
|
||||
this.editorTop = 30 - calHeight + offsetBottom;
|
||||
} else {
|
||||
this.editorTop = 30;
|
||||
}
|
||||
} else {
|
||||
this.isFixed = false;
|
||||
this.editorTop = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.throttledHandleScroll);
|
||||
},
|
||||
mounted() {
|
||||
this.editorHeight = window.innerHeight - 40 - 5;
|
||||
window.addEventListener('scroll', this.throttledHandleScroll);
|
||||
this.userTheme = loadUserThemeFromLocal();
|
||||
const previewConfig = loadPreviewFromLocal();
|
||||
const pageRefer = this.$route.params.refer;
|
||||
if (!previewConfig || !pageRefer) {
|
||||
this.$alert(getActionDisplayName('no-preview-config'), getActionDisplayName('notice'), {
|
||||
confirmButtonText: getActionDisplayName('confirm'),
|
||||
callback: action => {
|
||||
const newPath = this.$route.path.replace('/preview', '');
|
||||
this.$router.replace(newPath);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.previewConfig = previewConfig;
|
||||
const themeConfig = getThemeConfigObject(previewConfig.theme);
|
||||
if (themeConfig) {
|
||||
this.themeConfig = themeConfig;
|
||||
bus.$emit(ACTION_APPLY_THEME, themeConfig);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
230
examples/pages/template/theme.tpl
Normal file
230
examples/pages/template/theme.tpl
Normal file
@@ -0,0 +1,230 @@
|
||||
<style lang="scss">
|
||||
.page-theme {
|
||||
&:last-child {
|
||||
margin-bottom: 55px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin: 0;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.theme-card {
|
||||
display: inline-block;
|
||||
height: 150px;
|
||||
height: 16vw;
|
||||
max-height: 230px;
|
||||
flex: 0 0 24%;
|
||||
cursor: default;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.theme-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.second-section {
|
||||
margin-top: 60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-container page-theme">
|
||||
<section class="theme-section">
|
||||
<h2><%= 1 ></h2>
|
||||
<ul>
|
||||
<li class="theme-card" v-for="item in officialTheme" :key="item.name">
|
||||
<theme-card
|
||||
type="official"
|
||||
:config="item"
|
||||
@action="onAction"
|
||||
></theme-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="theme-section second-section">
|
||||
<h2><%= 2 > ({{userThemeCount}}/{{maxUserTheme}})</h2>
|
||||
<ul>
|
||||
<li class="theme-card" v-if="showUserUpload">
|
||||
<theme-card
|
||||
type="upload"
|
||||
:config="{name: 'upload'}"
|
||||
@action="onAction"
|
||||
></theme-card>
|
||||
</li>
|
||||
<li class="theme-card" v-for="item in displayUserTheme" :key="item.name">
|
||||
<theme-card
|
||||
type="user"
|
||||
:config="item"
|
||||
@action="onAction"
|
||||
></theme-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<el-dialog :visible.sync="copyDialogVisible">
|
||||
<el-form :model="copyForm" ref="copyForm" :rules="copyFormRule">
|
||||
<el-form-item label="<%= 3 >" prop="name">
|
||||
<el-input v-model="copyForm.name"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeCopyForm">{{getActionDisplayName('cancel')}}</el-button>
|
||||
<el-button type="primary" @click="copyToUser">{{getActionDisplayName('confirm')}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ThemeCard from '../../components/theme/theme-card.vue';
|
||||
import { themeList, eleThemeList } from '../../components/theme/theme-list.js';
|
||||
import { saveUserThemeToLocal, loadUserThemeFromLocal } from '../../components/theme/localstorage';
|
||||
import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
|
||||
|
||||
const maxUserTheme = 8;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ThemeCard
|
||||
},
|
||||
mounted() {
|
||||
this.userTheme = loadUserThemeFromLocal();
|
||||
if (!Array.isArray(this.userTheme)) {
|
||||
this.userTheme = [];
|
||||
saveUserThemeToLocal(this.userTheme);
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userTheme: [],
|
||||
maxUserTheme,
|
||||
copyDialogVisible: false,
|
||||
copyForm: {},
|
||||
copyFormRule: {
|
||||
name: [{
|
||||
validator: this.validateCopyName,
|
||||
trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
officialTheme() {
|
||||
return this.padEmpeyTheme(themeList.concat(this.$isEle ? eleThemeList : []));
|
||||
},
|
||||
userThemeCount() {
|
||||
return this.userTheme.length;
|
||||
},
|
||||
showUserUpload() {
|
||||
return this.userThemeCount < maxUserTheme;
|
||||
},
|
||||
displayUserTheme() {
|
||||
return this.padEmpeyTheme(this.userTheme, this.showUserUpload ? 1 : 0);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getActionDisplayName(key) {
|
||||
return getActionDisplayName(key);
|
||||
},
|
||||
validateCopyName(rule, value, callback) {
|
||||
if (!value) {
|
||||
callback(new Error(this.getActionDisplayName('require-them-name')));
|
||||
} else if (this.filterUserThemeByName(value).length > 0) {
|
||||
callback(new Error(this.getActionDisplayName('duplicate-them-name')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
filterUserThemeByName(name, include = true) {
|
||||
return this.userTheme.filter((theme) => (include ? theme.name === name : theme.name !== name));
|
||||
},
|
||||
padEmpeyTheme(theme, add = 0) {
|
||||
if (!theme.length) return [];
|
||||
const pad = 4 - ((theme.length + add) % 4);
|
||||
if (pad < 4) return theme.concat(Array(pad).fill({}));
|
||||
return theme;
|
||||
},
|
||||
onAction(name, item) {
|
||||
switch (name) {
|
||||
case 'copy':
|
||||
this.openCopyForm(item.theme);
|
||||
break;
|
||||
case 'upload':
|
||||
this.openCopyForm(item);
|
||||
break;
|
||||
case 'rename':
|
||||
this.openRenameForm(item.name);
|
||||
break;
|
||||
case 'delete':
|
||||
this.$confirm(this.getActionDisplayName('confirm-delete-theme'), this.getActionDisplayName('notice'), {
|
||||
confirmButtonText: this.getActionDisplayName('confirm'),
|
||||
cancelButtonText: this.getActionDisplayName('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.deleteUserThemeByName(item.name);
|
||||
}).catch(() => {});
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteUserThemeByName(name) {
|
||||
this.userTheme = this.filterUserThemeByName(name, false);
|
||||
this.saveToLocal();
|
||||
},
|
||||
openRenameForm(name) {
|
||||
this.copyForm.oldname = name;
|
||||
this.copyDialogVisible = true;
|
||||
},
|
||||
openCopyForm(theme) {
|
||||
if (this.userTheme.length >= 8) {
|
||||
this.$message.error(this.getActionDisplayName('max-user-theme'));
|
||||
return;
|
||||
}
|
||||
this.copyForm.theme = theme;
|
||||
this.copyDialogVisible = true;
|
||||
},
|
||||
closeCopyForm() {
|
||||
this.copyDialogVisible = false;
|
||||
this.$nextTick(() => {
|
||||
this.copyForm = {};
|
||||
});
|
||||
},
|
||||
copyToUser() {
|
||||
this.$refs.copyForm.validate((valid) => {
|
||||
if (valid) {
|
||||
const { theme, name, oldname } = this.copyForm;
|
||||
if (theme) {
|
||||
// copy
|
||||
this.userTheme.push({
|
||||
update: Date.now(),
|
||||
name,
|
||||
theme
|
||||
});
|
||||
} else {
|
||||
// rename
|
||||
this.userTheme.forEach((config) => {
|
||||
if (config.name === oldname) {
|
||||
config.update = Date.now();
|
||||
config.name = name;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.saveToLocal();
|
||||
this.closeCopyForm();
|
||||
}
|
||||
});
|
||||
},
|
||||
saveToLocal() {
|
||||
saveUserThemeToLocal(this.userTheme);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user