'admin-21.04.30:新增波浪效果指令及演示、窗格拆分器等'

This commit is contained in:
lyt 2021-04-30 16:15:43 +08:00
parent 6cf87bee90
commit a184ebf5d3
16 changed files with 372 additions and 12 deletions

View File

@ -102,6 +102,7 @@ cnpm run build
- <a href="https://github.com/crabbly/Print.js" target="_blank">print-js</a> - <a href="https://github.com/crabbly/Print.js" target="_blank">print-js</a>
- <a href="https://github.com/likaia/screen-shot" target="_blank">vue-web-screen-shot</a> - <a href="https://github.com/likaia/screen-shot" target="_blank">vue-web-screen-shot</a>
- <a href="https://github.com/jbaysolutions/vue-grid-layout" target="_blank">vue-grid-layout</a> - <a href="https://github.com/jbaysolutions/vue-grid-layout" target="_blank">vue-grid-layout</a>
- <a href="https://github.com/antoniandre/splitpanes" target="_blank">splitpanes</a>
#### 特别感谢 #### 特别感谢

View File

@ -21,13 +21,14 @@
"qrcodejs2-fixes": "^0.0.2", "qrcodejs2-fixes": "^0.0.2",
"screenfull": "^5.1.0", "screenfull": "^5.1.0",
"sortablejs": "^1.13.0", "sortablejs": "^1.13.0",
"splitpanes": "^3.0.4",
"vue": "^3.0.5", "vue": "^3.0.5",
"vue-grid-layout": "^3.0.0-beta1", "vue-grid-layout": "^3.0.0-beta1",
"vue-i18n": "^9.1.4", "vue-i18n": "^9.1.4",
"vue-router": "^4.0.2", "vue-router": "^4.0.2",
"vue-web-screen-shot": "^1.1.9", "vue-web-screen-shot": "^1.1.9",
"vuex": "^4.0.0-rc.2", "vuex": "^4.0.0-rc.2",
"wangeditor": "^4.6.16" "wangeditor": "^4.6.17"
}, },
"devDependencies": { "devDependencies": {
"@types/axios": "^0.14.0", "@types/axios": "^0.14.0",

View File

@ -33,6 +33,7 @@ export default {
funClipboard: 'Copy cut', funClipboard: 'Copy cut',
funScreenShort: 'screenCapture', funScreenShort: 'screenCapture',
funGridLayout: 'Drag layout', funGridLayout: 'Drag layout',
funSplitpanes: 'Pane splitter',
pagesIndex: 'pages', pagesIndex: 'pages',
pagesFiltering: 'Filtering', pagesFiltering: 'Filtering',
pagesFilteringDetails: 'FilteringDetails', pagesFilteringDetails: 'FilteringDetails',
@ -46,6 +47,7 @@ export default {
pagesWaterfall: 'Waterfall', pagesWaterfall: 'Waterfall',
pagesSteps: 'Steps', pagesSteps: 'Steps',
pagesPreview: 'Large preview', pagesPreview: 'Large preview',
pagesWaves: 'Wave effect',
chartIndex: 'chartIndex', chartIndex: 'chartIndex',
personal: 'personal', personal: 'personal',
tools: 'tools', tools: 'tools',

View File

@ -33,6 +33,7 @@ export default {
funClipboard: '复制剪切', funClipboard: '复制剪切',
funScreenShort: 'web端自定义截屏', funScreenShort: 'web端自定义截屏',
funGridLayout: '拖拽布局', funGridLayout: '拖拽布局',
funSplitpanes: '窗格拆分器',
pagesIndex: '页面', pagesIndex: '页面',
pagesFiltering: '过滤筛选组件', pagesFiltering: '过滤筛选组件',
pagesFilteringDetails: '过滤筛选组件详情', pagesFilteringDetails: '过滤筛选组件详情',
@ -46,6 +47,7 @@ export default {
pagesWaterfall: '瀑布屏', pagesWaterfall: '瀑布屏',
pagesSteps: '步骤条', pagesSteps: '步骤条',
pagesPreview: '大图预览', pagesPreview: '大图预览',
pagesWaves: '波浪效果',
chartIndex: '大数据图表', chartIndex: '大数据图表',
personal: '个人中心', personal: '个人中心',
tools: '工具类集合', tools: '工具类集合',

View File

@ -33,6 +33,7 @@ export default {
funClipboard: '複製剪切', funClipboard: '複製剪切',
funScreenShort: '自定義截圖', funScreenShort: '自定義截圖',
funGridLayout: '拖拽佈局', funGridLayout: '拖拽佈局',
funSplitpanes: '窗格折開器',
pagesIndex: '頁面', pagesIndex: '頁面',
pagesFiltering: '過濾篩選組件', pagesFiltering: '過濾篩選組件',
pagesFilteringDetails: '過濾篩選組件詳情', pagesFilteringDetails: '過濾篩選組件詳情',
@ -46,6 +47,7 @@ export default {
pagesWaterfall: '瀑布屏', pagesWaterfall: '瀑布屏',
pagesSteps: '步驟條', pagesSteps: '步驟條',
pagesPreview: '大圖預覽', pagesPreview: '大圖預覽',
pagesWaves: '波浪效果',
chartIndex: '大資料圖表', chartIndex: '大資料圖表',
personal: '個人中心', personal: '個人中心',
tools: '工具類集合', tools: '工具類集合',

View File

@ -2,7 +2,7 @@ import { createApp } from 'vue';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
import { store, key } from './store'; import { store, key } from './store';
import { authDirective } from '/@/utils/authDirective.ts'; import { directive } from '/@/utils/directive.ts';
import { i18n } from '/@/i18n/index.ts'; import { i18n } from '/@/i18n/index.ts';
import { globalComponentSize } from '/@/utils/componentSize.ts'; import { globalComponentSize } from '/@/utils/componentSize.ts';
@ -25,4 +25,4 @@ app
app.config.globalProperties.mittBus = mitt(); app.config.globalProperties.mittBus = mitt();
authDirective(app); directive(app);

View File

@ -514,6 +514,21 @@ export const dynamicRoutes = [
icon: 'iconfont icon-tuodong', icon: 'iconfont icon-tuodong',
}, },
}, },
{
path: '/fun/splitpanes',
name: 'funSplitpanes',
component: () => import('/@/views/fun/splitpanes/index.vue'),
meta: {
title: 'message.router.funSplitpanes',
isLink: '',
isHide: false,
isKeepAlive: true,
isAffix: false,
isIframe: false,
auth: ['admin', 'test'],
icon: 'iconfont icon--chaifenlie',
},
},
], ],
}, },
{ {
@ -712,6 +727,21 @@ export const dynamicRoutes = [
icon: 'iconfont icon-15tupianyulan', icon: 'iconfont icon-15tupianyulan',
}, },
}, },
{
path: '/pages/waves',
name: 'pagesWaves',
component: () => import('/@/views/pages/waves/index.vue'),
meta: {
title: 'message.router.pagesWaves',
isLink: '',
isHide: false,
isKeepAlive: true,
isAffix: false,
isIframe: false,
auth: ['admin', 'test'],
icon: 'iconfont icon-bolangneng',
},
},
], ],
}, },
{ {

View File

@ -4,3 +4,4 @@
@import './element.scss'; @import './element.scss';
@import './iconSelector.scss'; @import './iconSelector.scss';
@import './media/media.scss'; @import './media/media.scss';
@import './waves.scss';

101
src/theme/waves.scss Normal file
View File

@ -0,0 +1,101 @@
/* Waves v0.6.0
* http://fian.my.id/Waves
*
* Copyright 2014 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
*/
.waves-effect {
position: relative;
cursor: pointer;
display: inline-block;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
vertical-align: middle;
z-index: 1;
will-change: opacity, transform;
transition: all 0.3s ease-out;
}
.waves-effect .waves-ripple {
position: absolute;
border-radius: 50%;
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
opacity: 0;
background: rgba(0, 0, 0, 0.2);
transition: all 0.7s ease-out;
transition-property: opacity, -webkit-transform;
transition-property: transform, opacity;
transition-property: transform, opacity, -webkit-transform;
-webkit-transform: scale(0);
transform: scale(0);
pointer-events: none;
}
.waves-effect.waves-light .waves-ripple {
background-color: rgba(255, 255, 255, 0.45);
}
.waves-effect.waves-red .waves-ripple {
background-color: rgba(244, 67, 54, 0.7);
}
.waves-effect.waves-yellow .waves-ripple {
background-color: rgba(255, 235, 59, 0.7);
}
.waves-effect.waves-orange .waves-ripple {
background-color: rgba(255, 152, 0, 0.7);
}
.waves-effect.waves-purple .waves-ripple {
background-color: rgba(156, 39, 176, 0.7);
}
.waves-effect.waves-green .waves-ripple {
background-color: rgba(76, 175, 80, 0.7);
}
.waves-effect.waves-teal .waves-ripple {
background-color: rgba(0, 150, 136, 0.7);
}
.waves-effect input[type='button'],
.waves-effect input[type='reset'],
.waves-effect input[type='submit'] {
border: 0;
font-style: normal;
font-size: inherit;
text-transform: inherit;
background: none;
}
.waves-notransition {
transition: none !important;
}
.waves-circle {
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%);
}
.waves-input-wrapper {
border-radius: 0.2em;
vertical-align: bottom;
}
.waves-input-wrapper .waves-button-input {
position: relative;
top: 0;
left: 0;
z-index: 1;
}
.waves-circle {
text-align: center;
width: 2.5em;
height: 2.5em;
line-height: 2.5em;
border-radius: 50%;
-webkit-mask-image: none;
}
.waves-block {
display: block;
}
a.waves-effect .waves-ripple {
z-index: -1;
}

View File

@ -2,6 +2,7 @@ import type { App } from 'vue';
import { store } from '/@/store/index.ts'; import { store } from '/@/store/index.ts';
import { judementSameArr } from '/@/utils/arrayOperation.ts'; import { judementSameArr } from '/@/utils/arrayOperation.ts';
// 用户权限指令
export function authDirective(app: App) { export function authDirective(app: App) {
// 单个权限验证v-auth="xxx" // 单个权限验证v-auth="xxx"
app.directive('auth', { app.directive('auth', {

View File

@ -0,0 +1,50 @@
import type { App } from 'vue';
// 按钮波浪指令
export function wavesDirective(app: App) {
app.directive('waves', {
mounted(el, binding) {
el.classList.add('waves-effect');
binding.value && el.classList.add('waves-' + binding.value);
function setConvertStyle(obj: any) {
let style: string = '';
for (let i in obj) {
if (obj.hasOwnProperty(i)) style += i + ':' + obj[i] + ';';
}
return style;
}
function onCurrentClick(e: any) {
let elDiv = document.createElement('div');
elDiv.classList.add('waves-ripple');
el.appendChild(elDiv);
let styles = {
left: `${e.layerX}px`,
top: `${e.layerY}px`,
opacity: 1,
transform: `scale(${(el.clientWidth / 100) * 10})`,
'transition-duration': `750ms`,
'transition-timing-function': `cubic-bezier(0.250, 0.460, 0.450, 0.940)`,
};
elDiv.setAttribute('style', setConvertStyle(styles));
setTimeout(() => {
elDiv.setAttribute(
'style',
setConvertStyle({
opacity: 0,
transform: styles.transform,
left: styles.left,
top: styles.top,
})
);
setTimeout(() => {
elDiv && el.removeChild(elDiv);
}, 750);
}, 450);
}
el.addEventListener('mousedown', onCurrentClick, false);
},
unmounted(el) {
el.addEventListener('mousedown', () => {});
},
});
}

11
src/utils/directive.ts Normal file
View File

@ -0,0 +1,11 @@
import type { App } from 'vue';
import { authDirective } from '/@/utils/authDirective.ts';
import { wavesDirective } from '/@/utils/customDirective.ts';
// 导出指令方法
export function directive(app: App) {
// 用户权限指令
authDirective(app);
// 按钮波浪指令
wavesDirective(app);
}

View File

@ -1,6 +1,6 @@
// 字体图标 url // 字体图标 url
const cssCdnUrlList: Array<string> = [ const cssCdnUrlList: Array<string> = [
'//at.alicdn.com/t/font_2298093_omfjza0tsa.css', '//at.alicdn.com/t/font_2298093_zyqji9hnk.css',
'//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', '//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
]; ];
// 第三方 js url // 第三方 js url

View File

@ -0,0 +1,52 @@
<template>
<div class="splitpanes-container">
<el-card shadow="hover" header="splitpanes 窗格拆分器">
<el-alert
title="感谢优秀的 `splitpanes`项目地址https://github.com/antoniandre/splitpanes"
type="success"
:closable="false"
class="mb15"
></el-alert>
<splitpanes class="default-theme" @resize="paneSize = $event[0].size" style="height: 500px">
<pane :size="32"> 1 </pane>
<pane :size="36">
<splitpanes class="default-theme" :horizontal="true">
<pane :size="100"> 2 </pane>
<pane :size="100"> 3 </pane>
</splitpanes>
</pane>
<pane :size="32"> 4 </pane>
</splitpanes>
</el-card>
</div>
</template>
<script lang="ts">
import { toRefs, reactive } from 'vue';
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
export default {
name: 'funSplitpanes',
components: { Splitpanes, Pane },
setup() {
const state = reactive({
paneSize: 50,
});
return {
...toRefs(state),
};
},
};
</script>
<style scoped lang="scss">
.splitpanes__pane {
justify-content: center;
align-items: center;
display: flex;
position: relative;
font-size: 70px;
color: var(--color-primary-light-5);
border: 1px solid #ebeef5;
}
</style>

View File

@ -2,7 +2,7 @@
<div class="waterfall-container"> <div class="waterfall-container">
<el-card shadow="hover" header="瀑布屏(布局一)" class="mb15"> <el-card shadow="hover" header="瀑布屏(布局一)" class="mb15">
<div class="waterfall-first"> <div class="waterfall-first">
<div class="waterfall-first-item" v-for="v in 30" :key="v"> <div class="waterfall-first-item" v-for="v in 30" :key="v" v-waves>
<div class="w100 h100 flex"> <div class="w100 h100 flex">
<span class="flex-margin">{{ v }}</span> <span class="flex-margin">{{ v }}</span>
</div> </div>
@ -11,7 +11,7 @@
</el-card> </el-card>
<el-card shadow="hover" header="瀑布屏(布局二)"> <el-card shadow="hover" header="瀑布屏(布局二)">
<div class="waterfall-last"> <div class="waterfall-last">
<div class="waterfall-last-item" v-for="v in 30" :key="v"> <div class="waterfall-last-item" v-for="v in 30" :key="v" v-waves="'light'">
<div class="w100 h100 flex"> <div class="w100 h100 flex">
<span class="flex-margin">{{ v }}</span> <span class="flex-margin">{{ v }}</span>
</div> </div>
@ -62,9 +62,6 @@ export default {
transition: all 0.3s ease; transition: all 0.3s ease;
cursor: pointer; cursor: pointer;
} }
&:active {
opacity: 0.5;
}
} }
} }
.waterfall-last { .waterfall-last {
@ -84,9 +81,6 @@ export default {
transition: all 0.3s ease; transition: all 0.3s ease;
cursor: pointer; cursor: pointer;
} }
&:active {
opacity: 0.5;
}
} }
} }
@media (min-width: 576px) { @media (min-width: 576px) {

View File

@ -0,0 +1,112 @@
<template>
<div class="preview-container">
<el-card shadow="hover" header="波浪指令效果v-waves作用于 btn">
<el-row class="mb10" style="color: #808080">可选参数 v-waves=" |light|red|orange|purple|green|teal"</el-row>
<div class="flex-warp">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves>默认效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="primary" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'light'">light 效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="success" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'red'">red 效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="info" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'orange'">orange 效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="warning" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'purple'">purple 效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="danger" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'green'">green 效果</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="primary" size="small" icon="iconfont icon-bolangnengshiyanchang" v-waves="'teal'">teal 效果</el-button>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover" header="波浪指令效果v-waves作用于 div" class="mt15">
<div class="waterfall-first">
<div class="waterfall-first-item" v-for="v in 12" :key="v" v-waves>
<div class="w100 h100 flex">
<span class="flex-margin">{{ v }}</span>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts">
import { toRefs, reactive } from 'vue';
export default {
name: 'pagesWaves',
setup() {
const state = reactive({});
return {
...toRefs(state),
};
},
};
</script>
<style scoped lang="scss">
.preview-container {
.flex-warp {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
margin: 0 -5px;
.flex-warp-item {
padding: 5px;
.flex-warp-item-box {
width: 100%;
height: 100%;
}
}
}
.waterfall-first {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(188px, 1fr));
grid-gap: 0.25em;
grid-auto-flow: row dense;
grid-auto-rows: 20px;
.waterfall-first-item {
width: 100%;
background: var(--color-primary);
color: #ffffff;
transition: all 0.3s ease;
border-radius: 3px;
&:nth-of-type(3n + 1) {
grid-row: auto / span 5;
}
&:nth-of-type(3n + 2) {
grid-row: auto / span 6;
}
&:nth-of-type(3n + 3) {
grid-row: auto / span 8;
}
&:hover {
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
transition: all 0.3s ease;
cursor: pointer;
}
}
}
}
</style>