Merge pull request #13 from FairyEver/dev
vue-bigdata-table Former-commit-id: 1876337abf38d66273a00513975793cb94d13f20 [formerly 1876337abf38d66273a00513975793cb94d13f20 [formerly 1876337abf38d66273a00513975793cb94d13f20 [formerly 1876337abf38d66273a00513975793cb94d13f20 [formerly cb4119d1e8a4a3fcc4c77dbb168735602d00a32e [formerly 9728461ba894fc444a9ee7cb0d8014c31e6e265e]]]]] Former-commit-id: 04a07284aeebb2d2405a9d778831574f78fc7b5b Former-commit-id: bb4396b482c181554ca454e6f0713296128cff75 Former-commit-id: bd1ebb6d2627085114a2f09d582e90181ce1c211 [formerly a82e07af85b80d02d55ce03de2d347dd2bf36dee] Former-commit-id: b55b8d237a56929f8577c5c1686ff4f2e45f808e Former-commit-id: 3ce18c3cac1f74ec82c2abaa3afb45f17fa632a3 Former-commit-id: c4fbcad67f7a3b791718205a21ac10b13beec7a7 Former-commit-id: 77e649ad7c36fccf3862ab07e17332e1adb63dae Former-commit-id: b3de824fc380b8c522c296491e2ef1e9e18c6974
This commit is contained in:
@@ -2,3 +2,4 @@
|
||||
/config/
|
||||
/dist/
|
||||
/*.js
|
||||
/src/plugin/vue-bigdata-table
|
||||
|
||||
@@ -81,6 +81,10 @@ module.exports = {
|
||||
test: /\.scss$/,
|
||||
loaders: ["style", "css", "sass"]
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
loaders: ["style", "css", "less"]
|
||||
},
|
||||
{
|
||||
test: /\.md$/,
|
||||
loaders: ["text-loader"]
|
||||
|
||||
1
design.sketch.REMOVED.git-id
Normal file
1
design.sketch.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
5180df7143acd2b32403b34a30d5c86f32288d1c
|
||||
@@ -13,6 +13,12 @@ d2admin-vue-element(以下简称 d2admin)是一个管理系统前端模板
|
||||
因为现在集成了很多的插件和组件,首次加载会占用较多的时间,虽然已经做了首屏加载动画,还是建议您在发布的时候一定要删除没有用到的代码。比如项目没有用到图表,最好将集成的图表库以及封装的图表组件删除。
|
||||
:::
|
||||
|
||||
## 前端兴趣交流群
|
||||
|
||||
欢迎加入我们的讨论
|
||||
|
||||
<img style="margin-top: 50px;" src="./image/qr.png">
|
||||
|
||||
## 功能
|
||||
|
||||
* 首屏加载等待动画 避免首次加载白屏尴尬
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
* [ 修改 ] `d2-markdown` 组件 `md` 参数改名为 `source`
|
||||
* [ 修改 ] 删除了 `d2-markdown` 组件中图片的白色背景
|
||||
* [ 修改 ] 删除 `timeago` 插件,更换为更强大的 `dayjs`
|
||||
* [ 新增 ] `Tomorrow Night Blue` 主题
|
||||
* [ 修改 ] `src/assets/style/public-class.scss` 写法优化
|
||||
|
||||
## v1.0.0
|
||||
|
||||
|
||||
1
docs/zh/guide/image/design.psd.REMOVED.git-id
Normal file
1
docs/zh/guide/image/design.psd.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
820d76c3ae5a76d729e6faa798be96a4262730f1
|
||||
1
docs/zh/guide/image/qq.jpg.REMOVED.git-id
Normal file
1
docs/zh/guide/image/qq.jpg.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
59d87fe48fd0537d1db9b071ac7852df0f3424a8
|
||||
1
docs/zh/guide/image/qr.png.REMOVED.git-id
Normal file
1
docs/zh/guide/image/qr.png.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
0916a38f3664ab8d5bf9d1146a73793fb5789ab3
|
||||
1
docs/zh/guide/image/we.jpg.REMOVED.git-id
Normal file
1
docs/zh/guide/image/we.jpg.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
b63af11a18fb4e1fb3f87463b8d5e081474a1628
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"start": "npm run dev",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"lint": "eslint --fix --ext .js,.vue src",
|
||||
"build": "node build/build.js",
|
||||
"doc:dev": "vuepress dev docs",
|
||||
"doc:build": "vuepress build docs"
|
||||
@@ -68,6 +68,8 @@
|
||||
"file-loader": "^1.1.4",
|
||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||
"html-webpack-plugin": "^2.30.1",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^4.1.0",
|
||||
"node-notifier": "^5.1.2",
|
||||
"node-sass": "^4.7.2",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
|
||||
@@ -48,6 +48,12 @@ $sizes: (0, 10, 15, 20);
|
||||
.#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px; }
|
||||
|
||||
.#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px; }
|
||||
.#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px; }
|
||||
}
|
||||
|
||||
// 快速使用
|
||||
|
||||
@@ -1,162 +1,3 @@
|
||||
@import '../theme.scss';
|
||||
@import '~@/assets/style/public.scss';
|
||||
@import './setting.scss';
|
||||
|
||||
.theme-#{$theme-name} {
|
||||
|
||||
.layout-main {
|
||||
background-color: $theme-bg-color;
|
||||
// background-image: url($theme-bg-image);
|
||||
}
|
||||
// 菜单项目
|
||||
@mixin theme-menu-hover-style {
|
||||
color: $theme-menu-item-color-hover;
|
||||
i {
|
||||
color: $theme-menu-item-color-hover;
|
||||
}
|
||||
background-color: $theme-menu-item-background-color-hover;
|
||||
}
|
||||
.el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu-item:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu .el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
|
||||
// [组件] d2-container-full
|
||||
.d2-container-full {
|
||||
border: $theme-container-border-outer;
|
||||
border-bottom: none;
|
||||
background-color: $theme-container-background-color;
|
||||
.d2-container-full__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
.d2-container-full__footer {
|
||||
border-top: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
// [组件] d2-container-card
|
||||
.d2-container-card {
|
||||
border: $theme-container-border-outer;
|
||||
background-color: $theme-container-background-color;
|
||||
.el-card__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 顶栏
|
||||
.el-header {
|
||||
// 切换按钮
|
||||
.toggle-aside-btn {
|
||||
i {
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏菜单
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-header-item-color-active;
|
||||
background-color: $theme-header-item-background-color-active;
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏右侧
|
||||
.d2-header-right {
|
||||
.btn-text {
|
||||
color: $theme-header-item-color;
|
||||
&.can-hover {
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// [布局] 顶栏下面
|
||||
.el-container {
|
||||
// 侧边栏
|
||||
.el-aside {
|
||||
// [菜单] 正常状态
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-aside-item-color-focus;
|
||||
background-color: $theme-aside-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-aside-item-color-active;
|
||||
background-color: $theme-aside-item-background-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import '../theme.scss';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// 主题名称
|
||||
$theme-name: 'd2';
|
||||
// 主题背景颜色
|
||||
$theme-bg-color: $color-bg;
|
||||
$theme-bg-color: #f8f8f9;
|
||||
// 主题背景图片
|
||||
// $theme-bg-image: '/static/image/bg/xxx.jpg';
|
||||
$theme-bg-image: none;
|
||||
|
||||
// container组件
|
||||
$theme-container-background-color: rgba(#FFF, 1);
|
||||
@@ -39,4 +39,12 @@ $theme-aside-item-color-focus: $color-text-main;
|
||||
$theme-aside-item-background-color-focus: rgba(#000, .02);
|
||||
// 侧边栏上的项目在 active 时
|
||||
$theme-aside-item-color-active: $color-text-main;
|
||||
$theme-aside-item-background-color-active: rgba(#000, .03);
|
||||
$theme-aside-item-background-color-active: rgba(#000, .03);
|
||||
|
||||
// 侧边栏菜单为空的时候显示的元素
|
||||
$theme-aside-menu-empty-icon-color: $color-text-normal;
|
||||
$theme-aside-menu-empty-text-color: $color-text-normal;
|
||||
$theme-aside-menu-empty-background-color: rgba(#000, .03);
|
||||
$theme-aside-menu-empty-icon-color-hover: $color-text-main;
|
||||
$theme-aside-menu-empty-text-color-hover: $color-text-main;
|
||||
$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);
|
||||
@@ -1,162 +1,3 @@
|
||||
@import '../theme.scss';
|
||||
@import '~@/assets/style/public.scss';
|
||||
@import './setting.scss';
|
||||
|
||||
.theme-#{$theme-name} {
|
||||
|
||||
.layout-main {
|
||||
background-color: $theme-bg-color;
|
||||
background-image: url($theme-bg-image);
|
||||
}
|
||||
// 菜单项目
|
||||
@mixin theme-menu-hover-style {
|
||||
color: $theme-menu-item-color-hover;
|
||||
i {
|
||||
color: $theme-menu-item-color-hover;
|
||||
}
|
||||
background-color: $theme-menu-item-background-color-hover;
|
||||
}
|
||||
.el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu-item:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu .el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
|
||||
// [组件] d2-container-full
|
||||
.d2-container-full {
|
||||
border: $theme-container-border-outer;
|
||||
border-bottom: none;
|
||||
background-color: $theme-container-background-color;
|
||||
.d2-container-full__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
.d2-container-full__footer {
|
||||
border-top: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
// [组件] d2-container-card
|
||||
.d2-container-card {
|
||||
border: $theme-container-border-outer;
|
||||
background-color: $theme-container-background-color;
|
||||
.el-card__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 顶栏
|
||||
.el-header {
|
||||
// 切换按钮
|
||||
.toggle-aside-btn {
|
||||
i {
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏菜单
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-header-item-color-active;
|
||||
background-color: $theme-header-item-background-color-active;
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏右侧
|
||||
.d2-header-right {
|
||||
.btn-text {
|
||||
color: $theme-header-item-color;
|
||||
&.can-hover {
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// [布局] 顶栏下面
|
||||
.el-container {
|
||||
// 侧边栏
|
||||
.el-aside {
|
||||
// [菜单] 正常状态
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-aside-item-color-focus;
|
||||
background-color: $theme-aside-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-aside-item-color-active;
|
||||
background-color: $theme-aside-item-background-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import '../theme.scss';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// 主题名称
|
||||
$theme-name: 'line';
|
||||
// 主题背景颜色
|
||||
$theme-bg-color: $color-bg;
|
||||
$theme-bg-color: #f8f8f9;
|
||||
// 主题背景图片
|
||||
$theme-bg-image: '/static/image/bg/line-squashed.jpg';
|
||||
$theme-bg-image: url('/static/image/bg/line-squashed.jpg');
|
||||
|
||||
// container组件
|
||||
$theme-container-background-color: rgba(#FFF, .8);
|
||||
@@ -39,4 +39,12 @@ $theme-aside-item-color-focus: $color-text-main;
|
||||
$theme-aside-item-background-color-focus: rgba(#000, .02);
|
||||
// 侧边栏上的项目在 active 时
|
||||
$theme-aside-item-color-active: $color-text-main;
|
||||
$theme-aside-item-background-color-active: rgba(#000, .03);
|
||||
$theme-aside-item-background-color-active: rgba(#000, .03);
|
||||
|
||||
// 侧边栏菜单为空的时候显示的元素
|
||||
$theme-aside-menu-empty-icon-color: $color-text-normal;
|
||||
$theme-aside-menu-empty-text-color: $color-text-normal;
|
||||
$theme-aside-menu-empty-background-color: rgba(#000, .03);
|
||||
$theme-aside-menu-empty-icon-color-hover: $color-text-main;
|
||||
$theme-aside-menu-empty-text-color-hover: $color-text-main;
|
||||
$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);
|
||||
4
src/assets/style/theme/register.scss
Normal file
4
src/assets/style/theme/register.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import '~@/assets/style/theme/d2/index.scss';
|
||||
@import '~@/assets/style/theme/line/index.scss';
|
||||
@import '~@/assets/style/theme/star/index.scss';
|
||||
@import '~@/assets/style/theme/tomorrow-night-blue/index.scss';
|
||||
@@ -1,162 +1,3 @@
|
||||
@import '../theme.scss';
|
||||
@import '~@/assets/style/public.scss';
|
||||
@import './setting.scss';
|
||||
|
||||
.theme-#{$theme-name} {
|
||||
|
||||
.layout-main {
|
||||
background-color: $theme-bg-color;
|
||||
background-image: url($theme-bg-image);
|
||||
}
|
||||
// 菜单项目
|
||||
@mixin theme-menu-hover-style {
|
||||
color: $theme-menu-item-color-hover;
|
||||
i {
|
||||
color: $theme-menu-item-color-hover;
|
||||
}
|
||||
background-color: $theme-menu-item-background-color-hover;
|
||||
}
|
||||
.el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu-item:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu .el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
|
||||
// [组件] d2-container-full
|
||||
.d2-container-full {
|
||||
border: $theme-container-border-outer;
|
||||
border-bottom: none;
|
||||
background-color: $theme-container-background-color;
|
||||
.d2-container-full__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
.d2-container-full__footer {
|
||||
border-top: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
// [组件] d2-container-card
|
||||
.d2-container-card {
|
||||
border: $theme-container-border-outer;
|
||||
background-color: $theme-container-background-color;
|
||||
.el-card__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 顶栏
|
||||
.el-header {
|
||||
// 切换按钮
|
||||
.toggle-aside-btn {
|
||||
i {
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏菜单
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-header-item-color-active;
|
||||
background-color: $theme-header-item-background-color-active;
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏右侧
|
||||
.d2-header-right {
|
||||
.btn-text {
|
||||
color: $theme-header-item-color;
|
||||
&.can-hover {
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// [布局] 顶栏下面
|
||||
.el-container {
|
||||
// 侧边栏
|
||||
.el-aside {
|
||||
// [菜单] 正常状态
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-aside-item-color-focus;
|
||||
background-color: $theme-aside-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-aside-item-color-active;
|
||||
background-color: $theme-aside-item-background-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import '../theme.scss';
|
||||
|
||||
@@ -3,7 +3,7 @@ $theme-name: 'star';
|
||||
// 主题背景颜色
|
||||
$theme-bg-color: #EFF4F8;
|
||||
// 主题背景图片
|
||||
$theme-bg-image: '/static/image/bg/star-squashed.jpg';
|
||||
$theme-bg-image: url('/static/image/bg/star-squashed.jpg');
|
||||
|
||||
// container组件
|
||||
$theme-container-background-color: rgba(#FFF, .9);
|
||||
@@ -39,4 +39,12 @@ $theme-aside-item-color-focus: #FFF;
|
||||
$theme-aside-item-background-color-focus: rgba(#000, .2);
|
||||
// 侧边栏上的项目在 active 时
|
||||
$theme-aside-item-color-active: #FFF;
|
||||
$theme-aside-item-background-color-active: rgba(#000, .3);
|
||||
$theme-aside-item-background-color-active: rgba(#000, .3);
|
||||
|
||||
// 侧边栏菜单为空的时候显示的元素
|
||||
$theme-aside-menu-empty-icon-color: #FFF;
|
||||
$theme-aside-menu-empty-text-color: #FFF;
|
||||
$theme-aside-menu-empty-background-color: rgba(#FFF, .2);
|
||||
$theme-aside-menu-empty-icon-color-hover: #FFF;
|
||||
$theme-aside-menu-empty-text-color-hover: #FFF;
|
||||
$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .3);
|
||||
@@ -1,11 +1,19 @@
|
||||
@import '~@/assets/style/public.scss';
|
||||
|
||||
// 主题公用
|
||||
.layout-main {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
position: relative;
|
||||
// &:before {
|
||||
// content: '';
|
||||
// position: absolute;
|
||||
// top: 0px;
|
||||
// right: 0px;
|
||||
// bottom: 0px;
|
||||
// left: 0px;
|
||||
// background-color: rgba(#000, .5);
|
||||
// }
|
||||
// [布局] 顶栏
|
||||
.el-header {
|
||||
padding: 0px;
|
||||
@@ -26,8 +34,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
@extend %unable-select;
|
||||
i {
|
||||
font-size: 20px;
|
||||
margin-top: 4px;
|
||||
@@ -39,9 +46,11 @@
|
||||
border-bottom: none;
|
||||
background-color: transparent;
|
||||
.el-menu-item {
|
||||
@extend %unable-select;
|
||||
border-bottom: none;
|
||||
}
|
||||
.el-submenu {
|
||||
@extend %unable-select;
|
||||
.el-submenu__title {
|
||||
border-bottom: none;
|
||||
}
|
||||
@@ -60,8 +69,7 @@
|
||||
margin-left: 10px !important;
|
||||
}
|
||||
.el-dropdown {
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
@extend %unable-select;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,6 +81,7 @@
|
||||
overflow: inherit;
|
||||
// [菜单] 正常状态
|
||||
.el-menu {
|
||||
@extend %unable-select;
|
||||
background-color: transparent;
|
||||
border-right: none;
|
||||
.el-menu-item {
|
||||
@@ -83,6 +92,7 @@
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
@extend %unable-select;
|
||||
.el-submenu__title {
|
||||
i {
|
||||
margin-right: 5px;
|
||||
@@ -93,6 +103,25 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// 菜单为空的时候显示的信息
|
||||
.menu-empty {
|
||||
height: 160px;
|
||||
margin: 10px;
|
||||
margin-top: 0px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
@extend %unable-select;
|
||||
i {
|
||||
font-size: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
// [菜单] 折叠状态
|
||||
.el-menu--collapse {
|
||||
background-color: transparent;
|
||||
@@ -143,3 +172,211 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 每个主题特有的设置
|
||||
|
||||
.theme-#{$theme-name} {
|
||||
|
||||
.layout-main {
|
||||
background-color: $theme-bg-color;
|
||||
background-image: $theme-bg-image;
|
||||
}
|
||||
// 菜单项目
|
||||
@mixin theme-menu-hover-style {
|
||||
color: $theme-menu-item-color-hover;
|
||||
i {
|
||||
color: $theme-menu-item-color-hover;
|
||||
}
|
||||
background-color: $theme-menu-item-background-color-hover;
|
||||
}
|
||||
.el-submenu__title {
|
||||
@extend %unable-select;
|
||||
}
|
||||
.el-menu-item {
|
||||
@extend %unable-select;
|
||||
}
|
||||
.el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu-item:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
.el-menu--horizontal .el-menu .el-submenu__title:hover {
|
||||
@include theme-menu-hover-style;
|
||||
}
|
||||
|
||||
// [组件] d2-container-full
|
||||
.d2-container-full {
|
||||
border: $theme-container-border-outer;
|
||||
border-bottom: none;
|
||||
background-color: $theme-container-background-color;
|
||||
.d2-container-full__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
.d2-container-full__footer {
|
||||
border-top: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
// [组件] d2-container-card
|
||||
.d2-container-card {
|
||||
border: $theme-container-border-outer;
|
||||
background-color: $theme-container-background-color;
|
||||
.el-card__header {
|
||||
border-bottom: $theme-container-border-inner;
|
||||
background-color: $theme-container-header-footer-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 顶栏
|
||||
.el-header {
|
||||
// 切换按钮
|
||||
.toggle-aside-btn {
|
||||
i {
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏菜单
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-header-item-color-active;
|
||||
background-color: $theme-header-item-background-color-active;
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
transition: border-top-color 0s;
|
||||
color: $theme-header-item-color;
|
||||
background-color: $theme-header-item-background-color;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color-hover;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-header-item-color-focus;
|
||||
background-color: $theme-header-item-background-color-focus;
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-header-item-color-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶栏右侧
|
||||
.d2-header-right {
|
||||
.btn-text {
|
||||
color: $theme-header-item-color;
|
||||
&.can-hover {
|
||||
&:hover {
|
||||
color: $theme-header-item-color-hover;
|
||||
background-color: $theme-header-item-background-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// [布局] 顶栏下面
|
||||
.el-container {
|
||||
// 侧边栏
|
||||
.el-aside {
|
||||
// 菜单为空的时候显示的信息
|
||||
.menu-empty {
|
||||
background-color: $theme-aside-menu-empty-background-color;
|
||||
i {
|
||||
color: $theme-aside-menu-empty-icon-color;
|
||||
}
|
||||
span {
|
||||
color: $theme-aside-menu-empty-text-color;
|
||||
}
|
||||
&:hover {
|
||||
background-color: $theme-aside-menu-empty-background-color-hover;
|
||||
i {
|
||||
color: $theme-aside-menu-empty-icon-color-hover;
|
||||
}
|
||||
span {
|
||||
color: $theme-aside-menu-empty-text-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
// [菜单] 正常状态
|
||||
.el-menu {
|
||||
.el-menu-item {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
i {
|
||||
color: $theme-aside-item-color-hover;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
color: $theme-aside-item-color-focus;
|
||||
background-color: $theme-aside-item-background-color-focus;
|
||||
i {
|
||||
color: $theme-aside-item-color-focus;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
color: $theme-aside-item-color-active;
|
||||
background-color: $theme-aside-item-background-color-active;
|
||||
i {
|
||||
color: $theme-aside-item-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-submenu {
|
||||
.el-submenu__title {
|
||||
color: $theme-aside-item-color;
|
||||
background-color: $theme-aside-item-background-color;
|
||||
i {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-aside-item-color;
|
||||
}
|
||||
&:hover {
|
||||
color: $theme-aside-item-color-hover;
|
||||
background-color: $theme-aside-item-background-color-hover;
|
||||
i {
|
||||
color: $theme-aside-item-color-hover;
|
||||
}
|
||||
.el-submenu__icon-arrow {
|
||||
color: $theme-aside-item-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
src/assets/style/theme/tomorrow-night-blue/index.scss
Normal file
3
src/assets/style/theme/tomorrow-night-blue/index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@import '~@/assets/style/public.scss';
|
||||
@import './setting.scss';
|
||||
@import '../theme.scss';
|
||||
50
src/assets/style/theme/tomorrow-night-blue/setting.scss
Normal file
50
src/assets/style/theme/tomorrow-night-blue/setting.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
// 主题名称
|
||||
$theme-name: 'tomorrow-night-blue';
|
||||
// 主题背景颜色
|
||||
$theme-bg-color: #002147;
|
||||
// 主题背景图片
|
||||
$theme-bg-image: none;
|
||||
|
||||
// container组件
|
||||
$theme-container-background-color: #FFF;
|
||||
$theme-container-header-footer-background-color: #FFF;
|
||||
$theme-container-border-inner: 1px solid $color-border-1;
|
||||
$theme-container-border-outer: none;
|
||||
|
||||
// 顶栏和侧边栏中展开的菜单 hover 状态下
|
||||
$theme-menu-item-color-hover: #293849;
|
||||
$theme-menu-item-background-color-hover: #ecf5ff;
|
||||
|
||||
// 顶栏上的文字颜色
|
||||
$theme-header-item-color: #FF929A;
|
||||
$theme-header-item-background-color: transparent;
|
||||
// 顶栏上的项目在 hover 时
|
||||
$theme-header-item-color-hover: #FFEBA4;
|
||||
$theme-header-item-background-color-hover: #00162D;
|
||||
// 顶栏上的项目在 focus 时
|
||||
$theme-header-item-color-focus: #FFB870;
|
||||
$theme-header-item-background-color-focus: #00162D;
|
||||
// 顶栏上的项目在 active 时
|
||||
$theme-header-item-color-active: #FFB870;
|
||||
$theme-header-item-background-color-active: #00162D;
|
||||
|
||||
// 侧边栏上的文字颜色
|
||||
$theme-aside-item-color: #FF929A;
|
||||
$theme-aside-item-background-color: transparent;
|
||||
// 侧边栏上的项目在 hover 时
|
||||
$theme-aside-item-color-hover: #FFEBA4;
|
||||
$theme-aside-item-background-color-hover: #00162D;
|
||||
// 侧边栏上的项目在 focus 时
|
||||
$theme-aside-item-color-focus: #FFB870;
|
||||
$theme-aside-item-background-color-focus: #00162D;
|
||||
// 侧边栏上的项目在 active 时
|
||||
$theme-aside-item-color-active: #FFB870;
|
||||
$theme-aside-item-background-color-active: #00162D;
|
||||
|
||||
// 侧边栏菜单为空的时候显示的元素
|
||||
$theme-aside-menu-empty-icon-color: #FFB870;
|
||||
$theme-aside-menu-empty-text-color: #FFB870;
|
||||
$theme-aside-menu-empty-background-color: rgba(#FFF, .1);
|
||||
$theme-aside-menu-empty-icon-color-hover: #FFEBA4;
|
||||
$theme-aside-menu-empty-text-color-hover: #FFEBA4;
|
||||
$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .2);
|
||||
@@ -14,8 +14,8 @@ import menus from '@/menu/index.js'
|
||||
export default {
|
||||
name: 'd2-layout-main-menu-header',
|
||||
components: {
|
||||
'd2-layout-main-menu-item': () => import('../d2-layout-main-menu-item/index.vue'),
|
||||
'd2-layout-main-menu-sub': () => import('../d2-layout-main-menu-sub/index.vue')
|
||||
'd2-layout-main-menu-item': () => import('../-menu-item/index.vue'),
|
||||
'd2-layout-main-menu-sub': () => import('../-menu-sub/index.vue')
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div class="d2-header-right">
|
||||
<d2-layout-main-header-right-full-screen/>
|
||||
<d2-layout-main-header-right-theme/>
|
||||
<d2-layout-main-header-right-user/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'd2-layout-main-header-right',
|
||||
components: {
|
||||
'd2-layout-main-header-right-full-screen': () => import('./components/-full-screen.vue'),
|
||||
'd2-layout-main-header-right-theme': () => import('./components/-theme.vue'),
|
||||
'd2-layout-main-header-right-user': () => import('./components/-user.vue')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,26 +0,0 @@
|
||||
<template>
|
||||
<el-menu
|
||||
mode="horizontal"
|
||||
:router="true">
|
||||
<template v-for="(menu, menuIndex) in menus">
|
||||
<d2-layout-main-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/>
|
||||
<d2-layout-main-menu-sub v-else :menu="menu" :key="menuIndex"/>
|
||||
</template>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import menus from '@/menu/index.js'
|
||||
export default {
|
||||
name: 'd2-layout-main-menu-header',
|
||||
components: {
|
||||
'd2-layout-main-menu-item': () => import('../-menu-item/index.vue'),
|
||||
'd2-layout-main-menu-sub': () => import('../-menu-sub/index.vue')
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
menus
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -9,9 +9,10 @@
|
||||
<d2-layout-main-menu-sub v-else :menu="menu" :key="menuIndex"/>
|
||||
</template>
|
||||
</el-menu>
|
||||
<!-- <div v-if="sideMenu.filter(e => e.title).length === 0 && !collapse" class="d2-menu-side-empty">
|
||||
没有菜单
|
||||
</div> -->
|
||||
<div v-if="menus.length === 0 && !collapse" class="menu-empty">
|
||||
<d2-icon name="hdd-o"/>
|
||||
<span>当前目录没有菜单</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -9,8 +9,13 @@
|
||||
<div class="toggle-aside-btn" @click="collapse = !collapse">
|
||||
<d2-icon name="bars"/>
|
||||
</div>
|
||||
<d2-layout-main-menu-header/>
|
||||
<d2-layout-main-header-right/>
|
||||
<d2-layout-main-header-menu/>
|
||||
<!-- 顶栏右侧 -->
|
||||
<div class="d2-header-right">
|
||||
<d2-layout-main-header-full-screen/>
|
||||
<d2-layout-main-header-theme/>
|
||||
<d2-layout-main-header-user/>
|
||||
</div>
|
||||
</el-header>
|
||||
<!-- 下面 主体 -->
|
||||
<el-container>
|
||||
@@ -34,8 +39,10 @@ export default {
|
||||
name: 'd2-layout-main',
|
||||
components: {
|
||||
'd2-layout-main-menu-side': () => import('./components/-menu-side'),
|
||||
'd2-layout-main-menu-header': () => import('./components/-menu-header'),
|
||||
'd2-layout-main-header-right': () => import('./components/-header-right')
|
||||
'd2-layout-main-header-menu': () => import('./components/-header-menu'),
|
||||
'd2-layout-main-header-full-screen': () => import('./components/-full-screen'),
|
||||
'd2-layout-main-header-theme': () => import('./components/-theme'),
|
||||
'd2-layout-main-header-user': () => import('./components/-user')
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -64,8 +71,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// 主题
|
||||
@import '~@/assets/style/theme/d2/index.scss';
|
||||
@import '~@/assets/style/theme/line/index.scss';
|
||||
@import '~@/assets/style/theme/star/index.scss';
|
||||
// 注册主题
|
||||
@import '~@/assets/style/theme/register.scss';
|
||||
</style>
|
||||
|
||||
@@ -41,6 +41,8 @@ import pluginExport from '@/plugin/export'
|
||||
import pluginLog from '@/plugin/log'
|
||||
// 插件 打开页面
|
||||
import pluginOpen from '@/plugin/open'
|
||||
// 插件 支持百万级数据的表格
|
||||
import bigdataTable from '@/plugin/vue-bigdata-table'
|
||||
|
||||
Vue.use(ElementUI)
|
||||
|
||||
@@ -48,6 +50,7 @@ Vue.use(pluginImport)
|
||||
Vue.use(pluginExport)
|
||||
Vue.use(pluginLog)
|
||||
Vue.use(pluginOpen)
|
||||
Vue.use(bigdataTable)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ const demoComponents = {
|
||||
{ path: `${pre}markdown/url`, title: '异步加载文件' }
|
||||
]
|
||||
},
|
||||
{ path: `${pre}bigdata-table`, title: '超大量数据表格' },
|
||||
{ path: `${pre}countup`, title: '数字动画' },
|
||||
{ path: `${pre}editor-quill`, title: '富文本编辑器' },
|
||||
{ path: `${pre}editor-simpleMDE`, title: 'markdown编辑器' },
|
||||
|
||||
142
src/pages/demo/components/bigdata-table/index.vue
Normal file
142
src/pages/demo/components/bigdata-table/index.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<d2-container>
|
||||
<el-button-group slot="header">
|
||||
<el-button size="mini" @click="scrollRowTo(2)">跳转到第3行</el-button>
|
||||
<el-button size="mini" @click="scrollRowTo(Math.round(tableDataHandled.length * 0.8))">
|
||||
跳转到第{{Math.round(tableDataHandled.length * 0.8) + 1}}行
|
||||
</el-button>
|
||||
<el-button size="mini" @click="editCell">编辑第{{ editRow }}行第{{ editCol }}列</el-button>
|
||||
<el-button size="mini" @click="changeData(Math.round(Math.random() * 30000))">改变数据</el-button>
|
||||
<el-button size="mini" @click="changeDefaultSort">改变默认排序方式</el-button>
|
||||
</el-button-group>
|
||||
<h1 class="d2-mt-0">当前数据量 {{tableDataHandled.length}}</h1>
|
||||
<div class="wraper">
|
||||
<bigdata-table
|
||||
ref="table"
|
||||
v-model="tableDataHandled"
|
||||
:row-num="20"
|
||||
:col-num="7"
|
||||
show-index
|
||||
start-edit-type="dblclick"
|
||||
fixed
|
||||
stripe
|
||||
:col-width="200"
|
||||
:header-height="50"
|
||||
:can-edit="canEdit"
|
||||
:at-right-cell-posi="20"
|
||||
:at-left-cell-posi="40"
|
||||
:columns="columns"
|
||||
:index-render="indexRender"
|
||||
:fixed-col="0"
|
||||
:sort-index="2"
|
||||
:default-sort="defaultSort"
|
||||
selectable
|
||||
paste
|
||||
:beforeSave="beforeSave"
|
||||
:disabled-hover="false"
|
||||
@on-success-save="handleSuccessEdit"
|
||||
@on-fail-save="handleFailEdit"
|
||||
@on-moving-on-header="handleMoving"
|
||||
@on-click-tr="handleClickTr"
|
||||
@on-click-td="handleClickTd"/>
|
||||
</div>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
// 本页是由 https://github.com/lison16/vue-bigdata-table/blob/master/src/App.vue 修改而来
|
||||
// 由于原页面有太多的地方不符合本项目的代码规范,本页面不做代码检查
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
tableData: [],
|
||||
columns: [],
|
||||
tableDataHandled: [], // 带有数据的表格数据
|
||||
emptyData: [], // 空的表格数据
|
||||
canEdit: true,
|
||||
editRow: 1,
|
||||
editCol: 1,
|
||||
defaultSort: {1: 'down'}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tableDataHandled (res) {
|
||||
// res
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
indexRender (h, index) {
|
||||
return h('div', {}, index + 1)
|
||||
},
|
||||
handleMoving (e) {
|
||||
// this.$log('handleMoving', e.atGivenArea + '......' + e.colIndex)
|
||||
},
|
||||
scrollRowTo (index) {
|
||||
this.$refs.table.scrollToRow(index)
|
||||
},
|
||||
handleClickTr (index) {
|
||||
this.$log('handleClickTr', index)
|
||||
},
|
||||
handleClickTd (params) {
|
||||
this.$log('handleClickTd', params)
|
||||
},
|
||||
clickEditBtn () {
|
||||
this.canEdit = !this.canEdit
|
||||
},
|
||||
beforeSave ({ row, col, value }) {
|
||||
return (row + 1) % 2
|
||||
},
|
||||
handleSuccessEdit ({ row, col, value, initRowIndex }) {
|
||||
this.$message(`第${initRowIndex + 1}行第${initRowIndex + 1}列改为${value}`)
|
||||
},
|
||||
handleFailEdit (res) {
|
||||
this.$message('偶数行不能编辑')
|
||||
},
|
||||
editCell () {
|
||||
this.$refs.table.editCell(this.editRow - 1, this.editCol - 1)
|
||||
},
|
||||
changeData (rowLen) {
|
||||
let dataArr = []
|
||||
for (let i = 0; i < rowLen; i++) {
|
||||
let arr = [
|
||||
i + '00',
|
||||
'count' + i,
|
||||
'23.4534534345',
|
||||
'0023' + i,
|
||||
'123.234534534534',
|
||||
'namenasdfsdfsdfsdfssdfsdfsdsdfsdfsf' + i,
|
||||
'2014年1月1日'
|
||||
]
|
||||
dataArr.push(arr)
|
||||
}
|
||||
this.tableDataHandled = dataArr
|
||||
},
|
||||
changeDefaultSort () {
|
||||
this.defaultSort = {2: 'up'}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.changeData(10000)
|
||||
let columns = ['这是数字', '这是字符1列', '这是纬度', '这是数字', '这是经度', '这是字符2列', '这是时间'].map((title, col) => {
|
||||
return {
|
||||
title: title,
|
||||
align: 'center'
|
||||
}
|
||||
})
|
||||
this.columns = columns
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.wraper{
|
||||
height: 400px;
|
||||
// position: absolute;
|
||||
// top: 0px;
|
||||
// right: 0px;
|
||||
// left: 0px;
|
||||
// right: 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,62 +1,63 @@
|
||||
<template>
|
||||
<d2-container type="full">
|
||||
<template slot="header">
|
||||
<el-button @click="handleReset">重新设置基础时间 this.now = dayjs()</el-button>
|
||||
</template>
|
||||
<h1 class="d2-mt-0">当前时间</h1>
|
||||
<template slot="header">日期计算</template>
|
||||
<h1 class="d2-mt-0">解析</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`now.format('YYYY年M月D日 HH:mm:ss')`"/>{{now.format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 当前时间\ndayjs()`"/>{{dayjs()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 时间字符串\ndayjs('1995-12-25')`"/>{{dayjs('1995-12-25')}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// Unix 时间戳 (毫秒)\ndayjs(1318781876406)`"/>{{dayjs(1318781876406)}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// Date 对象\ndayjs(new Date(2018, 8, 18))`"/>{{dayjs(new Date(2018, 8, 18))}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 复制\ndayjs().clone()`"/>{{dayjs().clone()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 检测是否是一个有效的时间\ndayjs().isValid()`"/>{{dayjs().isValid()}}</el-card></el-col>
|
||||
</el-row>
|
||||
<h1>获取</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//获取年\nnow.year()`"/>{{now.year()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//获取月\nnow.month()`"/>{{now.month()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//获取日\nnow.date()`"/>{{now.date()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//获取星期\nnow.day()`"/>{{now.day()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`//获取小时\nnow.hour()`"/>{{now.hour()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`//获取分钟\nnow.minute()`"/>{{now.minute()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`//获取秒\nnow.second()`"/>{{now.second()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`//获取毫秒\nnow.millisecond()`"/>{{now.millisecond()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 获取年\ndayjs().year()`"/>{{dayjs().year()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 获取月\ndayjs().month()`"/>{{dayjs().month()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 获取日\ndayjs().date()`"/>{{dayjs().date()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 获取星期\ndayjs().day()`"/>{{dayjs().day()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 获取小时\ndayjs().hour()`"/>{{dayjs().hour()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 获取分钟\ndayjs().minute()`"/>{{dayjs().minute()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 获取秒\ndayjs().second()`"/>{{dayjs().second()}}</el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="never"><d2-highlight slot="header" :code="`// 获取毫秒\ndayjs().millisecond()`"/>{{dayjs().millisecond()}}</el-card></el-col>
|
||||
</el-row>
|
||||
<h1>设置</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`//设置月份\nnow.set('month', 6).month()`"/>{{now.set('month', 6).month()}}</el-card></el-col>
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`//设置秒\nnow.set('second', 30).second()`"/>{{now.set('second', 30).second()}}</el-card></el-col>
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`//设置小时\nnow.set('hour', 4).hour()`"/>{{now.set('hour', 4).hour()}}</el-card></el-col>
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`// 设置月份\ndayjs().set('month', 6).month()`"/>{{dayjs().set('month', 6).month()}}</el-card></el-col>
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`// 设置秒\ndayjs().set('second', 30).second()`"/>{{dayjs().set('second', 30).second()}}</el-card></el-col>
|
||||
<el-col :span="8"><el-card shadow="never"><d2-highlight slot="header" :code="`// 设置小时\ndayjs().set('hour', 4).hour()`"/>{{dayjs().set('hour', 4).hour()}}</el-card></el-col>
|
||||
</el-row>
|
||||
<h1>操作</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//增加\nnow.add(1, 'day').format('YYYY年M月D日 HH:mm:ss')`"/>{{now.add(1, 'day').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//减少\nnow.subtract(7, 'year').format('YYYY年M月D日 HH:mm:ss')`"/>{{now.subtract(7, 'year').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`//开头时间\nnow.startOf('year').format('YYYY年M月D日 HH:mm:ss')`"/>{{now.startOf('year').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`//末尾时间\nnow.endOf('month').format('YYYY年M月D日 HH:mm:ss')`"/>{{now.endOf('month').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 增加\ndayjs().add(1, 'day').format('YYYY年M月D日 HH:mm:ss')`"/>{{dayjs().add(1, 'day').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 减少\ndayjs().subtract(7, 'year').format('YYYY年M月D日 HH:mm:ss')`"/>{{dayjs().subtract(7, 'year').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`// 开头时间\ndayjs().startOf('year').format('YYYY年M月D日 HH:mm:ss')`"/>{{dayjs().startOf('year').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`// 末尾时间\ndayjs().endOf('month').format('YYYY年M月D日 HH:mm:ss')`"/>{{dayjs().endOf('month').format('YYYY年M月D日 HH:mm:ss')}}</el-card></el-col>
|
||||
</el-row>
|
||||
<h1>显示</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//格式化\nnow.format('YYYY-M-D HH:mm:ss')`"/>{{now.format('YYYY-M-D HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//时间差\nnow.diff(now.subtract(1, 'day'), 'days')`"/>{{now.diff(now.subtract(1, 'day'), 'days')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//Unix 时间戳 (毫秒)\nnow.valueOf()`"/>{{now.valueOf()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//Unix 时间戳 (秒)\nnow.unix()`"/>{{now.unix()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//天数 (月)\nnow.daysInMonth()`"/>{{now.daysInMonth()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//Date 对象\nnow.toDate()`"/>{{now.toDate()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//数组\nnow.toArray()`"/>{{now.toArray()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//序列化 Dayjs 对象时会返回 ISO 8601 格式的字符串\nnow.toJSON()`"/>{{now.toJSON()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//ISO 8601 字符串\nnow.toISOString()`"/>{{now.toISOString()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//字符串\nnow.toString()`"/>{{now.toString()}}</el-card></el-col>
|
||||
<el-col :span="24"><el-card shadow="never"><d2-highlight slot="header" :code="`//对象\nnow.toObject()`"/>{{now.toObject()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 格式化\ndayjs().format('YYYY-M-D HH:mm:ss')`"/>{{dayjs().format('YYYY-M-D HH:mm:ss')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 时间差\ndayjs().diff(dayjs().subtract(1, 'day'), 'days')`"/>{{dayjs().diff(dayjs().subtract(1, 'day'), 'days')}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// Unix 时间戳 (毫秒)\ndayjs().valueOf()`"/>{{dayjs().valueOf()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// Unix 时间戳 (秒)\ndayjs().unix()`"/>{{dayjs().unix()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 天数 (月)\ndayjs().daysInMonth()`"/>{{dayjs().daysInMonth()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// Date 对象\ndayjs().toDate()`"/>{{dayjs().toDate()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 数组\ndayjs().toArray()`"/>{{dayjs().toArray()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 序列化 Dayjs 对象时会返回 ISO 8601 格式的字符串\ndayjs().toJSON()`"/>{{dayjs().toJSON()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// ISO 8601 字符串\ndayjs().toISOString()`"/>{{dayjs().toISOString()}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 字符串\ndayjs().toString()`"/>{{dayjs().toString()}}</el-card></el-col>
|
||||
<el-col :span="24"><el-card shadow="never"><d2-highlight slot="header" :code="`// 对象\ndayjs().toObject()`"/>{{dayjs().toObject()}}</el-card></el-col>
|
||||
</el-row>
|
||||
<h1>查询</h1>
|
||||
<el-row :gutter="20" class="d2-mt">
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//是否之前\nnow.isBefore(now.add(1, 'day'))`"/>{{now.isBefore(now.add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//是否之前\nnow.isBefore(now.subtract(1, 'day'))`"/>{{now.isBefore(now.subtract(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//是否相同\nnow.isSame(now)`"/>{{now.isSame(now)}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`//是否相同\nnow.isSame(now.add(1, 'day'))`"/>{{now.isSame(now.add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`//是否之后\nnow.isAfter(now.add(1, 'day'))`"/>{{now.isAfter(now.add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`//是否之后\nnow.isAfter(now.subtract(1, 'day'))`"/>{{now.isAfter(now.subtract(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 是否之前\ndayjs().isBefore(dayjs().add(1, 'day'))`"/>{{dayjs().isBefore(dayjs().add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 是否之前\ndayjs().isBefore(dayjs().subtract(1, 'day'))`"/>{{dayjs().isBefore(dayjs().subtract(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 是否相同\ndayjs().isSame(dayjs())`"/>{{dayjs().isSame(dayjs())}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never" class="d2-mb"><d2-highlight slot="header" :code="`// 是否相同\ndayjs().isSame(dayjs().add(1, 'day'))`"/>{{dayjs().isSame(dayjs().add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`// 是否之后\ndayjs().isAfter(dayjs().add(1, 'day'))`"/>{{dayjs().isAfter(dayjs().add(1, 'day'))}}</el-card></el-col>
|
||||
<el-col :span="12"><el-card shadow="never"><d2-highlight slot="header" :code="`// 是否之后\ndayjs().isAfter(dayjs().subtract(1, 'day'))`"/>{{dayjs().isAfter(dayjs().subtract(1, 'day'))}}</el-card></el-col>
|
||||
</el-row>
|
||||
<template slot="footer">
|
||||
<d2-demo-link-btn title="依赖" :link="link"/>
|
||||
</template>
|
||||
<d2-demo-link-btn slot="footer" title="依赖" link="https://github.com/iamkun/dayjs"/>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
@@ -65,13 +66,7 @@ import dayjs from 'dayjs'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
link: 'https://github.com/iamkun/dayjs',
|
||||
now: dayjs()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleReset () {
|
||||
this.now = dayjs()
|
||||
dayjs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
76
src/plugin/vue-bigdata-table/components/button.vue
Executable file
76
src/plugin/vue-bigdata-table/components/button.vue
Executable file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<button class="v-bt-button" @click="handleClick">
|
||||
<span v-if="type === 'confirm'" class="i con-i"><i class="l con-i-l1 l1"></i><i class="l con-i-l2 l2"></i></span>
|
||||
<span v-else class="i can-i"><i class="l can-i-l1 l1"></i><i class="l can-i-l2 l2"></i></span>
|
||||
</button>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Button',
|
||||
props: {
|
||||
type: String
|
||||
},
|
||||
methods: {
|
||||
handleClick (e) {
|
||||
this.$emit('click', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import '../styles/common.less';
|
||||
.v-bt-button{
|
||||
padding: 2px 7px;
|
||||
width: 20px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
outline: none;
|
||||
transform: translateY(3px);
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
.l{
|
||||
background: @basic-blue;
|
||||
transition: background .2s ease;
|
||||
}
|
||||
}
|
||||
.i{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
i{
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
background: #000000;
|
||||
border-radius: 1px;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
.l{
|
||||
transition: background .2s ease;
|
||||
}
|
||||
.con-i{
|
||||
&-l1{
|
||||
width: 7px;
|
||||
transform: rotateZ(45deg) translate(3px, 0px);
|
||||
}
|
||||
&-l2{
|
||||
width: 10px;
|
||||
transform: rotateZ(-45deg) translate(5px, 4px);
|
||||
}
|
||||
}
|
||||
.can-i{
|
||||
&-l1{
|
||||
width: 12px;
|
||||
transform: rotateZ(45deg);
|
||||
}
|
||||
&-l2{
|
||||
width: 12px;
|
||||
transform: rotateZ(-45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
55
src/plugin/vue-bigdata-table/components/input-render.js
Executable file
55
src/plugin/vue-bigdata-table/components/input-render.js
Executable file
@@ -0,0 +1,55 @@
|
||||
import Input from './input.vue';
|
||||
import Button from './button.vue';
|
||||
export default (h, {row, col, value, beforeSave, initRowIndex}, table) => {
|
||||
return h('div', {
|
||||
'class': 'edit-item-con'
|
||||
}, [
|
||||
h(Input, {
|
||||
'class': 'edit-item-input',
|
||||
props: {
|
||||
value: value
|
||||
},
|
||||
on: {
|
||||
input (res) {
|
||||
table.editContent = res;
|
||||
}
|
||||
}
|
||||
}),
|
||||
h('div', {
|
||||
'class': 'edit-item-btn-con'
|
||||
}, [
|
||||
h(Button, {
|
||||
'class': 'edit-btn',
|
||||
props: {
|
||||
type: 'confirm'
|
||||
},
|
||||
on: {
|
||||
click () {
|
||||
const params = {
|
||||
row,
|
||||
col,
|
||||
value: table.editContent,
|
||||
initRowIndex
|
||||
};
|
||||
if (beforeSave({ row, col, value, initRowIndex })) {
|
||||
table.$emit('on-success-save', params);
|
||||
} else {
|
||||
table.$emit('on-fail-save', params);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
h(Button, {
|
||||
'class': 'edit-btn',
|
||||
props: {
|
||||
type: 'cancel'
|
||||
},
|
||||
on: {
|
||||
click () {
|
||||
table.$emit('on-cancel-edit');
|
||||
}
|
||||
}
|
||||
})
|
||||
])
|
||||
]);
|
||||
};
|
||||
46
src/plugin/vue-bigdata-table/components/input.vue
Executable file
46
src/plugin/vue-bigdata-table/components/input.vue
Executable file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<input class="v-bt-input" :value="value" @input="handleInput" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Input',
|
||||
props: {
|
||||
value: [String, Number]
|
||||
},
|
||||
methods: {
|
||||
handleInput (e) {
|
||||
this.$emit('input', e.target.value);
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$emit('input', this.value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import '../styles/common.less';
|
||||
.v-bt-input{
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 1.5;
|
||||
padding: 4px 7px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #dddee1;
|
||||
border-radius: 4px;
|
||||
color: #495060;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
position: relative;
|
||||
cursor: text;
|
||||
outline: none;
|
||||
transition: border .2s ease-in-out,background .2s ease-in-out,box-shadow .2s ease-in-out,-webkit-box-shadow .2s ease-in-out;
|
||||
&:hover{
|
||||
border-color: @basic-blue;
|
||||
}
|
||||
&:focus{
|
||||
border-color: @basic-blue;
|
||||
box-shadow: 0 0 0 2px rgba(45,140,240,.2)
|
||||
}
|
||||
}
|
||||
</style>
|
||||
209
src/plugin/vue-bigdata-table/components/item-table.vue
Executable file
209
src/plugin/vue-bigdata-table/components/item-table.vue
Executable file
@@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div class="v-bt-item-table">
|
||||
<table v-show="showTable && fixedCol >= 0" @paste="handlePaste" :class="['v-bt-data-table', 'v-bt-fixed-table', showFixedBoxShadow ? 'box-shadow' : '']" cellspacing="0" cellpadding="0" border="0">
|
||||
<colgroup>
|
||||
<col
|
||||
v-if="i <= fixedCol"
|
||||
:width="width" v-for="(width, i) in widthArr"
|
||||
:key="'colgroup-fixed-' + i"
|
||||
>
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(tr, index) in itemData"
|
||||
:key="index"
|
||||
:style="{background: currentMouseEnterIndex === index && canSelectText ? '#ebf7ff' : ''}"
|
||||
:class="[stripe && (indexBase + index) % 2 !== 0 ? 'stripe-gray' : '', tr.className, currentScrollToRowIndex === indexBase + index ? 'scroll-to-row-tip' : '']"
|
||||
@click="handleClickTr(indexBase + index)"
|
||||
@mouseenter.stop="handleMouseIn(index)"
|
||||
@mouseleave.stop="handleMouseLeave">
|
||||
<td v-if="showIndex" :class="['v-bt-cell', 'v-bt-data-table-center']">
|
||||
<render-dom :render="indexRender" :back-value="(indexBase + index)"></render-dom>
|
||||
</td>
|
||||
<td
|
||||
v-if="i <= fixedColCom"
|
||||
:data-row="indexBase + index"
|
||||
:data-col="i"
|
||||
@click="handleClickTd(indexBase + index, i)"
|
||||
@dblclick="handleDblclickTd(indexBase + index, i, typeof td === 'object' ? td.value : td)"
|
||||
v-for="(td, i) in tr"
|
||||
:class="['v-bt-cell',
|
||||
setAlign(i),
|
||||
typeof td === 'object' ? td.className : '',
|
||||
getSelectCellClasses(indexBase + index, i)
|
||||
]"
|
||||
:style="rowStyles" :key="i">
|
||||
<template v-if="!canEdit || (canEdit && `${indexBase + index}-${i}` !== edittingTd)">
|
||||
<div v-if="!showCellRender[showIndex ? (i + 1) : i]" class="v-bt-cell">{{ typeof td === 'object' ? td.value : td }}</div>
|
||||
<template v-else>
|
||||
<render-dom :render="showCellRender[showIndex ? (i + 1) : i]" :back-value="{row: indexBase + index, col: i}"></render-dom>
|
||||
</template>
|
||||
</template>
|
||||
<render-dom v-else :render="editCellRender" :back-value="{row: indexBase + index, col: i, value: typeof td === 'object' ? td.value : td, beforeSave}"></render-dom>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table v-show="showTable" @paste="handlePaste" ref="itemTable" class="v-bt-data-table v-bt-content-table" :style="{position: fixedCol < 0 ? '' : 'absolute'}" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<colgroup>
|
||||
<col
|
||||
:width="width" v-for="(width, i) in widthArr"
|
||||
:key="'colgroup-' + i"
|
||||
>
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(tr, index) in itemData"
|
||||
:key="index"
|
||||
@click="handleClickTr(indexBase + index)"
|
||||
@mouseenter.stop="handleMouseIn(index)"
|
||||
@mouseleave.stop="handleMouseLeave"
|
||||
:style="{background: currentMouseEnterIndex === index && canSelectText ? '#ebf7ff' : ''}"
|
||||
:class="[stripe && (indexBase + index) % 2 !== 0 ? 'stripe-gray' : '', tr.className, currentScrollToRowIndex === indexBase + index ? 'scroll-to-row-tip' : '']">
|
||||
<td v-if="showIndex" :class="['v-bt-cell', 'v-bt-data-table-center']">
|
||||
<render-dom v-if="fixedCol < 0" :render="indexRender" :back-value="(indexBase + index)"></render-dom>
|
||||
</td>
|
||||
<td
|
||||
v-for="(td, i) in tr"
|
||||
:data-row="indexBase + index"
|
||||
:data-col="i"
|
||||
@click="handleClickTd(indexBase + index, i)"
|
||||
@dblclick="handleDblclickTd(indexBase + index, i, typeof td === 'object' ? td.value : td)"
|
||||
:class="['v-bt-cell',
|
||||
setAlign(i),
|
||||
typeof td === 'object' ? td.className : '',
|
||||
getSelectCellClasses(indexBase + index, i)
|
||||
]"
|
||||
:style="rowStyles"
|
||||
:key="i">
|
||||
<template v-if="!canEdit || (canEdit && `${indexBase + index}-${i}` !== edittingTd)">
|
||||
<div v-if="(!showCellRender[showIndex ? (i + 1) : i]) && (i >= fixedCol)" class="v-bt-cell">{{ typeof td === 'object' ? td.value : td }}</div>
|
||||
<template v-else-if="i >= fixedCol">
|
||||
<render-dom :render="showCellRender[showIndex ? (i + 1) : i]" :back-value="{row: indexBase + index, col: i}"></render-dom>
|
||||
</template>
|
||||
</template>
|
||||
<render-dom v-else :render="editCellRender" :back-value="{row: indexBase + index, col: i, value: typeof td === 'object' ? td.value : td, beforeSave, initRowIndex: tr.initRowIndex}"></render-dom>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import renderDom from './renderDom';
|
||||
export default {
|
||||
name: 'ItemTable',
|
||||
components: {
|
||||
renderDom
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
prefix: 'v-bt-data-table',
|
||||
tableWidth: 0,
|
||||
currentMouseEnterIndex: -1,
|
||||
editInputValue: ''
|
||||
};
|
||||
},
|
||||
props: {
|
||||
times: Number,
|
||||
tableIndex: Number,
|
||||
itemData: Array,
|
||||
rowStyles: Object,
|
||||
widthArr: Array,
|
||||
columns: Array,
|
||||
itemNum: Number,
|
||||
showIndex: Boolean,
|
||||
indexRender: Function,
|
||||
stripe: Boolean,
|
||||
fixedCol: Number,
|
||||
currentScrollToRowIndex: Number,
|
||||
canEdit: Boolean,
|
||||
edittingTd: String,
|
||||
startEditType: String,
|
||||
showFixedBoxShadow: Boolean,
|
||||
editCellRender: Function,
|
||||
beforeSave: Function,
|
||||
canSelectText: Boolean,
|
||||
startSelect: Object,
|
||||
endSelect: Object,
|
||||
disabledHover: Boolean
|
||||
},
|
||||
computed: {
|
||||
showTable () {
|
||||
return this.itemData.length > 0;
|
||||
},
|
||||
indexBase () {
|
||||
return this.times * this.itemNum * 3 + this.itemNum * (this.tableIndex - 1);
|
||||
},
|
||||
showCellRender () {
|
||||
return this.columns.map(item => {
|
||||
return item.cellRender ? item.cellRender : undefined;
|
||||
});
|
||||
},
|
||||
baseIndex () {
|
||||
return this.showIndex ? 1 : 0;
|
||||
},
|
||||
fixedColCom () {
|
||||
return this.showIndex ? (this.fixedCol - 1) : this.fixedCol;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setAlign (i) {
|
||||
let columns = this.columns[i + this.baseIndex];
|
||||
if (!columns) return;
|
||||
let col = columns;
|
||||
return this.prefix + '-' + col.align;
|
||||
},
|
||||
backValue (row, col) {
|
||||
return {
|
||||
row: row,
|
||||
col: col
|
||||
};
|
||||
},
|
||||
handleMouseIn (index) {
|
||||
if (!this.disabledHover) return;
|
||||
this.currentMouseEnterIndex = index;
|
||||
},
|
||||
handleMouseLeave () {
|
||||
this.currentMouseEnterIndex = -1;
|
||||
},
|
||||
handleClickTr (index) {
|
||||
this.$emit('on-click-tr', index);
|
||||
},
|
||||
handleClickTd (row, col) {
|
||||
this.$emit('on-click-td', { row, col });
|
||||
},
|
||||
editCell (row, col) {
|
||||
this.$emit('on-edit-cell', row, col);
|
||||
},
|
||||
handleDblclickTd (row, col, value) {
|
||||
this.editInputValue = value;
|
||||
if (this.canEdit && this.startEditType === 'dblclick') this.editCell(row, col);
|
||||
},
|
||||
getSelectCellClasses (row, col) {
|
||||
let startSelect = this.startSelect;
|
||||
let endSelect = this.endSelect;
|
||||
let startRow = parseInt(startSelect['row']);
|
||||
let endRow = parseInt(endSelect['row']);
|
||||
let startCol = parseInt(startSelect['col']);
|
||||
return [
|
||||
((startRow === row) && startCol === col) ? 'start-select-cell' : '',
|
||||
((endRow === row) && endSelect['col'] === col) ? 'end-select-cell' : '',
|
||||
((startRow === row) && endSelect['col'] === col) ? 'right-top-select-cell' : '',
|
||||
((endRow === row) && startCol === col) ? 'left-bottom-select-cell' : '',
|
||||
((startRow === row) && col > startCol && col < endSelect['col']) ? 'top-center-select-cell' : '',
|
||||
((endRow === row) && col > startCol && col < endSelect['col']) ? 'bottom-center-select-cell' : '',
|
||||
(startCol === col && row > startRow && row < endRow) ? 'left-center-select-cell' : '',
|
||||
(endSelect['col'] === col && row > startRow && row < endRow) ? 'right-center-select-cell' : ''
|
||||
];
|
||||
},
|
||||
handlePaste (e) {
|
||||
const data = e.clipboardData.getData('text/plain');
|
||||
const rowsData = data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map((row) => {
|
||||
return row.split('\t');
|
||||
});
|
||||
this.$emit('on-paste', rowsData);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
11
src/plugin/vue-bigdata-table/components/renderDom.js
Executable file
11
src/plugin/vue-bigdata-table/components/renderDom.js
Executable file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
name: 'RenderCell',
|
||||
functional: true,
|
||||
props: {
|
||||
render: Function,
|
||||
backValue: [Number, Object]
|
||||
},
|
||||
render: (h, ctx) => {
|
||||
return ctx.props.render(h, ctx.props.backValue, ctx.parent);
|
||||
}
|
||||
};
|
||||
44
src/plugin/vue-bigdata-table/components/sort-button.vue
Executable file
44
src/plugin/vue-bigdata-table/components/sort-button.vue
Executable file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<span class="sort-button-wrapper" @click="handleSort">
|
||||
<i data-sort-btn="up" :class="[currentActiveColSort && currentSortType === 'up' ? 'sort-button-item-up-active' : '']" class="sort-button-item sort-button-item-up"></i>
|
||||
<i data-sort-btn="down" :class="[currentActiveColSort && currentSortType === 'down' ? 'sort-button-item-down-active' : '']" class="sort-button-item sort-button-item-down"></i>
|
||||
</span>
|
||||
</template>
|
||||
<script>
|
||||
import { attr } from '../util';
|
||||
export default {
|
||||
name: 'sortButton',
|
||||
data () {
|
||||
return {
|
||||
sortingType: ''
|
||||
};
|
||||
},
|
||||
props: {
|
||||
colIndex: Number,
|
||||
currentSortColIndex: Number,
|
||||
currentSortType: String
|
||||
},
|
||||
computed: {
|
||||
currentActiveColSort () {
|
||||
return this.colIndex === this.currentSortColIndex;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentSortType (type) {
|
||||
if (this.currentSortColIndex === this.colIndex) this.sortingType = type;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSort (e) {
|
||||
const sortType = attr(e.target, 'data-sort-btn');
|
||||
if (this.sortingType === sortType) {
|
||||
this.sortingType = '';
|
||||
this.$emit('on-cancel-sort');
|
||||
} else {
|
||||
this.sortingType = sortType;
|
||||
this.$emit('on-sort', this.colIndex, sortType);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
8
src/plugin/vue-bigdata-table/index.js
Executable file
8
src/plugin/vue-bigdata-table/index.js
Executable file
@@ -0,0 +1,8 @@
|
||||
import bigdataTable from './vue-bigdata-table.vue';
|
||||
const install = (Vue, opts = {}) => {
|
||||
Vue.component('bigdataTable', bigdataTable);
|
||||
};
|
||||
if (typeof window !== 'undefined' && window.Vue) {
|
||||
install(window.Vue);
|
||||
}
|
||||
export default Object.assign(bigdataTable, {install});
|
||||
199
src/plugin/vue-bigdata-table/mixins/data-handle.js
Executable file
199
src/plugin/vue-bigdata-table/mixins/data-handle.js
Executable file
@@ -0,0 +1,199 @@
|
||||
import ItemTable from '../components/item-table.vue';
|
||||
import { iteratorByTimes, getHeaderWords } from '../util';
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
times0: 0, // 当前是第几轮
|
||||
times1: 0,
|
||||
times2: -1,
|
||||
table1Data: [],
|
||||
table2Data: [],
|
||||
table3Data: [],
|
||||
currentIndex: 0, // 当前展示的表格是第几个
|
||||
itemNum: 0, // 一块数据显示的数据条数
|
||||
timer: null,
|
||||
scrollLeft: 0,
|
||||
insideTableData: [],
|
||||
initTableData: [] // 初始表格数据,用于恢复搜索和筛选
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
cellNum () { // 表格列数
|
||||
return this.columnsHandled.length;
|
||||
},
|
||||
columnsHandled () {
|
||||
let columns = [...this.columns];
|
||||
if (this.colNum > this.columns.length) {
|
||||
let colLength = this.colNum - this.columns.length;
|
||||
let headerWordsArr = getHeaderWords(colLength);
|
||||
iteratorByTimes(colLength, (i) => {
|
||||
columns.push({
|
||||
title: headerWordsArr[i]
|
||||
});
|
||||
});
|
||||
}
|
||||
if (this.showIndex) {
|
||||
columns.unshift({
|
||||
title: 'No',
|
||||
align: 'center',
|
||||
width: this.indexWidthInside
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
scrollTop (top) {
|
||||
this.currentIndex = parseInt((top % (this.moduleHeight * 3)) / this.moduleHeight);
|
||||
this.$nextTick(() => {
|
||||
this.setTopPlace();
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getComputedTableDataIndex (colIndex) {
|
||||
return this.showIndex ? (colIndex - 1) : colIndex;
|
||||
},
|
||||
handleScroll (e) {
|
||||
const ele = e.srcElement || e.target;
|
||||
const { scrollTop, scrollLeft } = ele;
|
||||
this.scrollLeft = scrollLeft;
|
||||
this.scrollTop = scrollTop;
|
||||
},
|
||||
setTableData () {
|
||||
const count1 = this.times0 * this.itemNum * 3;
|
||||
this.table1Data = this.insideTableData.slice(count1, count1 + this.itemNum);
|
||||
const count2 = this.times1 * this.itemNum * 3;
|
||||
this.table2Data = this.insideTableData.slice(count2 + this.itemNum, count2 + this.itemNum * 2);
|
||||
const count3 = this.times2 * this.itemNum * 3;
|
||||
this.table3Data = this.insideTableData.slice(count3 + this.itemNum * 2, count3 + this.itemNum * 3);
|
||||
},
|
||||
getTables (h) {
|
||||
let table1 = this.getItemTable(h, this.table1Data, 1);
|
||||
let table2 = this.getItemTable(h, this.table2Data, 2);
|
||||
let table3 = this.getItemTable(h, this.table3Data, 3);
|
||||
if (this.currentIndex === 0) return [table1, table2, table3];
|
||||
else if (this.currentIndex === 1) return [table2, table3, table1];
|
||||
else return [table3, table1, table2];
|
||||
},
|
||||
renderTable (h) {
|
||||
return h('div', {
|
||||
style: this.tableWidthStyles
|
||||
}, this.getTables(h));
|
||||
},
|
||||
getItemTable (h, data, index) {
|
||||
return h(ItemTable, {
|
||||
props: {
|
||||
times: this['times' + (index - 1)],
|
||||
tableIndex: index,
|
||||
itemData: data,
|
||||
itemNum: this.itemNum,
|
||||
rowStyles: this.rowStyles,
|
||||
widthArr: this.colWidthArr,
|
||||
columns: this.columnsHandled,
|
||||
showIndex: this.showIndex,
|
||||
indexRender: this.indexRender,
|
||||
stripe: this.stripe,
|
||||
fixedCol: this.fixedCol,
|
||||
currentScrollToRowIndex: this.currentScrollToRowIndex,
|
||||
canEdit: this.canEdit,
|
||||
edittingTd: this.edittingTd,
|
||||
startEditType: this.startEditType,
|
||||
showFixedBoxShadow: this.showFixedBoxShadow,
|
||||
editCellRender: this.editCellRender,
|
||||
beforeSave: this.beforeSave,
|
||||
canSelectText: this.canSelectText,
|
||||
startSelect: this.startSelect,
|
||||
endSelect: this.endSelect,
|
||||
disabledHover: this.disabledHover
|
||||
},
|
||||
on: {
|
||||
'on-click-tr': (index) => {
|
||||
this.$emit('on-click-tr', index);
|
||||
},
|
||||
'on-click-td': (params) => {
|
||||
this.$emit('on-click-td', params);
|
||||
},
|
||||
'on-edit-cell': (row, col) => {
|
||||
this.edittingTd = `${row}-${col}`;
|
||||
},
|
||||
'on-success-save': ({ row, col, value, initRowIndex }) => {
|
||||
let data = [...this.value];
|
||||
data[initRowIndex][col] = value;
|
||||
this.$emit('input', data);
|
||||
this.$emit('on-success-save', { row, col, value, initRowIndex });
|
||||
this.edittingTd = '';
|
||||
},
|
||||
'on-fail-save': ({ row, col, value, initRowIndex }) => {
|
||||
this.$emit('on-fail-save', { row, col, value, initRowIndex });
|
||||
},
|
||||
'on-cancel-edit': () => {
|
||||
this.edittingTd = '';
|
||||
},
|
||||
'on-paste': (data) => {
|
||||
if (!this.paste) return;
|
||||
let value = [...this.value];
|
||||
let rowLength = data.length;
|
||||
let startSelect = this.startSelect;
|
||||
let endSelect = this.endSelect;
|
||||
let startRow = startSelect.row;
|
||||
let startCol = startSelect.col;
|
||||
let endRow = endSelect.row;
|
||||
let endCol = endSelect.col;
|
||||
let selectRow = endRow - startRow + 1;
|
||||
let selectCol = endCol - startCol + 1;
|
||||
// let lastColLength = value[0].length - startCol;
|
||||
// let lastRowLength = value.length - startRow;
|
||||
if (rowLength === 0) return;
|
||||
let colLength = data[0].length;
|
||||
if (colLength === 0) return;
|
||||
// 使用复制的数据替换原数据
|
||||
for (let r = 0; r < rowLength && r < selectRow; r++) {
|
||||
for (let c = 0; c < colLength && c < selectCol; c++) {
|
||||
let valueRow = startRow + r;
|
||||
let valueCol = startCol + c;
|
||||
if (typeof value[valueRow][valueCol] === 'object') {
|
||||
value[valueRow][valueCol].value = data[r][c];
|
||||
} else {
|
||||
value[valueRow][valueCol] = data[r][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (let r = startRow; r < selectRow; r++) {
|
||||
// for (let c = startCol; c < selectCol; c++) {
|
||||
// //
|
||||
// }
|
||||
// }
|
||||
this.$emit('input', value);
|
||||
this.$emit('on-paste', data);
|
||||
this._tableResize();
|
||||
}
|
||||
},
|
||||
key: 'table-item-key' + index,
|
||||
ref: 'itemTable' + index,
|
||||
attrs: {
|
||||
'data-index': index
|
||||
}
|
||||
});
|
||||
},
|
||||
_scrollToIndexRow (index) {
|
||||
index = parseInt(index);
|
||||
if (isNaN(index) || index >= this.insideTableData.length || index < 0) return;
|
||||
let scrollTop = index * this.itemRowHeight;
|
||||
this.$refs.outer.scrollTop = scrollTop;
|
||||
this.currentScrollToRowIndex = index;
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.currentScrollToRowIndex = -1;
|
||||
}, 1800);
|
||||
},
|
||||
// 给表格数据添加行号,用于排序后正确修改数据
|
||||
setIndex (tableData) {
|
||||
return tableData.map((item, i) => {
|
||||
let row = item;
|
||||
row.initRowIndex = i;
|
||||
return row;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
77
src/plugin/vue-bigdata-table/mixins/edit.js
Executable file
77
src/plugin/vue-bigdata-table/mixins/edit.js
Executable file
@@ -0,0 +1,77 @@
|
||||
import { findNodeUpper, on, off, attr } from '../util';
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
edittingTd: '', // 正在编辑的单元格的行号和列号拼接的字符串 `${row}-${col}`
|
||||
editContent: '', // 用来保存编辑的内容
|
||||
selectCellsStart: {}, // 编辑模式下可选中多行多列,此用来保存其实单元格行列号
|
||||
selectCellsEnd: {},
|
||||
selectTotalColStartIndex: -1, // 选取整列起始序列号
|
||||
selectTotalColEndIndex: -1
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startSelect () {
|
||||
return {
|
||||
row: Math.min(this.selectCellsStart.row, this.selectCellsEnd.row),
|
||||
col: Math.min(this.selectCellsStart.col, this.selectCellsEnd.col)
|
||||
};
|
||||
},
|
||||
endSelect () {
|
||||
return {
|
||||
row: Math.max(this.selectCellsStart.row, this.selectCellsEnd.row),
|
||||
col: Math.max(this.selectCellsStart.col, this.selectCellsEnd.col)
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
_editCell (row, col) {
|
||||
if (!this.canEdit || row < 0 || row > this.insideTableData.length || col < 0 || col > this.columns.length || this.edittingTd === `${row}-${col}`) return;
|
||||
if (parseInt(this.edittingTd.split('-')[0]) !== row) this.scrollToRow(row);
|
||||
this.edittingTd = `${row}-${col}`;
|
||||
},
|
||||
getCurrentTd (e) {
|
||||
return e.target.tagName === 'TD' ? e.target : findNodeUpper(e.target, 'td');
|
||||
},
|
||||
handleMousedownOnTable (e) {
|
||||
if (e.button !== 0 || (!this.paste && !this.selectable)) return;
|
||||
let currentTd = this.getCurrentTd(e);
|
||||
this.selectCellsStart = {
|
||||
row: attr(currentTd, 'data-row'),
|
||||
col: attr(currentTd, 'data-col')
|
||||
};
|
||||
this.selectCellsEnd = {
|
||||
row: attr(currentTd, 'data-row'),
|
||||
col: attr(currentTd, 'data-col')
|
||||
};
|
||||
this.canSelectText = false;
|
||||
on(document, 'mousemove', this.handleMoveOnTable);
|
||||
on(document, 'mouseup', this.handleUpOnTable);
|
||||
},
|
||||
handleMoveOnTable (e) {
|
||||
if (!(e.target.tagName === 'TD' || findNodeUpper(e.target, 'td'))) return;
|
||||
let currentTd = this.getCurrentTd(e);
|
||||
this.selectCellsEnd = {
|
||||
row: attr(currentTd, 'data-row'),
|
||||
col: attr(currentTd, 'data-col')
|
||||
};
|
||||
},
|
||||
handleUpOnTable (e) {
|
||||
if (!this.paste && !this.selectable) return;
|
||||
this.canSelectText = true;
|
||||
this.handleMoveOnTable(e);
|
||||
off(document, 'mousemove', this.handleMoveOnTable);
|
||||
off(document, 'mouseup', this.handleUpOnTable);
|
||||
this.$emit('on-select-cells', {
|
||||
start: {
|
||||
row: this.startSelect.row,
|
||||
col: this.startSelect.col
|
||||
},
|
||||
end: {
|
||||
row: this.endSelect.row,
|
||||
col: this.endSelect.col
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
31
src/plugin/vue-bigdata-table/mixins/empty-table.js
Executable file
31
src/plugin/vue-bigdata-table/mixins/empty-table.js
Executable file
@@ -0,0 +1,31 @@
|
||||
export default {
|
||||
methods: {
|
||||
_createEmptyData () {
|
||||
// this.$nextTick(() => {
|
||||
let rowNum = this.rowNum;
|
||||
let colNum = this.colNum;
|
||||
if (this.rowNum && this.colNum) {
|
||||
console.log(this.value.length, this.rowNum, this.colNum);
|
||||
let valueRowNum = this.value.length;
|
||||
let valueColNum = this.value[0] ? this.value[0].length : 0;
|
||||
let totalRowNum = valueRowNum + rowNum;
|
||||
let totalColNum = valueColNum + colNum;
|
||||
let value = [...this.value];
|
||||
console.log(totalRowNum, valueRowNum);
|
||||
for (let r = valueRowNum; r < totalRowNum; r++) {
|
||||
value.push([]);
|
||||
for (let c = valueColNum; c < totalColNum; c++) {
|
||||
value[r].push('');
|
||||
}
|
||||
}
|
||||
// this.
|
||||
console.log(value);
|
||||
this.$emit('input', value);
|
||||
// this.$nextTick(() => {
|
||||
// this._tableResize();
|
||||
// })
|
||||
}
|
||||
// });
|
||||
}
|
||||
}
|
||||
};
|
||||
64
src/plugin/vue-bigdata-table/mixins/header-move.js
Executable file
64
src/plugin/vue-bigdata-table/mixins/header-move.js
Executable file
@@ -0,0 +1,64 @@
|
||||
import { findNodeUpper, attr } from '../util';
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
isOnCellEdge: false, // 鼠标是否在表头的两个单元格之间的边框上
|
||||
canResizeCell: false,
|
||||
initCellX: 0, // 用于计算鼠标移动的距离
|
||||
scrollLeft: 0,
|
||||
colIndex: 0, // 在表头上移动时鼠标所在列的序号,
|
||||
atLeftGivenArea: false, // 是否在表头单元格指定区域(距左侧)
|
||||
atRightGivenArea: false // 是否在表头单元格指定区域(距右侧)
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleMousemove (e) {
|
||||
let cell = e.srcElement.tagName.toUpperCase() === 'TH' ? e.srcElement : findNodeUpper(e.srcElement, 'th');
|
||||
let cellDomRect = cell.getBoundingClientRect();
|
||||
let atLeft = (e.pageX - cellDomRect.left) < (cellDomRect.width / 2);
|
||||
let atLeftGivenArea = (cellDomRect.left + this.atLeftCellPosi) >= e.pageX;
|
||||
let atRightGivenArea = (cellDomRect.right - e.pageX) <= this.atRightCellPosi;
|
||||
let cellIndex = parseInt(attr(cell, 'data-index')); // 当前单元格的序号
|
||||
if (atLeft && cellIndex !== 0) {
|
||||
this.isOnCellEdge = (e.pageX - cellDomRect.left) <= 1 && cellIndex - 1 !== this.fixedCol;
|
||||
} else if (!atLeft && cellIndex !== this.cellNum - 1) {
|
||||
this.isOnCellEdge = (cellDomRect.right - e.pageX) <= 1 && cellIndex !== this.fixedCol;
|
||||
}
|
||||
e.atRightGivenArea = atRightGivenArea;
|
||||
e.atLeftGivenArea = atLeftGivenArea;
|
||||
this.atRightGivenArea = atRightGivenArea;
|
||||
this.atLeftGivenArea = atLeftGivenArea;
|
||||
let index = 0; // 调整表格列宽的左侧的表格的序列
|
||||
e.colIndex = cellIndex;
|
||||
this.colIndex = cellIndex;
|
||||
this.$emit('on-moving-on-header', e);
|
||||
if (this.canResizeCell) {
|
||||
if (atLeft) {
|
||||
index = cellIndex - 1;
|
||||
} else {
|
||||
index = cellIndex;
|
||||
}
|
||||
if (index === this.fixedCol) return;
|
||||
let widthLeft = this.widthArr[index] + e.pageX - this.initCellX;
|
||||
let widthRight = this.widthArr[index + 1] + this.initCellX - e.pageX;
|
||||
this.widthArr.splice(index, 2, widthLeft, widthRight);
|
||||
this.initCellX = e.pageX;
|
||||
}
|
||||
},
|
||||
handleMousedown (e) {
|
||||
e.colIndex = this.cellIndex;
|
||||
this.$emit('on-mousedown-on-header', e);
|
||||
if (this.isOnCellEdge) {
|
||||
this.canResizeCell = true;
|
||||
this.initCellX = e.pageX;
|
||||
}
|
||||
},
|
||||
canNotMove (e) {
|
||||
this.canResizeCell = false;
|
||||
e.colIndex = this.colIndex;
|
||||
e.atLeftGivenArea = this.atLeftGivenArea;
|
||||
e.atRightGivenArea = this.atRightGivenArea;
|
||||
this.$emit('on-mouseup-on-header', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
8
src/plugin/vue-bigdata-table/mixins/index.js
Executable file
8
src/plugin/vue-bigdata-table/mixins/index.js
Executable file
@@ -0,0 +1,8 @@
|
||||
import headerMove from './header-move';
|
||||
import styleComputed from './style-compute';
|
||||
import dataHandle from './data-handle';
|
||||
import edit from './edit';
|
||||
import emptyTable from './empty-table';
|
||||
import sort from './sort';
|
||||
|
||||
export default [ headerMove, styleComputed, dataHandle, edit, emptyTable, sort ];
|
||||
40
src/plugin/vue-bigdata-table/mixins/sort.js
Executable file
40
src/plugin/vue-bigdata-table/mixins/sort.js
Executable file
@@ -0,0 +1,40 @@
|
||||
import { sortArr, sortDesArr } from '../util';
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
sortedByColIndex: -1,
|
||||
sortedType: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showSortBtn (colIndex) {
|
||||
const sortable = this.sortable ? true : this.sortIndex !== undefined;
|
||||
return (sortable && !(this.showIndex && colIndex === 0) && (typeof this.sortIndex === 'number' ? colIndex <= this.sortIndex : this.sortIndex.indexOf(colIndex) >= 0)) || this.columnsHandled[colIndex].sortable;
|
||||
},
|
||||
handleSort (colIndex, sortType) {
|
||||
this.sortedByColIndex = colIndex;
|
||||
this.sortedType = sortType;
|
||||
let valueArr = [...this.value];
|
||||
colIndex = this.showIndex ? colIndex - 1 : colIndex;
|
||||
if (sortType === 'up') {
|
||||
sortArr(valueArr, colIndex);
|
||||
} else {
|
||||
sortDesArr(valueArr, colIndex);
|
||||
}
|
||||
this.insideTableData = [...valueArr];
|
||||
},
|
||||
handleCancelSort () {
|
||||
this.sortedByColIndex = -1;
|
||||
this.sortedType = '';
|
||||
this.insideTableData = [...this.value];
|
||||
},
|
||||
initSort () {
|
||||
if (this.defaultSort) {
|
||||
const colIndex = parseInt(Object.keys(this.defaultSort)[0]);
|
||||
if (!(colIndex || colIndex === 0)) return;
|
||||
const sortType = this.defaultSort[colIndex];
|
||||
this.handleSort(colIndex, sortType);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
177
src/plugin/vue-bigdata-table/mixins/style-compute.js
Executable file
177
src/plugin/vue-bigdata-table/mixins/style-compute.js
Executable file
@@ -0,0 +1,177 @@
|
||||
import { getScrollbarWidth } from '../util';
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
wrapperHeight: 0,
|
||||
scrollTop: 0,
|
||||
moduleHeight: 0, // 三个tr块中的一块的高度
|
||||
topPlaceholderHeight: 0, // 顶部占位容器高度
|
||||
tableWidth: 0,
|
||||
widthArr: [], // 用于给数据表格传递列宽
|
||||
totalRowHeight: 0, // 如果全量渲染应该是多高,用于计算占位
|
||||
currentScrollToRowIndex: -1, // 当前跳转到的行号,用于做闪烁提示
|
||||
canSelectText: true, // 用于控制是否可选中表格文字
|
||||
indexWidthInside: 0,
|
||||
outerWidth: 0, // 外面容器宽度
|
||||
oldTableWidth: 0 // 旧的表格宽度,用于重新计算列宽
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
fixedColCom () {
|
||||
return this.showIndex ? (this.fixedCol + 1) : this.fixedCol;
|
||||
},
|
||||
wrapperClasses () {
|
||||
return [
|
||||
this.prefix,
|
||||
this.fixed ? `${this.prefix}-fixed` : ''
|
||||
];
|
||||
},
|
||||
headerStyle () {
|
||||
return {
|
||||
height: this.headerHeight + 'px',
|
||||
transform: 'translateX(0)'
|
||||
};
|
||||
},
|
||||
showFixedBoxShadow () {
|
||||
return this.scrollLeft !== 0;
|
||||
},
|
||||
tableWidthStyles () {
|
||||
return {width: this.tableWidth + 'px'};
|
||||
},
|
||||
rowStyles () {
|
||||
return this.rowHeight !== undefined ? {height: `${this.rowHeight}px`} : {};
|
||||
},
|
||||
placeholderHeight () {
|
||||
return this.totalRowHeight - this.moduleHeight * 3; // 占位容器的总高度(上 + 下)
|
||||
},
|
||||
bottomPlaceholderHeight () {
|
||||
return (this.placeholderHeight - this.topPlaceholderHeight) < 0 ? 0 : this.placeholderHeight - this.topPlaceholderHeight;
|
||||
},
|
||||
itemRowHeight () {
|
||||
return this.rowHeight === undefined ? 48 : this.rowHeight;
|
||||
},
|
||||
colWidthArr () {
|
||||
let len = this.cellNum;
|
||||
let colWidthArr = [];
|
||||
if (this.fixedWrapperWidth) {
|
||||
let width = this.outerWidth;
|
||||
let num = this.cellNum;
|
||||
if (this.showIndex) {
|
||||
colWidthArr.push(this.indexWidth);
|
||||
width -= this.indexWidth;
|
||||
num -= 1;
|
||||
}
|
||||
let i = -1;
|
||||
let itemColWidth = width / num;
|
||||
while (++i < num) {
|
||||
colWidthArr.push(itemColWidth);
|
||||
}
|
||||
} else {
|
||||
let i = 0;
|
||||
let hasWidthCellCount = 0; // 统计设置了width的列的数量,从而为没有设置width的列分配宽度
|
||||
let noWidthCellIndexArr = []; // 没有设置宽度的列的序列
|
||||
let hasWidthCellTotalWidth = 0; // 设置了width的列一共多宽
|
||||
while (i < len) {
|
||||
if (this.columnsHandled[i].width) {
|
||||
hasWidthCellCount++;
|
||||
hasWidthCellTotalWidth += this.columnsHandled[i].width;
|
||||
colWidthArr.push(this.columnsHandled[i].width);
|
||||
} else {
|
||||
noWidthCellIndexArr.push(i);
|
||||
colWidthArr.push(0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
let noWidthCellWidth = (this.tableWidth - hasWidthCellTotalWidth) / (len - hasWidthCellCount);
|
||||
let w = 0;
|
||||
let indexArrLen = noWidthCellIndexArr.length;
|
||||
while (w < indexArrLen) {
|
||||
colWidthArr[noWidthCellIndexArr[w]] = noWidthCellWidth;
|
||||
w++;
|
||||
}
|
||||
// this.widthArr = colWidthArr;
|
||||
}
|
||||
return colWidthArr;
|
||||
},
|
||||
cursorOnHeader () {
|
||||
return this.headerTrStyle.cursor ? this.headerTrStyle.cursor : ((this.isOnCellEdge || this.canResizeCell) ? 'col-resize' : 'default');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
_tableResize () {
|
||||
this.$nextTick(() => {
|
||||
this.updateHeight();
|
||||
this.setComputedProps();
|
||||
let scrollBarWidth = this.totalRowHeight > this.wrapperHeight ? getScrollbarWidth() : 0;
|
||||
this.outerWidth = this.$refs.outer.offsetWidth - 2 - scrollBarWidth;
|
||||
let width = this.colWidth * this.columns.length + (this.showIndex ? this.indexWidthInside : 0);
|
||||
// this.tableWidth = width > this.outerWidth ? width : this.outerWidth;
|
||||
this.tableWidth = this.fixedWrapperWidth ? this.outerWidth : (width > this.outerWidth ? width : this.outerWidth);
|
||||
if (width < this.outerWidth) this._setColWidthArr();
|
||||
this.widthArr = this.colWidthArr;
|
||||
});
|
||||
},
|
||||
updateHeight () {
|
||||
this.$nextTick(() => {
|
||||
let wrapperHeight = this.$refs.outer.offsetHeight;
|
||||
this.itemNum = Math.ceil((wrapperHeight - this.headerHeight) / this.itemRowHeight) + this.appendNum;
|
||||
this.moduleHeight = this.itemNum * this.itemRowHeight;
|
||||
this.wrapperHeight = wrapperHeight;
|
||||
this.setTopPlace();
|
||||
});
|
||||
},
|
||||
setComputedProps () {
|
||||
const len = this.insideTableData.length;
|
||||
this.totalRowHeight = len * this.itemRowHeight;
|
||||
},
|
||||
setIndexWidth (len) {
|
||||
let width = 70;
|
||||
if (len <= 99) {
|
||||
width = 50;
|
||||
} else if (len > 99 && len <= 1000) {
|
||||
width = 60;
|
||||
} else if (len > 1000 && len <= 10000) {
|
||||
width = 70;
|
||||
} else if (len > 10000 && len <= 100000) {
|
||||
width = 90;
|
||||
} else {
|
||||
width = 100;
|
||||
}
|
||||
return width;
|
||||
},
|
||||
setTopPlace () {
|
||||
let scrollTop = this.scrollTop;
|
||||
let t0 = 0;
|
||||
let t1 = 0;
|
||||
let t2 = 0;
|
||||
if (scrollTop > this.moduleHeight) {
|
||||
switch (this.currentIndex) {
|
||||
case 0: t0 = parseInt(scrollTop / (this.moduleHeight * 3)); t1 = t2 = t0; break;
|
||||
case 1: t1 = parseInt((scrollTop - this.moduleHeight) / (this.moduleHeight * 3)); t0 = t1 + 1; t2 = t1; break;
|
||||
case 2: t2 = parseInt((scrollTop - this.moduleHeight * 2) / (this.moduleHeight * 3)); t0 = t1 = t2 + 1;
|
||||
}
|
||||
}
|
||||
this.times0 = t0;
|
||||
this.times1 = t1;
|
||||
this.times2 = t2;
|
||||
this.topPlaceholderHeight = parseInt(scrollTop / this.moduleHeight) * this.moduleHeight;
|
||||
this.setTableData();
|
||||
},
|
||||
_initM () {
|
||||
if (this.indexWidth === undefined) this.indexWidthInside = this.setIndexWidth(this.insideTableData.length);
|
||||
else this.indexWidthInside = this.indexWidth;
|
||||
this.oldTableWidth = this.colWidthArr.reduce((sum, b) => {
|
||||
return sum + b;
|
||||
}, 0);
|
||||
this.widthArr = this.colWidthArr;
|
||||
if ((this.colWidth * this.columns.length + (this.showIndex ? this.indexWidthInside : 0)) < this.outerWidth) this._setColWidthArr();
|
||||
},
|
||||
_setColWidthArr () {
|
||||
let widthArr = this.widthArr.map(width => {
|
||||
return width / this.oldTableWidth * this.tableWidth;
|
||||
});
|
||||
this.oldTableWidth = this.tableWidth;
|
||||
this.widthArr = widthArr;
|
||||
}
|
||||
}
|
||||
};
|
||||
29
src/plugin/vue-bigdata-table/styles/common.less
Executable file
29
src/plugin/vue-bigdata-table/styles/common.less
Executable file
@@ -0,0 +1,29 @@
|
||||
@basic-blue: #3695FE;
|
||||
@border-color: #e9eaec;
|
||||
@sort-border-width: 4px;
|
||||
@sort-border-default: #bbbec4;
|
||||
@sort-border-hover: #495060;
|
||||
@sort-border-active: @basic-blue;
|
||||
// 超出用省略号代替
|
||||
.text-ellipsis{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
// 选择单元格表格
|
||||
.select-border (@direction) {
|
||||
border-@{direction}: 1px solid @basic-blue;
|
||||
}
|
||||
.no-select{
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.sticky{
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
232
src/plugin/vue-bigdata-table/styles/vue-bigdata-table.less
Executable file
232
src/plugin/vue-bigdata-table/styles/vue-bigdata-table.less
Executable file
@@ -0,0 +1,232 @@
|
||||
@import './common.less';
|
||||
@prefix: ~"v-bt";
|
||||
@keyframes scroll-tip {
|
||||
0% {
|
||||
background: #fff;
|
||||
}
|
||||
50% {
|
||||
background: #d0e8ff;
|
||||
}
|
||||
}
|
||||
|
||||
.@{prefix} {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
* {
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
color: #495060;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
&-outer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
border: 1px solid @border-color;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.@{prefix}-header-wrapper {
|
||||
box-sizing: border-box;
|
||||
z-index: 70;
|
||||
&.header-wrapper-fixed {
|
||||
.sticky;
|
||||
}
|
||||
table {
|
||||
table-layout: fixed;
|
||||
height: 100%;
|
||||
tr th {
|
||||
border-right: 1px solid @border-color;
|
||||
border-bottom: 1px solid @border-color;
|
||||
background: #fff;
|
||||
.text-ellipsis;
|
||||
.@{prefix}-header-inside-wrapper {
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-fixed-header {
|
||||
.sticky;
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
z-index: 110;
|
||||
transition: box-shadow .2s ease;
|
||||
&.box-shadow {
|
||||
box-shadow: 2px 0 6px -2px rgba(0, 0, 0, .2);
|
||||
transition: box-shadow .2s ease;
|
||||
}
|
||||
}
|
||||
&-wrapper {
|
||||
width: 100%;
|
||||
border-bottom: none;
|
||||
.@{prefix}-content {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
&.noselect-text {
|
||||
.no-select;
|
||||
}
|
||||
}
|
||||
&:nth-child(2) {
|
||||
border-top: 1px solid @border-color;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
border-bottom: 1px solid @border-color;
|
||||
}
|
||||
.@{prefix}-data-table {
|
||||
&.@{prefix}-content-table {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
table-layout: fixed;
|
||||
tr {
|
||||
background: #fff;
|
||||
&.scroll-to-row-tip {
|
||||
animation: scroll-tip .6s 3;
|
||||
}
|
||||
td{
|
||||
min-width: 0;
|
||||
height: 48px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
border-bottom: 1px solid @border-color;
|
||||
border-right: 1px solid @border-color;
|
||||
border-left: 1px solid transparent;
|
||||
border-top: 1px solid transparent; // 表格选中
|
||||
.@{prefix}-cell {
|
||||
box-sizing: border-box;
|
||||
padding: 0 18px;
|
||||
.text-ellipsis;
|
||||
}
|
||||
.edit-item-con {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 0 6px;
|
||||
box-sizing: border-box;
|
||||
.edit-item {
|
||||
&-input {
|
||||
width: ~"calc(100% - 50px)";
|
||||
float: left;
|
||||
}
|
||||
&-btn-con {
|
||||
float: left;
|
||||
.edit-btn {
|
||||
width: 20px;
|
||||
margin: 7px 4px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.start-select-cell {
|
||||
.select-border(left);
|
||||
.select-border(top);
|
||||
}
|
||||
&.end-select-cell {
|
||||
.select-border(right);
|
||||
.select-border(bottom);
|
||||
}
|
||||
&.right-top-select-cell {
|
||||
.select-border(right);
|
||||
.select-border(top);
|
||||
}
|
||||
&.left-bottom-select-cell {
|
||||
.select-border(left);
|
||||
.select-border(bottom);
|
||||
}
|
||||
&.top-center-select-cell {
|
||||
.select-border(top);
|
||||
}
|
||||
&.bottom-center-select-cell {
|
||||
.select-border(bottom);
|
||||
}
|
||||
&.left-center-select-cell {
|
||||
.select-border(left);
|
||||
}
|
||||
&.right-center-select-cell {
|
||||
.select-border(right);
|
||||
}
|
||||
}
|
||||
&.stripe-gray {
|
||||
background: #f8f8f9;
|
||||
}
|
||||
}
|
||||
&-left {
|
||||
text-align: left;
|
||||
}
|
||||
&-center {
|
||||
text-align: center;
|
||||
}
|
||||
&-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-fixed {
|
||||
.@{prefix}-header-wrapper {
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
&-fixed-table {
|
||||
.sticky;
|
||||
left: 0;
|
||||
z-index: 60;
|
||||
transition: box-shadow .2s ease;
|
||||
&.box-shadow {
|
||||
box-shadow: 2px 0 6px -2px rgba(0, 0, 0, .2);
|
||||
transition: box-shadow .2s ease;
|
||||
}
|
||||
td {
|
||||
border-right: 1px solid @border-color;
|
||||
}
|
||||
}
|
||||
&-item-table {
|
||||
position: relative;
|
||||
}
|
||||
.sort-button {
|
||||
&-wrapper {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 10px;
|
||||
height: 11px;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
&-item {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: @sort-border-width solid transparent;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: border-color .2s ease;
|
||||
&-up {
|
||||
top: -4px;
|
||||
border-bottom: @sort-border-width solid @sort-border-default;
|
||||
&:hover {
|
||||
border-bottom: @sort-border-width solid @sort-border-hover;
|
||||
}
|
||||
&-active {
|
||||
border-bottom: @sort-border-width solid @sort-border-active;
|
||||
}
|
||||
}
|
||||
&-down {
|
||||
bottom: -4px;
|
||||
border-top: @sort-border-width solid @sort-border-default;
|
||||
&:hover {
|
||||
border-top: @sort-border-width solid @sort-border-hover;
|
||||
}
|
||||
&-active {
|
||||
border-top: @sort-border-width solid @sort-border-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
136
src/plugin/vue-bigdata-table/util/index.js
Executable file
136
src/plugin/vue-bigdata-table/util/index.js
Executable file
@@ -0,0 +1,136 @@
|
||||
export const findNodeUpper = (ele, tag) => {
|
||||
if (ele.parentNode) {
|
||||
if (ele.parentNode.tagName === tag.toUpperCase()) {
|
||||
return ele.parentNode;
|
||||
} else {
|
||||
if (ele.parentNode) return findNodeUpper(ele.parentNode, tag);
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const getScrollbarWidth = () => {
|
||||
let oP = document.createElement('p');
|
||||
let styles = {
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
overflowY: 'scroll'
|
||||
};
|
||||
for (let i in styles) {
|
||||
oP.style[i] = styles[i];
|
||||
}
|
||||
document.body.appendChild(oP);
|
||||
let scrollbarWidth = oP.offsetWidth - oP.clientWidth;
|
||||
oP.remove();
|
||||
return scrollbarWidth;
|
||||
};
|
||||
|
||||
export const createNewArray = (length, content = undefined) => {
|
||||
let i = -1;
|
||||
let arr = [];
|
||||
while (++i < length) {
|
||||
let con = Array.isArray(content) ? content[i] : content;
|
||||
arr.push(con);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
export const iteratorByTimes = (times, fn) => {
|
||||
let i = -1;
|
||||
while (++i < times) {
|
||||
fn(i);
|
||||
}
|
||||
};
|
||||
|
||||
export const getHeaderWords = (length) => {
|
||||
let wordsArr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
let headerArr = [];
|
||||
if (length <= 26) {
|
||||
headerArr = wordsArr.slice(0, length);
|
||||
} else {
|
||||
headerArr = [...wordsArr];
|
||||
let num = length - 26;
|
||||
let firstWordIndex = 0;
|
||||
let secondWordIndex = 0;
|
||||
let i = -1;
|
||||
while (++i < num) {
|
||||
firstWordIndex = Math.floor(i / 26);
|
||||
secondWordIndex = i % 26;
|
||||
let sumWord = `${wordsArr[firstWordIndex]}${wordsArr[secondWordIndex]}`;
|
||||
headerArr.push(sumWord);
|
||||
}
|
||||
}
|
||||
return headerArr;
|
||||
};
|
||||
|
||||
// 获取数组中第一个不为空的值
|
||||
export const getFirstNotNullValue = (array, index) => {
|
||||
if (!(array && array.length)) return false;
|
||||
let r = -1;
|
||||
let rowLength = array.length;
|
||||
while (++r < rowLength) {
|
||||
let item = array[r][index];
|
||||
if (item || item === 0) return item;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const isChineseReg = new RegExp('[\\u4E00-\\u9FFF]+', 'g');
|
||||
export const sortArr = (arr, index) => {
|
||||
if (arr.length <= 1) return;
|
||||
const firstNotNullValue = getFirstNotNullValue(arr, index);
|
||||
if (!firstNotNullValue && firstNotNullValue !== 0) return;
|
||||
if (!isChineseReg.test(firstNotNullValue)) {
|
||||
if (isNaN(Number(firstNotNullValue))) {
|
||||
// 非中文非数值
|
||||
arr.sort();
|
||||
} else {
|
||||
// 数值型
|
||||
arr.sort((a, b) => {
|
||||
return a[index] - b[index];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
arr.sort((a, b) => {
|
||||
return a[index].localeCompare(b[index], 'zh');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 倒序
|
||||
export const sortDesArr = (arr, index) => {
|
||||
if (arr.length <= 1) return;
|
||||
const firstNotNullValue = getFirstNotNullValue(arr, index);
|
||||
if (!firstNotNullValue && firstNotNullValue !== 0) return;
|
||||
if (!isChineseReg.test(firstNotNullValue)) {
|
||||
if (isNaN(Number(firstNotNullValue))) {
|
||||
// 非中文非数值
|
||||
arr.sort().reverse();
|
||||
} else {
|
||||
// 数值型
|
||||
arr.sort((a, b) => {
|
||||
return b[index] - a[index];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
arr.sort((a, b) => {
|
||||
return b[index].localeCompare(a[index], 'zh');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const on = (ele, event, callback) => {
|
||||
ele.addEventListener(event, callback);
|
||||
};
|
||||
|
||||
export const off = (ele, event, callback) => {
|
||||
ele.removeEventListener(event, callback);
|
||||
};
|
||||
|
||||
export const attr = (ele, attribution, value) => {
|
||||
if (value || value === 0) {
|
||||
ele.setAttribute(attribution, value);
|
||||
} else {
|
||||
return ele.getAttribute(attribution);
|
||||
}
|
||||
}
|
||||
294
src/plugin/vue-bigdata-table/vue-bigdata-table.vue
Executable file
294
src/plugin/vue-bigdata-table/vue-bigdata-table.vue
Executable file
@@ -0,0 +1,294 @@
|
||||
<style lang="less">
|
||||
@import './styles/vue-bigdata-table.less';
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div class="v-bt-outer" ref="outer" @DOMMouseScroll="handleScroll" @scroll="handleScroll">
|
||||
<div :class="wrapperClasses" :style="tableWidthStyles">
|
||||
<div class="v-bt-wrapper" ref="outWrapper">
|
||||
<div :class="['v-bt-header-wrapper', fixed ? 'header-wrapper-fixed' : '']" :style="headerStyle">
|
||||
<slot name="top" :colWidthArr="widthArr"></slot>
|
||||
<table v-if="fixedCol >= 0" :class="['v-bt-fixed-header', showFixedBoxShadow ? 'box-shadow' : '']" cellspacing="0" cellpadding="0" border="0">
|
||||
<colgroup>
|
||||
<col v-if="i <= fixedCol" :width="width" v-for="(width, i) in widthArr" :key="'header-key-fixed-' + i" />
|
||||
</colgroup>
|
||||
<tr
|
||||
:style="{cursor: cursorOnHeader}"
|
||||
@mousemove.capture.prevent="handleMousemove"
|
||||
@mousedown="handleMousedown"
|
||||
@mouseup="canNotMove"
|
||||
@mouseleave="canNotMove">
|
||||
<th v-if="i <= fixedCol" v-for="(col, i) in columnsHandled" :data-index="i" :key="`table-title-${i}`" style="border-right: 1px solid #e9eaec;">
|
||||
<span v-if="!col.render">{{ col.title }}<sort-button v-if="showSortBtn(i)" :col-index="i" @on-sort="handleSort" @on-cancel-sort="handleCancelSort" :current-sort-col-index="sortedByColIndex" :current-sort-type="sortedType"></sort-button></span>
|
||||
<render-dom v-else :render="col.render" :back-value="getComputedTableDataIndex(i)"></render-dom>
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
<table ref="headerTable" style="position: absolute;left: 0;top: 0;" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<colgroup>
|
||||
<col :width="width" v-for="(width, i) in widthArr" :key="'header-key-' + i" />
|
||||
</colgroup>
|
||||
<tr
|
||||
:style="{cursor: cursorOnHeader}"
|
||||
@mousemove.capture.prevent="handleMousemove"
|
||||
@mousedown="handleMousedown"
|
||||
@mouseup="canNotMove"
|
||||
@mouseleave="canNotMove">
|
||||
<th v-for="(col, i) in columnsHandled" :data-index="i" :key="`table-title-${i}`">
|
||||
<span v-if="!col.render && (i > fixedCol)">{{ col.title }}<sort-button v-if="showSortBtn(i)" :col-index="i" @on-sort="handleSort" @on-cancel-sort="handleCancelSort" :current-sort-col-index="sortedByColIndex" :current-sort-type="sortedType"></sort-button></span>
|
||||
<render-dom v-else-if="(i > fixedCol)" :render="col.render" :back-value="getComputedTableDataIndex(i)"></render-dom>
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div :class="['v-bt-content', canSelectText ? '' : 'noselect-text']" @mousedown="handleMousedownOnTable">
|
||||
<div :style="{height: `${topPlaceholderHeight}px`}"></div>
|
||||
<render-dom :render="renderTable"></render-dom>
|
||||
<div :style="{height: `${bottomPlaceholderHeight}px`}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import renderDom from './components/renderDom';
|
||||
import sortButton from './components/sort-button.vue';
|
||||
import editRender from './components/input-render';
|
||||
import mixins from './mixins';
|
||||
export default {
|
||||
name: 'bigdataTable',
|
||||
components: {
|
||||
renderDom,
|
||||
sortButton
|
||||
},
|
||||
mixins: [ ...mixins ],
|
||||
props: {
|
||||
/**
|
||||
* @description 是否显示序列号列
|
||||
*/
|
||||
showIndex: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rowNum: Number,
|
||||
colNum: Number,
|
||||
/**
|
||||
* @description 表格数据二维数组
|
||||
*/
|
||||
value: {
|
||||
type: Array
|
||||
},
|
||||
/**
|
||||
* @description 表格行高
|
||||
*/
|
||||
rowHeight: {
|
||||
type: Number,
|
||||
default: 48
|
||||
},
|
||||
/**
|
||||
* @description 是否固定表头
|
||||
*/
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 设为true后表格列宽总是平分容器宽度减去indexWidth后的宽度
|
||||
*/
|
||||
fixedWrapperWidth: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 是否取消鼠标悬浮高亮效果
|
||||
*/
|
||||
disabledHover: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* @description 表头数组,元素为单个表头的对象,【{ title: 'xxx', render: (h) => {} }】
|
||||
*/
|
||||
columns: {
|
||||
type: Array
|
||||
},
|
||||
/**
|
||||
* @description 表头高度
|
||||
*/
|
||||
colWidth: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
/**
|
||||
* @description 表头高度
|
||||
*/
|
||||
headerHeight: {
|
||||
type: Number,
|
||||
default: 52
|
||||
},
|
||||
/**
|
||||
* @description 表头tr行的样式
|
||||
*/
|
||||
headerTrStyle: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 序列号列宽,如果没有设置,则会根据数据行数自动计算适合的宽度
|
||||
*/
|
||||
indexWidth: Number,
|
||||
/**
|
||||
* @description 序列号渲染render
|
||||
*/
|
||||
indexRender: {
|
||||
type: Function,
|
||||
default: (h, index) => {
|
||||
return h('span', index + 1);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 是否显示斑马线
|
||||
*/
|
||||
stripe: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 当前鼠标在表头单元格左侧atLeftCellPosi像素处
|
||||
*/
|
||||
atLeftCellPosi: {
|
||||
type: Number,
|
||||
default: 80
|
||||
},
|
||||
/**
|
||||
* @description 当前鼠标在表头单元格右侧atRightCellPosi像素处
|
||||
*/
|
||||
atRightCellPosi: {
|
||||
type: Number,
|
||||
default: 80
|
||||
},
|
||||
/**
|
||||
* @description 固定的列的范围,[0, fixedCol],设为2即固定0,1,2列,这三列横向不滚动
|
||||
*/
|
||||
fixedCol: {
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
/**
|
||||
* @description 根据表格容器高度计算内置单个表格(1/3)渲染的行数基础上额外渲染的行数,行数越多表格接替渲染效果越好,但越耗性能
|
||||
*/
|
||||
appendNum: {
|
||||
type: Number,
|
||||
default: 15
|
||||
},
|
||||
/**
|
||||
* @description 当前是否可编辑
|
||||
*/
|
||||
canEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 触发编辑单元格的方式,enum:['dblclick' => 双击单元格]
|
||||
*/
|
||||
startEditType: {
|
||||
type: String,
|
||||
default: 'dblclick'
|
||||
},
|
||||
/**
|
||||
* @description 编辑单元格所渲染元素的render函数,如果不传则使用内置元素
|
||||
*/
|
||||
editCellRender: {
|
||||
type: Function,
|
||||
default: editRender
|
||||
},
|
||||
/**
|
||||
* @description 保存修改的单元格内容之前的钩子,如果该函数返回false,则阻止保存
|
||||
*/
|
||||
beforeSave: {
|
||||
type: Function,
|
||||
default: () => {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 是否可选择单元格
|
||||
*/
|
||||
selectable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 是否可粘贴,如果设为true,则selectable效果为true
|
||||
*/
|
||||
paste: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 是否可排序
|
||||
*/
|
||||
sortable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* @description 开启排序的列序号数组或序号
|
||||
*/
|
||||
sortIndex: [Array, Number],
|
||||
/**
|
||||
* @description 默认按指定列指定排序方式排序
|
||||
*/
|
||||
defaultSort: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
prefix: 'v-bt'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 涉及到表格容器尺寸变化或数据变化的情况调用此方法重新计算相关值
|
||||
resize () {
|
||||
this._tableResize();
|
||||
},
|
||||
// 获取表格横向滚动的距离
|
||||
getScrollLeft () {
|
||||
return this.$refs.outer.scrollLeft;
|
||||
},
|
||||
// 调用此方法跳转到某条数据
|
||||
scrollToRow (index) {
|
||||
this._scrollToIndexRow(index);
|
||||
},
|
||||
// canEdit为true时调用此方法使第row+1行第col+1列变为编辑状态,这里的行列指的是表格显示的行和除序列号列的列
|
||||
editCell (row, col) {
|
||||
this._editCell(row, col);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value (val) {
|
||||
this.$nextTick(() => {
|
||||
this.insideTableData = this.setIndex(this.value);
|
||||
this.initSort();
|
||||
this._initM();
|
||||
});
|
||||
},
|
||||
insideTableData () {
|
||||
this.resize();
|
||||
},
|
||||
defaultSort () {
|
||||
this.insideTableData = this.setIndex(this.value);
|
||||
this._initM();
|
||||
this.resize();
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
this.insideTableData = this.setIndex(this.value);
|
||||
this._initM();
|
||||
this.resize();
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -26,6 +26,7 @@ const routes = [
|
||||
redirect: { name: 'demo-components-index' },
|
||||
component: () => import('@/components/core/d2-layout-main/index.vue'),
|
||||
children: (pre => [
|
||||
{ path: 'bigdata-table', name: `${pre}bigdata-table`, component: () => import('@/pages/demo/components/bigdata-table/index.vue') },
|
||||
{ path: 'container/full', name: `${pre}container-full`, component: () => import('@/pages/demo/components/container/full.vue') },
|
||||
{ path: 'container/ghost', name: `${pre}container-ghost`, component: () => import('@/pages/demo/components/container/ghost.vue') },
|
||||
{ path: 'container/card', name: `${pre}container-card`, component: () => import('@/pages/demo/components/container/card.vue') },
|
||||
|
||||
@@ -17,6 +17,11 @@ export default {
|
||||
name: '流星',
|
||||
value: 'star',
|
||||
preview: '/static/image/theme/star/preview@2x.png'
|
||||
},
|
||||
{
|
||||
name: 'Tomorrow Night Blue (vsCode)',
|
||||
value: 'tomorrow-night-blue',
|
||||
preview: '/static/image/theme/tomorrow-night-blue/preview@2x.png'
|
||||
}
|
||||
],
|
||||
name: ''
|
||||
|
||||
Reference in New Issue
Block a user