Compare commits

...

No commits in common. 'master' and 'develop' have entirely different histories.

  1. 26
      .npmignore
  2. 13
      babel.config.js
  3. 55
      build/webpack.config.js
  4. 1
      examples/assets/addIcon.svg
  5. 1
      examples/assets/addIcon_light.svg
  6. 1
      examples/assets/bind_sites.svg
  7. 1
      examples/assets/form_linkActive.svg
  8. 1
      examples/assets/home-bread.svg
  9. 1
      examples/assets/prompt-icon-1.svg
  10. 1
      examples/assets/prompt-icon-2.svg
  11. 1
      examples/assets/prompt-icon-3.svg
  12. 1
      examples/assets/radio_checked.svg
  13. 1
      examples/assets/require.svg
  14. BIN
      examples/assets/separator.png
  15. BIN
      examples/assets/table_empty.png
  16. 1264
      examples/package-lock.json
  17. 15
      examples/package.json
  18. 600
      examples/src/App.vue
  19. 287
      examples/src/a.vue
  20. 13
      examples/src/main.js
  21. 109
      examples/src/table.vue
  22. 1
      examples/vue.config.js
  23. 15670
      package-lock.json
  24. 25
      package.json
  25. 37
      packages/.eslintrc.js
  26. 7
      packages/Breadcrumb/index.js
  27. 116
      packages/Breadcrumb/src/index.vue
  28. 271
      packages/CustomDropdown/src/index copy.vue
  29. 697
      packages/CustomDropdown/src/index.vue
  30. 64
      packages/DevicePreview/src/index.scss
  31. 69
      packages/DevicePreview/src/index.vue
  32. 139
      packages/GuipDialog/src/index.vue
  33. 17
      packages/GuipInput/src/index.vue
  34. 65
      packages/GuipMessage/index.js
  35. 72
      packages/GuipMessage/src/index.vue
  36. 22
      packages/GuipRadio/src/index.vue
  37. 20
      packages/GuipSelect/src/index.vue
  38. 7
      packages/GuipSwitch/index.js
  39. 109
      packages/GuipSwitch/src/index.vue
  40. 7
      packages/GuipTable/index.js
  41. 145
      packages/GuipTable/src/index.vue
  42. 7
      packages/GuipToolTip/index.js
  43. 104
      packages/GuipToolTip/src/index.vue
  44. 1
      packages/PromptText/index.js
  45. 41
      packages/PromptText/src/index.scss
  46. 49
      packages/PromptText/src/index.vue
  47. 7
      packages/SvgIcon/index.js
  48. 126
      packages/SvgIcon/src/index.vue
  49. 7
      packages/SvgIcon1/index.js
  50. 167
      packages/SvgIcon1/src/index.vue
  51. 1
      packages/assets/bind_sites.svg
  52. BIN
      packages/assets/dropDown_expand.png
  53. BIN
      packages/assets/home-bread.png
  54. 1
      packages/assets/home-bread.svg
  55. BIN
      packages/assets/message_Success.png
  56. BIN
      packages/assets/message_Warning.png
  57. BIN
      packages/assets/message_error.png
  58. BIN
      packages/assets/separator.png
  59. BIN
      packages/assets/table_empty.png
  60. 129
      packages/index.js
  61. 63
      packages/styles/common.scss
  62. 539
      packages/styles/component.scss
  63. 22
      packages/styles/index.css
  64. 6
      packages/utils/clipboard.js
  65. 2
      packages/utils/dirClipBoard.js
  66. 8
      packages/utils/eventBus.js
  67. 5
      postcss.config.js

26
.npmignore

@ -1,24 +1,8 @@
# 忽略文件
examples/
build/
node_modules/
*.map
*.html
# 本地开发文件
.DS_Store
*.local
# 日志文件
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 编辑器目录和文件
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.log
*.md
*.yml
webpack.config.js
.gitignore

13
babel.config.js

@ -0,0 +1,13 @@
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}

55
build/webpack.config.js

@ -6,13 +6,13 @@ const {
module.exports = {
mode: 'production',
stats: 'verbose',
// stats: 'verbose',
entry: {
'zhicheng-components': './packages/index.js'
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].umd.js',
filename: 'js/[name].umd.js',
library: 'ZhichengUI',
libraryTarget: 'umd',
umdNamedDefine: true,
@ -20,7 +20,9 @@ module.exports = {
},
resolve: {
alias: {
'@': path.resolve(__dirname, './packages') // 确保别名指向正确
'@': path.resolve(__dirname, './packages'), // 确保别名指向正确
'@assets': path.resolve(__dirname, './packages/assets'),
'vue$': 'vue/dist/vue.esm.js'
}
},
module: {
@ -40,13 +42,32 @@ module.exports = {
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', {
loader: 'sass-loader',
options: {
implementation: require('sass') // 显式指定 sass
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
// fibers: require('fibers'), // 不再需要
fibers:false,
outputStyle: 'compressed',
quietDeps: true // 忽略警告
}
}
}
}]
]
},
// {
// test: /\.scss$/,
// use: [MiniCssExtractPlugin.loader, 'css-loader', {
// loader: 'sass-loader',
// options: {
// implementation: require('sass') // 显式指定 sass
// }
// }]
// },
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [{
@ -64,22 +85,12 @@ module.exports = {
use: [{
loader: 'url-loader',
options: {
limit: 4096,
limit: 8192,
name: 'img/[name].[hash:8].[ext]',
esModule: false,
publicPath: '../'
}
}]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
@ -90,7 +101,8 @@ module.exports = {
})
],
optimization: {
splitChunks: false
splitChunks: false,
minimize: false // 临时关闭压缩
},
externals: {
vue: {
@ -99,5 +111,8 @@ module.exports = {
commonjs2: 'vue',
amd: 'vue'
}
},
stats: {
warningsFilter: () => true // 过滤所有警告
}
}

1
examples/assets/addIcon.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

1
examples/assets/addIcon_light.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

1
examples/assets/bind_sites.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_166_49091"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_166_49091)"><g><path d="M3.993058,2.326391373069763Q2.333333,3.986113373069763,2.333333,6.333333373069763Q2.333333,10.987083373069764,7.58354,15.187233373069763Q7.62755,15.222433373069762,7.67685,15.249733373069763Q7.72614,15.277133373069763,7.77933,15.295733373069764Q7.83251,15.314433373069763,7.88808,15.323833373069764Q7.94364,15.333333373069763,8,15.333333373069763Q8.05636,15.333333373069763,8.111930000000001,15.323833373069764Q8.16749,15.314433373069763,8.22067,15.295733373069764Q8.273859999999999,15.277133373069763,8.32315,15.249733373069763Q8.37245,15.222433373069762,8.41646,15.187233373069763Q13.6667,10.987083373069764,13.6667,6.333333373069763Q13.6667,3.986113373069763,12.00694,2.326391373069763Q10.34721,0.6666663730697632,8,0.6666663730697632Q5.65278,0.6666663730697632,3.993058,2.326391373069763ZM8,13.804833373069764Q3.666667,10.166283373069763,3.666667,6.333333373069763Q3.666667,4.538403373069763,4.9358699999999995,3.269203373069763Q6.20507,2.000000373069763,8,2.000000373069763Q9.79493,2.000000373069763,11.06413,3.269203373069763Q12.33333,4.538403373069763,12.33333,6.333333373069763Q12.33333,10.166293373069763,8,13.804833373069764Z" fill-rule="evenodd" fill="#8A9099" fill-opacity="1"/></g><g><path d="M6.114383,4.447716492279053Q5.333333,5.228765492279052,5.333333,6.333333492279053Q5.333333,7.437903492279053,6.114383,8.218953492279052Q6.895433,9.000003492279053,8,9.000003492279053Q9.104569999999999,9.000003492279053,9.88562,8.218953492279052Q10.66667,7.437903492279053,10.66667,6.333333492279053Q10.66667,5.228765492279052,9.88562,4.447716492279053Q9.104569999999999,3.666666492279053,8,3.666666492279053Q6.895432,3.666666492279053,6.114383,4.447716492279053ZM7.05719,7.276143492279052Q6.666667,6.885613492279052,6.666667,6.333333492279053Q6.666667,5.781053492279053,7.05719,5.390523492279053Q7.44772,5.000000492279053,8,5.000000492279053Q8.55228,5.000000492279053,8.94281,5.390523492279053Q9.33333,5.781053492279053,9.33333,6.333333492279053Q9.33333,6.885613492279052,8.94281,7.276143492279052Q8.55228,7.666663492279053,8,7.666663492279053Q7.44772,7.666663492279053,7.05719,7.276143492279052Z" fill-rule="evenodd" fill="#8A9099" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

1
examples/assets/form_linkActive.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

1
examples/assets/home-bread.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

1
examples/assets/prompt-icon-1.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_217_60685"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_217_60685)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#006AFF" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
examples/assets/prompt-icon-2.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_354_94660/23_30613"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_354_94660/23_30613)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#FF8C00" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
examples/assets/prompt-icon-3.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_242_77707/23_30613"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_242_77707/23_30613)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#FF4D4F" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
examples/assets/radio_checked.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="14" height="14" viewBox="0 0 14 14"><g><g><rect x="0" y="0" width="14" height="14" rx="7" fill="#FFFFFF" fill-opacity="1"/><rect x="0.5" y="0.5" width="13" height="13" rx="6.5" fill-opacity="0" stroke-opacity="1" stroke="#006AFF" fill="none" stroke-width="1"/></g><g><rect x="2.380126953125" y="2.3798828125" width="9.239999771118164" height="9.239999771118164" rx="4.619999885559082" fill="#006AFF" fill-opacity="1"/><rect x="2.710126966238022" y="2.709882825613022" width="8.57999974489212" height="8.57999974489212" rx="4.28999987244606" fill-opacity="0" stroke-opacity="1" stroke="#006AFF" fill="none" stroke-width="0.6600000262260437"/></g></g></svg>

After

Width:  |  Height:  |  Size: 771 B

1
examples/assets/require.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="8" height="8" viewBox="0 0 8 8"><g><g><path d="M4.53619,3.49598C4.93756,3.30242,5.33495,3.10073,5.72813,2.89102C6.10411,2.68903,6.40809,2.53804,6.63208,2.44504C6.85606,2.35305,7.03205,2.30305,7.16805,2.30305C7.39203,2.30305,7.58402,2.37805,7.75201,2.53804C7.912,2.69803,8,2.89102,8,3.126C8,3.26099,7.96,3.40299,7.88001,3.54598C7.80001,3.68897,7.71202,3.78196,7.62402,3.82396C6.80007,4.16794,5.88012,4.41992,4.88817,4.57091C5.07216,4.7389,5.28815,4.97489,5.55214,5.26887C5.81612,5.56285,5.95211,5.71384,5.96811,5.73884C6.06411,5.88183,6.2001,6.05882,6.37609,6.26881C6.55208,6.4788,6.67207,6.63879,6.73607,6.75578C6.80007,6.87377,6.84006,7.01576,6.84006,7.18475C6.84107,7.39587,6.75753,7.5986,6.60808,7.74772C6.45193,7.91074,6.23371,7.99948,6.00811,7.9917C5.76812,7.9917,5.48814,7.78972,5.18416,7.39474C4.88017,7.00776,4.4802,6.29481,4.00022,5.26087C3.51225,6.18481,3.18427,6.80678,3.02428,7.10076C2.85629,7.39474,2.69629,7.62073,2.5443,7.77272C2.40703,7.91778,2.21605,7.99989,2.01633,7.9997C1.79003,8.00605,1.5728,7.91065,1.42436,7.73972C1.28036,7.59025,1.19759,7.39224,1.19238,7.18475C1.19238,6.99976,1.22438,6.86477,1.28837,6.77278C1.88034,5.93283,2.49631,5.19288,3.13627,4.57991C2.65244,4.50186,2.17205,4.40378,1.69635,4.28593C1.23363,4.16226,0.781541,4.00176,0.344425,3.80596C0.264429,3.76496,0.192433,3.67197,0.120437,3.52898C0.0420906,3.41216,0.00031659,3.27466,0.000443602,3.134C-0.00716869,2.91112,0.0835016,2.69615,0.24843,2.54604C0.397403,2.39297,0.602823,2.30798,0.816398,2.31105C0.96839,2.31105,1.16038,2.36105,1.39237,2.45404C1.62435,2.55404,1.91234,2.68903,2.27232,2.88202C2.6323,3.06701,3.03228,3.27699,3.48825,3.50398C3.40825,3.07601,3.33626,2.58804,3.28026,2.04207C3.22427,1.4961,3.20027,1.11813,3.20027,0.916139C3.20027,0.664155,3.27226,0.454168,3.42425,0.277179C3.5641,0.0976285,3.7807,-0.00510704,4.00822,0.000195663C4.24021,0.000195663,4.4322,0.09219,4.58419,0.269179C4.73618,0.454168,4.80818,0.689153,4.80818,0.983135C4.80818,1.06713,4.79218,1.22712,4.77618,1.46311C4.76018,1.70609,4.72018,1.99207,4.68018,2.32805C4.63219,2.67203,4.58419,3.05801,4.53619,3.49598Z" fill="#FF4D4F" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
examples/assets/separator.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

BIN
examples/assets/table_empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

1264
examples/package-lock.json

File diff suppressed because it is too large

15
examples/package.json

@ -9,11 +9,12 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"element-ui": "^2.15.13",
"@zhicheng1012/zhicheng-components": "^1.0.18",
"core-js": "^3.40.0",
"element-ui": "^2.15.14",
"my-components": "file:../",
"vue": "^2.6.14",
"vue-loader": "^15.9.8"
"vue": "2.6.14",
"vue-loader": "^17.4.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.19",
@ -22,10 +23,10 @@
"babel-eslint": "^10.1.0",
"css-loader": "^5.2.7",
"eslint": "^6.8.0",
"sass": "^1.32.13",
"sass-loader": "^8.0.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.14"
"sass": "^1.89.2",
"sass-loader": "^10.2.0",
"vue-template-compiler": "2.6.14"
},
"browserslist": [
"> 1%",

600
examples/src/App.vue

@ -1,8 +1,9 @@
<template>
<div id="app" class="demo-container">
<el-form :model="form" class="el-row demo-ruleForm" ref="formRef">
<el-form :model="form" :rules="rules" class="el-row demo-ruleForm" ref="formRef">
<!-- 当前示例项目未配置路由相关信息--暂时注释 -->
<!-- <Breadcrumb /> -->
<!-- 按钮组件示例 -->
<section class="demo-section">
<h2>页面提示框集合</h2>
<PromptText text='这是一个提示框' :type="1" />
@ -13,18 +14,20 @@
<p class="flex">
<a href="https://e.360.cn/static/zhihui/login/?rdurl=https%3A%2F%2Fe.360.cn%2F" class="flex"
target="_blank">
<img src="~@assets/form_linkActive.svg" alt="">前往登陆</a>登录360智慧平台
<img src="../assets/form_linkActive.svg" alt="">前往登陆</a>登录360智慧平台
<!-- <img src="~@assets/form_linkActive.svg" alt="">前往登陆</a>登录360智慧平台 -->
</p>
</template>
<template #desc>
<p class="mt12 flex">
1. <a href="https://e.360.cn/static/zhihui/login/?rdurl=https%3A%2F%2Fe.360.cn%2F" class="flex"
target="_blank">
<img src="~@assets/form_linkActive.svg" alt="">前往登陆</a>登录360智慧平台
<img src="../assets/form_linkActive.svg" alt="">前往登陆</a>登录360智慧平台
</p>
<p class="mt10 flex">
2. <a href="https://dianjing.e.360.cn/ocpc/list" class="flex" target="_blank">
<img src="~@assets/form_linkActive.svg" alt="">前往ocpc设置页</a>点击添加OCPC投放包按钮注意转换类型只能选择订单其他的根据表单提示填写
<img src="../assets/form_linkActive.svg"
alt="">前往ocpc设置页</a>点击添加OCPC投放包按钮注意转换类型只能选择订单其他的根据表单提示填写
</p>
</template>
</PromptText>
@ -42,7 +45,6 @@
</div>
<div class="ele-item">
<label for="">强按钮</label>
<!-- 默认 type= primary normal 样式 -->
<GuipButton>默认</GuipButton>
<GuipButton loading>按钮</GuipButton>
<GuipButton disabled>按钮</GuipButton>
@ -81,21 +83,13 @@
@input="handleInput" @focus="handleInput" placeholder="这是自定义默认提示语" />
<div style="width: 20px;height: 10px;"></div>
<GuipInput ref="GuipInput" width="200px" label="售价" placeholder="请输入售价" unit="元"></GuipInput>
<GuipInput v-model="form.input3" width="400px">
<span slot="prependshow">http:</span>
<!-- <img slot="prefix" src="../assets/radio_checked.svg" alt=""> -->
<!-- 输入框后面小图标 -事件自定义 -->
<i slot="suffix" class="el-icon-close" @click="handleClear"></i>
<!-- <img slot="suffix" src="../assets/radio_nochecked.svg" alt="" @click="handleClear"> -->
<!-- 这个 appendshow 宽度 居中方式 自定义添加类名修改-->
<!-- <GuipButton slot="appendshow" size="mini">默认按钮</GuipButton> -->
<!-- 这个 appendshow 宽度 居中方式 自定义添加类名修改-->
<span slot="appendshow">.checkcopy.com</span>
</GuipInput>
<!-- <el-input placeholder="oieuwroieuwi" style="width:400px;height:60px"></el-input> -->
</div>
<div class="ele-item">
<label for="">文本域固定行数</label>
@ -113,6 +107,35 @@
</div>
</section>
<section class="demo-section">
<h2>提示框</h2>
<div class="ele-item">
<GuipButton type="system" @click="openMessage('success')">成功提示</GuipButton>
<GuipButton type="system" @click="openMessage('error')"> 失败提示</GuipButton>
<GuipButton type="system" @click="openMessage('info')">警告提示</GuipButton>
</div>
</section>
<section class="demo-section">
<h2>复制功能</h2>
<div class="ele-item">
<label for="">copy固定内容</label>
<!-- 复制固定文本 -->
<GuipButton size="big" v-clipboard="'渝过田晴'">复制渝过田晴</GuipButton>
<!-- 复制动态文本 -->
<GuipButton size="big" v-clipboard="content">点击复制: {{ content }}</GuipButton>
</div>
<div class="ele-item">
<label for="">手动点击copy</label>
<GuipInput v-model="form.input1">
<!-- 提示可以不添加 图标可更换 -->
<GuipToolTip content="点击复制到粘贴板" slot="suffix">
<img src="../assets/home-bread.svg" @click="handleClickCopy" />
</GuipToolTip>
</GuipInput>
</div>
</section>
<section class="demo-section">
<h2>实时预览tab组件</h2>
<DevicePreview>
<template #desktop>
@ -129,12 +152,13 @@
<div class="ele-item">
<label for="">单选框(对象格式)</label>
<GuipRadio v-model="form.language" :options="languageOptions" label="选择语言" prop="language"
@change="radioChange" />
@change="radioChange" :rules="rules.language" />
</div>
<div class="ele-item">
<label for="">单选框2数组格式 + 自定义取值</label>
<GuipRadio v-model="form.language" :options="languageOptions1" label="自定义属性" prop="language"
@change="radioChange" label-key="name" :disabledKeys="['1']" value-key="id" />
selectedLabelKey="selectedLabel" @change="radioChange" :rules="rules.language" label-key="name"
:disabledKeys="['1']" value-key="id" />
</div>
<div class="ele-item">
<label for="">单选框</label>
@ -151,90 +175,177 @@
</el-radio-group>
</div>
</section>
<section class="demo-section">
<h2>下拉组件集合</h2>
<!-- <div class="flex ele-item">
<label for="">普通下拉选择框可自定义属性</label>
<GuipSelect width="600px" v-model="form.card" clearable label="卡片" :default-value="form.card" prop="card"
:options="options" valueKey="id1" labelKey="id2" />
</div> -->
<!-- <div class="flex ele-item">
<label for="">inputdrop组合使用(默认使用)</label>
<GuipFormItem column="column" class="combo-formItem w510" label="域名设置" required="true">
<div slot="formDom" class="self-drop-wrap flex">
<GuipInput style="width: 60%;" v-model="form.domain_set" placeholder="仅支持数字、字母">
</GuipInput>
<div @click="toggleDrop" class="point flex appendDrop" style="width: 40%;">
{{ currentDomainItem.name }}</div>
</div>
<CustomDropdown slot="formDom" ref="dropDomain" width="100%" v-model="form.domainSuffix1"
:options="domainOptions" @change="changeSelectIp" placeholder="请选择">
<template #normal>
<div class="flex flex-between noraml-jump">
<div class="left">
<b>添加新域名</b>
<p class="one ft12">域名需要在阿里云完成ICP备案并解析到平台服务器</p>
<p class="ft12">如果暂时未准备好可先选用平台免费域名随时支持域名修改 </p>
</div>
<div class="right">
<GuipButton size="form">前往绑定</GuipButton>
</div>
</div>
</template>
</CustomDropdown>
<h2>下拉展开组件集合</h2>
<div class="ele-item">
<label for="">下拉框</label>
<GuipSelect width="600px" v-model="form.card" clearable label="卡片" :default-value="form.card"
@change="selectChangeTest" prop="card" :options="options" valueKey="id1" labelKey="id2"
:extraItem="{ label: '全部', value: '99999' }" />
</div>
</section>
<section class="demo-section">
<h2>自定义表单展示形式</h2>
<!-- 必须添加 slot -->
<div style="width: 400px;">
<GuipFormItem column="column" class="mb24" label="自定义左侧">
<span class="desc" slot="formRight"><a href="https://www.baidu.com/">跳转一下</a> 自定义右侧</span>
<GuipInput slot="formDom" ref="GuipInput" v-model="form.input1" width="100%" placeholder="这是自定义默认提示语" />
</GuipFormItem>
</div> -->
<!-- <div class="flex ele-item">
<label for="">inputdrop组合使用(自定义下拉选择项)</label>
<GuipFormItem column="column" class="combo-formItem w510" label="域名设置" required="true">
<div slot="formDom" class="self-drop-wrap flex">
<GuipInput style="width: 60%;" v-model="form.domain_set" placeholder="仅支持数字、字母">
</GuipInput>
<div @click="toggleDrop1" class="point flex appendDrop" style="width: 40%;">
{{ currentDomainItem.name }}
</div>
</section>
<section class="demo-section">
<h2>表格(表头自定义自定义渲染固定列)</h2>
<GuipButton type="primary" @click="toggleAllSelection">全选按钮</GuipButton>
<GuipTable :tableData="tableData2" ref="multipleTable" @selectChange="handleSelectionChange" :multiple="true"
autoColumn="true" :loading="tableLoading" :border="true">
<!-- <template slot="header"> -->
<el-table-column width="180" fixed="left" label="名称(固定左)"></el-table-column>
<el-table-column prop="created_at" label="时间" width="200">
<template slot-scope="scope">
<div class="flex cell_render">
<GuipToolTip content="文字居中">
<span :class="(scope.row.payment == '0' ? 'normal_payment' : 'self_payment')">{{
scope.row.payment
==
'0' ? '文字居中' : '文字居中' }}</span>
</GuipToolTip>
<GuipToolTip content="图标居中">
<svg-icon :size="16" :path="require('../assets/home-bread.svg')" :color="'#8A9099'"
:hoverColor="'#006AFF'" />
</GuipToolTip>
</div>
</div>
<CustomDropdown slot="formDom" ref="dropDomain1" width="100%" v-model="form.domainSuffix"
:options="domainOptions" @change="changeSelectIp" valueKey="id" placeholder="请选择">
<template #normal>
<div class="flex flex-between noraml-jump">
<div class="left">
<b>添加新域名</b>
<p class="one ft12">域名需要在阿里云完成ICP备案并解析到平台服务器</p>
<p class="ft12">如果暂时未准备好可先选用平台免费域名随时支持域名修改 </p>
</div>
<div class="right">
<GuipButton size="form">前往绑定</GuipButton>
</div>
</div>
</template>
<template #item="{ item }">
<div class="flex-between">
<div class="left">
<p class="one">{{ item.label }}</p>
</div>
<div class="right">
<img v-if="form.domainSuffix == item.id" src="~@assets/drop-selected.svg" alt="">
</div>
</template>
</el-table-column>
<el-table-column prop="unit_num" label="数量" width="180">
<template slot-scope="scope">
<GuipToolTip content="单元格局中">
<div class="flex">
<span :class="(scope.row.payment == '0' ? 'normal_payment' : 'self_payment')">{{
scope.row.payment
==
'0' ? '单元格局中' : '单元格局中' }}</span>
<svg-icon :size="16" :path="require('../assets/home-bread.svg')" :color="'#8A9099'"
:hoverColor="'#006AFF'" />
</div>
</template>
</CustomDropdown>
</GuipFormItem>
</div> -->
</GuipToolTip>
</template>
</el-table-column>
<el-table-column prop="name2" label="姓名" width="150"></el-table-column>
<el-table-column prop="price" label="价格" width="150">
<template slot-scope="scope">
<span @click="handlePriceClick(scope.row)">{{ scope.row.price }}</span>
</template>
</el-table-column>
<el-table-column prop="address" label="地址1" width="150"> </el-table-column>
<el-table-column prop="address" label="地址2" width="250"> </el-table-column>
<el-table-column prop="address" label="地址3" width="150"> </el-table-column>
<el-table-column prop="address1" label="地址测试" width="100"></el-table-column>
<el-table-column prop="price" label="价格" width="300">
<template slot-scope="scope">
<GuipSelect width="200px" @change="changeSelect(scope.row)" v-model="form.card" prop="card"
:options="options" defaultValue="选项1" />
</template>
</el-table-column>
<el-table-column label="操作(固定右)" width="200" fixed="right">
<template slot-scope="scope">
<div class="flex">
<el-button @click="handleClick(scope.row)" type="text">查看</el-button>
<el-button type="text">编辑</el-button>
</div>
</template>
</el-table-column>
</GuipTable>
<el-pagination background @size-change='handleSizeChange' @current-change='handleCurrentChange'
:current-page="currentPage" :page-size=pageSize layout="prev, pager, next,jumper" :total="total">
</el-pagination>
</section>
<section class="demo-section">
<h2>开关组件</h2>
<GuipSwitch v-model="form.switchValue3" activeText="默认类型boolean" inactiveText="关闭" @change="onSwitchChange">
</GuipSwitch>
<GuipSwitch v-model="switchValue" float="right" activeText="文案在右,默认左侧" inactiveText="关闭"
@change="onSwitchChange">
</GuipSwitch>
<GuipSwitch v-model="switchValue1" :active-value="1" :inactive-value="0" activeText="number"
@change="onSwitchChange">
</GuipSwitch>
<GuipSwitch v-model="form.switchValue2" active-value="0" inactive-value="1" activeText="string"
@change="onSwitchChange">
</GuipSwitch>
</section>
<section class="demo-section">
<h2>图标组件相关</h2>
<SvgIcon1 :iconPath="require(`../assets/home-bread.svg`)" defaultColor="#8A9099" :size="16"
activeColor="#006AFF" />
<svg-icon :size="16" :path="require('../assets/home-bread.svg')" :color="'#8A9099'" :hoverColor="'#006AFF'" />
<GuipToolTip placement="bottom" effect="light" content="点击进入编辑">
<SvgIcon1 :iconPath="require(`../assets/home-bread.svg`)" defaultColor="#8A9099" :size="16"
activeColor="#006AFF" />
</GuipToolTip>
</section>
<section class="demo-section">
<h2>弹出框组件相关</h2>
<div class="flex ele-item">
<label for="">单独实现自定义内容下拉选择</label>
<!-- <CustomDropdown width="500px"
v-model="selectedValue"
:options="options"
:null-option="nullOption"
@change="handleSafeChange"
@opened="onOpen"
@closed="onClose"
> -->
<CustomDropdown width="500px" v-model="form.domainSuffix" :options="domainOptions" @change="changeSelectIp"
valueKey="id" placeholder="请选择" @opened="onOpen"
@closed="onClose">
<GuipButton type="primary" :btnstyle="{ width: '300px' }" @click="openDialog">打开弹框标题巨左按钮居右
</GuipButton>
<GuipButton type="primary" :btnstyle="{ width: '300px' }" @click="openDialog1">打开弹框标题巨中按钮居中
</GuipButton>
<GuipButton type="primary" :btnstyle="{ width: '300px' }" @click="openDialog2">打开弹框-放弃原按钮自定义
</GuipButton>
<!-- <GuipButton type="primary" @click="openLoading" size="page">展示加载动画 2s</GuipButton> -->
</div>
</section>
<!-- <div class="flex ele-item">
<label for="">inputdrop组合使用(默认使用)</label>
<GuipFormItem column="column" class="combo-formItem w510" label="域名设置" required="true">
<div slot="formDom" class="self-drop-wrap flex">
<GuipInput style="width: 60%;" v-model="form.domain_set" placeholder="仅支持数字、字母">
</GuipInput>
<div @click="toggleDrop" class="point flex appendDrop" style="width: 40%;">
{{ currentDomainItem.name }}</div>
</div>
<CustomDropdown slot="formDom" ref="dropDomain" width="100%" v-model="form.domainSuffix1"
group="account-selector" :options="domainOptions" @change="changeSelectIp" placeholder="请选择">
<template #normal>
<div class="flex flex-between noraml-jump">
<div class="left">
<b>添加新域名</b>
<p class="one ft12">域名需要在阿里云完成ICP备案并解析到平台服务器</p>
<p class="ft12">如果暂时未准备好可先选用平台免费域名随时支持域名修改 </p>
</div>
<div class="right">
<GuipButton size="form">前往绑定</GuipButton>
</div>
</div>
</template>
</CustomDropdown>
</GuipFormItem>
</div> -->
<!-- <div class="flex ele-item">
<label for="">inputdrop组合使用(自定义下拉选择项)</label>
<GuipFormItem column="column" class="combo-formItem w510" label="域名设置" required="true">
<div slot="formDom" class="self-drop-wrap flex">
<GuipInput style="width: 60%;" v-model="form.domain_set" placeholder="仅支持数字、字母">
</GuipInput>
<div @click="toggleDrop1" class="point flex appendDrop" style="width: 40%;">
{{ currentDomainItem.name }}
</div>
</div>
<CustomDropdown slot="formDom" ref="dropDomain1" width="100%" v-model="form.domainSuffix"
group="account-selector" :options="domainOptions" @change="changeSelectIp" valueKey="id" placeholder="请选择">
<template #normal>
<div class="flex flex-between noraml-jump">
<div class="left">
@ -249,20 +360,84 @@
</template>
<template #item="{ item }">
<div class="flex-between">
<p>测试一下自定义内容{{ item.id }} + {{ item.label }}</p>
<p>易烊千玺/田栩宁</p>
<div class="left">
<p class="one">{{ item.label }}</p>
</div>
<div class="right">
<span v-if="form.domainSuffix == item.id">*</span>
</div>
</div>
</template>
</CustomDropdown>
</GuipFormItem>
</div> -->
<!-- <div class="flex ele-item">
<label for="">单独实现自定义内容下拉选择</label>
<CustomDropdown width="500px" v-model="form.domainSuffix" :options="domainOptions" group="account-selector"
@change="changeSelectIp" valueKey="id" placeholder="请选择">
<template #normal>
<div class="flex flex-between noraml-jump">
<div class="left">
<b>添加新域名</b>
<p class="one ft12">域名需要在阿里云完成ICP备案并解析到平台服务器</p>
<p class="ft12">如果暂时未准备好可先选用平台免费域名随时支持域名修改 </p>
</div>
<div class="right">
<GuipButton size="form">前往绑定</GuipButton>
</div>
</div>
</template>
<template #item="{ item }">
<div class="flex-between">
<p>测试一下自定义内容{{ item.id }} + {{ item.label }}</p>
<p>易烊千玺/田栩宁</p>
</div>
</template>
</CustomDropdown>
</div> -->
<GuipDialog :dialogVisible="dialogVisible" title="自定义标题" :show-close-button="false"
:show-cancel-button="showCancelButton" @confirm="handleConfirm" @cancel="handleCancel" @close="handleClose"
@dialogVisibleChange="dialogVisibleChange">
<!-- 自定义内容 -->
<div>
<p>这是一个自定义内容的弹框</p>
</div>
</section>
</GuipDialog>
<GuipDialog type="center" :dialogVisible="dialogVisible1" title="自定义标题" @close="handleClose"
@dialogVisibleChange="dialogVisibleChange">
<!-- 自定义内容 -->
<div>
<p>这是一个自定义内容的弹框</p>
</div>
</GuipDialog>
<GuipDialog type="center" :dialogVisible="dialogVisible2" title="自定义标题、内容、按钮" :showFooterButton="false"
@close="handleClose" @dialogVisibleChange="dialogVisibleChange">
<!-- 自定义内容 -->
<div>
<p>这是一个自定义内容的弹框</p>
<p>这是一个自定义内容的弹框</p>
<p>这是一个自定义内容的弹框</p>
<p>这是一个自定义内容的弹框</p>
<!-- 样式自定义 -->
<div class="btns gap10 mt24" style="width:100%">
<GuipButton type="ignore">取消</GuipButton>
<GuipButton :btnstyle="{ width: '240px' }">咖啡不加糖喔</GuipButton>
</div>
</div>
</GuipDialog>
<div style="width: 100%;height: 500px;"></div>
</el-form>
</div>
</template>
<script>
// import { GuipMessage } from '@zhicheng1012/zhicheng-components'
export default {
data() {
return {
@ -326,28 +501,33 @@ export default {
timer: null,
date1: '',
switchValue: true,
switchValue3: true,
switchValue1: 1,
switchValue2: '0',
dialogVisible1: false,
dialogVisible2: false,
dialogVisible: false,//
showCancelButton: true, //
showCloseButton: true, //
form: {
username: '',
language: '',
switchValue3: true,
switchValue2: '0',
domain_set: '',
domainSuffix: '11',
domainSuffix1: '.chachongz.com',
card: '1',
card1: '20',
input1: '跨年的烟火,绽放天空',
input2: '',
input3: '',
},
languageOptions1: [
{ label: 'JavaScript', value: 'js', selectedLabel: 'JavaScripthhhhhhhhhh', id: '1', name: '麻辣烫' },
{ label: 'Python', value: 'py', selectedLabel: 'JavaScripthhhhhhhhhh', id: '10', name: '易烊千玺' },
{ label: 'Java', value: 'java', disabled: true, selectedLabel: 'JavaScripthhhhhhhhhh', id: '11', name: '王源' }, //
{ label: 'Go', value: 'go', selectedLabel: 'JavaScripthhhhhhhhhh', id: '12', name: '王俊凯' },
{ label: 'JavaScript', value: 'js', selectedLabel: '333提拉米苏33', id: '1', name: '麻辣烫' },
{ label: 'Python', value: 'py', selectedLabel: '柠檬茶', id: '10', name: '易烊千玺' },
{ label: 'Java', value: 'java', disabled: true, selectedLabel: '榴莲大福', id: '11', name: '王源' }, //
{ label: 'Go', value: 'go', selectedLabel: '444222麻辣烫', id: '12', name: '王俊凯' },
],
languageOptions: {
'20': '查重站',
@ -408,6 +588,7 @@ export default {
address: '上海市普陀区金沙江路 1518 弄',
price: '20',
age: 20,
statu: 1,
//
edit_name: '王小虎', edit_address: '上海市普陀区金沙江路 1518 弄'
}, {
@ -416,6 +597,8 @@ export default {
address: '上海市普陀区金沙江路 151811 弄',
price: '10',
age: 30,
statu: 1,
edit_name: '王小虎11', edit_address: '上海市普陀区金沙江路 151811 弄'
}, {
@ -423,6 +606,7 @@ export default {
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
price: '200',
statu: 0,
}, {
date: '2016-05-01',
name: '王小虎',
@ -563,7 +747,7 @@ export default {
value: '选项1',
label1: '黄金hhhhhh',
id1: '1',
id2: '啊11哈哈',
id2: '1是打开快递吧',
label: '黄金糕'
}, {
value: '选项2',
@ -592,8 +776,32 @@ export default {
}],
}
},
created() {
console.log('当前组件注册情况:', this.$options.components)
mounted() {
// this.getList();
// this.getStagePurchase()
// this.$loadingFn.show()
// setInterval(()=>{
// this.$loadingFn.hide()
// },70000)
// this.timer = setTimeout(() => {
// this.$store.dispatch('hideLoading')
// }, 2000)
// this.timer = null;
// GuipMessage({
// type: 'success',
// title: '',
// message: '',
// duration: 5000,
// showClose: true,
// center: true
// })
// =----ok
// this.$Message({
// message: '',
// type: 'info',
// duration: 3000
// })
},
computed: {
currentDomainItem() {
@ -601,8 +809,21 @@ export default {
}
},
methods: {
switchChange(value) {
console.log(value, '====value');
console.log(this.switchValue1, '===uuuu');
},
handleEvent(data) {
console.log(data, 'data')
},
handleOptions(options) {
console.log(options, 'options')
},
// copy
handleClickCopy() {
// GuipMessage.success('')
// this.$Message.success('')
this.$copy(this.form.input1, {
successMsg: '内容已复制到剪贴板',
errorMsg: '复制失败,请按Ctrl+C手动复制',
@ -627,17 +848,10 @@ export default {
console.log(e, '---000changeInputtest');
},
changeSelectIp(item) {
//
// this.selectedItem1 = { ...item };
console.log(item, this.form.domainSuffix, this.form.domainSuffix1, '选中的项-值-');
},
onOpen() {
console.log('下拉框打开')
},
onClose() {
console.log('下拉框关闭')
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
console.log(row, column);
if (rowIndex % 2 === 0) {
@ -748,15 +962,25 @@ export default {
return randomNumber
},
onSwitchChange(value) {
console.log('Switch 状态变化:', this.switchValue, value);
console.log('Switch/ 状态变化:', this.switchValue, value);
// console.log('Switch :',this.form.switchValue2,this.form.switchValue3, value);
},
onSwitchChange1(value) {
//
// console.log(this.tableData2,value,'this.tableData2===');
console.log('Switch/ 状态变化:', value.statu);
},
// ---start
openDialog() {
console.log(this.switchValue1, 'switchValue1');
this.dialogVisible = true;
},
openDialog1() {
this.dialogVisible1 = true;
},
openDialog2() {
this.dialogVisible2 = true;
},
//
handleConfirm() {
this.$message.success('点击了确认按钮');
@ -767,11 +991,14 @@ export default {
this.$message.warning('点击了取消按钮');
this.dialogVisible = false;
this.dialogVisible1 = false;
this.dialogVisible2 = false;
},
//
handleClose() {
this.$message.info('弹框已关闭');
this.dialogVisible = false;
this.dialogVisible1 = false;
this.dialogVisible2 = false;
},
dialogVisibleChange(data) {
console.log(data, 'data098908090');
@ -805,6 +1032,9 @@ export default {
radioChange(data) {
console.log(data, 'radio--data');
},
selectChangeTest(val) {
console.log(val, 'select-----选中的', this.form.card, this.form.card1);
},
handleClick(row) {
console.log(row);
},
@ -842,18 +1072,19 @@ export default {
// this.handleInput('')
console.log(value, 'value===qinghcu');
},
// getList() {
// const dataList = rules();
// dataList.forEach((item) => {
// if (item.field === "id") {
// item.options = this.cities;
// }
// if (item.field === "id1") {
// item.options = this.optionss;
// }
// });
// this.formList = dataList;
// },
getList() {
const dataList = rules();
dataList.forEach((item) => {
if (item.field === "id") {
item.options = this.cities;
}
if (item.field === "id1") {
item.options = this.optionss;
}
});
console.log(this.formList, 'this.formList====');
this.formList = dataList;
},
save() {
this.$refs.VabForm.submitForm("ruleForm");
},
@ -883,7 +1114,7 @@ export default {
}
</script>
<style scoped>
<style scoped lang="scss">
.demo-container {
padding: 20px;
max-width: 90%;
@ -918,4 +1149,119 @@ h2 {
padding-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
}
.elementWrap {
/* width: 100%; */
padding: 30px 40px;
background: #fff;
.ele-item {
display: flex;
align-items: center;
justify-content: flex-start;
margin: 20px 0 30px;
label {
font-size: 16px;
font-weight: bold;
width: 100px;
margin-right: 10px;
text-align: left;
}
}
}
// start
// input drop使
.combo-formItem {
::v-deep {
.form-item-bottom {
position: relative;
}
.select-trigger {
background: #F6F7FA;
border-color: transparent;
}
.is-open .select-trigger {
border-color: #006AFF;
}
.el-input__inner {
border-radius: 2px 0 0 2px;
}
}
.self-drop-wrap {
position: absolute;
z-index: 1;
width: 100%;
}
.appendDrop {
height: 38px;
align-items: center;
border-radius: 0 2px 2px 0;
border: 1px solid #DFE2E6;
border-left-color: transparent;
justify-content: center;
box-sizing: border-box;
padding: 0 30px 0 12px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
&:hover {
border: 1px solid #006AFF;
}
}
}
// end
.ScaleBox {
width: 1000px;
background-size: 100% 100%;
-ms-transition: 0.3s;
transition: 0.3s;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
margin: 0 auto;
}
.cardfooter {
width: 100%;
bottom: 20px;
right: 30px;
text-align: right;
justify-content: center;
}
.btn1 {
cursor: pointer;
font-weight: bold;
width: 114px;
height: 40px;
/* 自动布局 */
display: flex;
align-items: center;
padding: 11px 12px;
box-sizing: border-box;
color: #FFFFFF;
border-radius: 4px;
transition: all .3s;
background: linear-gradient(290deg, #FF4143 4%, #FF768B 92%);
&:hover {
opacity: 0.7;
background: linear-gradient(290deg, #FF4143 4%, #FF768B 92%);
}
}
.btns {
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>

287
examples/src/a.vue

@ -0,0 +1,287 @@
<template>
<transition :name="customize ? '' : 'menu-collapse'">
<el-menu v-if="!customize" class="el-menu-vertical-demo custom-menu" @open="handleOpen"
:default-active="currentMenuItem?.index"
@close="handleClose" @select="handleSelect" :collapse="isCollapse" :collapse-transition="true"
>
<div style="height: 100%;padding: 0 0 20px;box-sizing: border-box;">
<div class="menu-top">
<span v-show="!isCollapse">
导航
</span>
<GuipToolTip :content="isCollapse ? '展开' : '收起'">
<img v-if="!isCollapse" class="point" src="../assets/menu-close.svg" @click="changeMenuStatus(true)" alt="">
<img v-else class="point" src="../assets/menu-open.svg" @click="changeMenuStatus(false)" alt="">
</GuipToolTip>
</div>
<template v-for="item in menuData" >
<el-submenu v-if="item.children" :key="item.index" :index="item.index">
<template slot="title">
<SvgIcon1 :iconPath="require(`@/assets/menu/${item.icon}.svg`)" defaultColor="#8A9099"
activeColor="#006AFF" :isActive="item.index == currentMenuItem?.index?.substring(0,1) && isCollapse" />
<span class="title_text" >{{ item.title }}</span>
</template>
<el-menu-item style="padding: 0 22px 0 32px;" v-for="subItem in item.children" :key="subItem.index"
:index="subItem.index" @click="handleSelect(subItem.index, [item.index, subItem.index], subItem)">
{{ subItem.title }}
</el-menu-item>
</el-submenu>
<el-menu-item v-else :index="item.index" :key="item.index" @click="handleSelect(item.index, [item.index], item)">
<div class="flex">
<SvgIcon1 :iconPath="require(`@/assets/menu/${item.icon}.svg`)" defaultColor="#8A9099"
activeColor="#006AFF" :isActive="item.index == currentMenuItem?.index" />
<span class="title_text" slot="title">{{ item.title }}</span>
</div>
</el-menu-item>
</template>
</div>
</el-menu>
<SetLeftMenu v-else :menuList="menuData"/>
</transition>
</template>
<script>
import SetLeftMenu from '@/components/SetLeftMenu.vue'
import SvgIcon1 from '@/components/SvgIcon1.vue';
import GuipToolTip from '@/components/GuipToolTip.vue';
export default {
name: 'SliderMenu',
components: {
SvgIcon1,
GuipToolTip,
SetLeftMenu
},
props: {
menuData: {
type: Array,
default: () => []
},
customize:{
type:Boolean,
default:false
}
},
data() {
return {
isCollapse: false,
routerList: [],
currentMenuItem:'',
currentMenuParent:''
};
},
watch: {
"$route.path"() {
if(this.customize)return
this.updateCurrentMenu();
},
},
methods: {
changeMenuStatus(flag) {
this.isCollapse = flag;
},
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
// handleSelect(index,indexPath) {
// this.activeMenu = index;
// console.log(index,indexPath, '---index');
// // menu path
// const allItems = this.menuData.flatMap(menu => menu.children);
// const targetItem = allItems.find(item => item.index === index);
// if (targetItem && this.$route.path !== targetItem.path) {
// this.$router.push(targetItem.path);
// }
// },
handleSelect(index, indexPath, menuItem) {
if (menuItem.path && this.$route.path !== menuItem.path) {
this.$router.push(menuItem.path);
}
},
updateCurrentMenu() {
const result = this.findMenuItemByPath(this.menuData, this.$route.path);
this.currentMenuItem = result?.item;
},
findMenuItemByPath(menuItems, targetPath, parent = null) {
for (const item of menuItems) {
if (item.path === targetPath) return { item, parent };
if (item.children?.length) {
const found = this.findMenuItemByPath(item.children, targetPath, item);
if (found) return found;
}
}
return null;
},
},
mounted() {
// console.log(this.$route.path,'this.$route.path----');
// const allItems = this.menuData.flatMap(menu =>menu.children ? menu.children?.map(child => ({ ...child, parentIndex: menu.index })) : menu.children);
// console.log(allItems,'=====');
// const current = allItems.find(item => item.path === this.$route.path);
// this.activeMenu = current ? current.index : '';
// this.defaultOpeneds = current ? [current.parentIndex] : [];
// this.routerList = this.$router.options.router;//
// console.log(this.$route.path, this.$router.options.router, 'this.$route.path===');
// //
// this.activeMenu = this.$route.path;
this.updateCurrentMenu();
}
}
</script>
<style lang="scss" scoped>
.menu-collapse-leave-active,
.menu-collapse-enter-active {
transition: all 0.5s;
}
.menu-collapse-enter,
.menu-collapse-leave-to {
opacity: 0;
transform: translateX(-30px);
}
.el-menu--vertical {
.el-menu-item {
height: 40px;
line-height: 40px;
}
.el-menu-item.is-active {
font-weight: bold;
}
}
.title_img {
width: 16px;
margin-right: 4px;
}
.title_text {
margin-left: 4px;
font-size: 14px;
font-weight: bold;
display: block;
}
.el-menu--collapse .title_text {
display: none;
}
.el-menu--collapse ::v-deep .el-submenu__icon-arrow {
display: none;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 158px;
min-width: 158px;
min-height: calc(100vh - 62px);
overflow-y: auto;
}
.el-menu-item {
padding: 0 22px;
font-size: 14px;
}
.menu-top {
background: #FFFFFF;
box-sizing: border-box;
/* middle/middle_line_1 */
border-width: 0px 0px 1px 0px;
border-style: solid;
border-color: #DFE2E6;
padding: 15px 0px;
margin: 0 22px;
display: flex;
font-size: 14px;
color: #1E2226;
font-weight: bold;
line-height: normal;
letter-spacing: 0.08em;
justify-content: space-between;
align-items: center;
img {
width: 14px;
height: 14px;
}
}
::v-deep .el-submenu {
// width: 16px;
font-size: 12px;
}
::v-deep .el-submenu .el-menu-item {
min-width: 138px;
width: 100%;
}
::v-deep .el-submenu__title {
display: flex;
align-items: center;
justify-content: flex-start;
}
::v-deep .el-submenu__title:hover {
background-color: transparent;
// cursor: not-allowed;
}
::v-deep .el-submenu__title .el-submenu__icon-arrow.el-icon-arrow-down {
// display: none;
}
::v-deep .el-submenu .el-menu-item {
padding: 0 22px;
display: flex;
justify-content: flex-start;
}
::v-deep .el-submenu .el-menu-item {
height: 36px;
}
::v-deep.el-submenu .el-menu-item {
height: 36px;
line-height: 36px;
color: #8A9099;
letter-spacing: 0.08em;
}
::v-deep .el-menu-item:hover {
background: #F6F7FA;
}
::v-deep .el-menu-item.is-active {
color: #006AFF;
font-weight: bold;
}
// .el-submenu .el-menu {
// transition: all 0.3s ease;
// }
// .el-menu--collapse .el-submenu > .el-menu {
// display: block !important;
// overflow: hidden;
// transition: all 0.3s ease;
// opacity: 0;
// height: 0;
// transform: translateY(-10px);
// }
// .el-menu--collapse .el-submenu.is-opened > .el-menu {
// opacity: 0;
// height: 0;
// }
</style>

13
examples/src/main.js

@ -1,13 +1,24 @@
import Vue from 'vue/dist/vue.esm.js' // 必须用完整版
import App from './App.vue'
import ElementUI from 'element-ui';
// import ZhichengUI from '@zhicheng1012/zhicheng-components'
// import '@zhicheng1012/zhicheng-components/dist/css/zhicheng-components.css';
import 'element-ui/lib/theme-chalk/index.css' // 如果依赖Element
import MyComponents from '../../packages' // 本地引用组件库
// import 'element-ui/lib/theme-chalk/index.css' // 如果依赖Element
// main.js
import 'core-js/stable'
// import './style/theme/index.css'
// import './style/theme/common.scss'
Vue.use(MyComponents)
Vue.use(ElementUI);
// Vue.use(ZhichengUI)
Vue.config.productionTip = false
new Vue({
render: h => h(App)

109
examples/src/table.vue

@ -0,0 +1,109 @@
<template>
<div>
<h3>测试表格</h3>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}],
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods:{
onSubmit() {
console.log('submit!');
}
}
}
</script>

1
examples/vue.config.js

@ -13,6 +13,7 @@ module.exports = {
alias: {
// 别名
'@assets': path.resolve(__dirname, '../packages/assets')
// '@': path.resolve(__dirname, './assets')
}
}
}

15670
package-lock.json

File diff suppressed because it is too large

25
package.json

@ -1,8 +1,8 @@
{
"name": "@zhicheng1012/zhicheng-components",
"version": "1.0.9",
"version": "1.0.28",
"description": "A Vue 2 component library",
"main": "dist/zhicheng-components.umd.js",
"main": "dist/js/zhicheng-components.umd.js",
"publishConfig": {
"access": "public"
},
@ -10,7 +10,7 @@
"**/*.css",
"**/*.scss"
],
"module": "dist/zhicheng-components.esm.js",
"module": "dist/js/zhicheng-components.esm.js",
"files": [
"dist",
"packages"
@ -23,11 +23,7 @@
"release": "npm version patch && npm publish"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/plugin-transform-runtime": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"babel-eslint": "~10.1.0",
"babel-loader": "^8.2.5",
"css-loader": "~5.2.7",
"eslint": "~6.8.0",
"eslint-plugin-vue": "~6.2.2",
@ -37,16 +33,16 @@
"sass-loader": "^8.0.2",
"style-loader": "~2.0.0",
"url-loader": "^4.1.1",
"vue": "^2.6.14",
"vue": "2.6.14",
"vue-loader": "^15.9.8",
"vue-svg-loader": "^0.16.0",
"vue-template-compiler": "^2.6.14",
"vue-template-compiler": "2.6.14",
"webpack": "~4.46.0",
"webpack-cli": "~4.10.0"
},
"peerDependencies": {
"element-ui": "^2.15.14",
"vue": "^2.6.14"
"element-ui": "2.15.14",
"vue": "2.6.14"
},
"browserslist": [
"> 1%",
@ -65,6 +61,13 @@
],
"license": "MIT",
"dependencies": {
"async-validator": "^1.11.5",
"core-js": "^3.40.0",
"vue-clickaway": "^2.2.2"
},
"resolutions": {
"core-js": "3.40.0",
"vue": "2.6.14",
"vue-template-compiler": "2.6.14"
}
}

37
packages/.eslintrc.js

@ -1,22 +1,17 @@
// .eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true
},
extends: [
'eslint:recommended',
'plugin:vue/essential'
],
parserOptions: {
ecmaVersion: 2018, // 改为 2018(兼容 Vue 2)
sourceType: 'module',
parser: 'babel-eslint'
},
rules: {
'vue/multi-word-component-names': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
env: {
browser: true,
es2021: true
},
extends: [
'eslint:recommended',
'plugin:vue/essential'
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module'
},
rules: {
'vue/multi-word-component-names': 'off'
}
}

7
packages/Breadcrumb/index.js

@ -0,0 +1,7 @@
import Breadcrumb from './src/index.vue'
Breadcrumb.install = function(Vue) {
Vue.component(Breadcrumb.name || 'Breadcrumb', Breadcrumb)
}
export default Breadcrumb

116
packages/Breadcrumb/src/index.vue

@ -0,0 +1,116 @@
<template>
<div v-if="breadcrumbs.length > 0" class="guip-breadcrumb-container flex-between">
<nav>
<ol class="breadcrumb">
<li
v-for="(item, index) in breadcrumbs"
:key="index"
class="breadcrumb-item"
:class="{ active: index === breadcrumbs.length - 1 }"
>
<template v-if="index !== breadcrumbs.length - 1">
<router-link to="/" v-if="item.title == '首页'">
<!-- <SvgIcon1 :iconPath="require(`../../assets/home-bread.png`)" defaultColor="#8A9099" :size="16" activeColor="#006AFF"/> -->
<img class="home-icon" src="../../assets/home-bread.png" alt="">
</router-link>
<router-link v-else :to="item.path">{{ item.title }}</router-link>
<img class="separator" src="../../assets/separator.png" alt="">
</template>
<template v-else>
<span>{{ item.title }}</span>
</template>
</li>
</ol>
</nav>
<div v-if="breadRightText" class="gap8 breadRight">
<img class="ml-8" src="../../assets/bind_sites.svg" alt="" />
站点简称<a :href="breadRightText">{{ breadRightText }}</a>
</div>
</div>
</template>
<script>
import SvgIcon1 from '../..//SvgIcon1';
export default {
name: 'Breadcrumb',
components: {
SvgIcon1,
},
computed: {
breadcrumbs() {
if (this.$route.meta.hideBreadcrumb) return [];
const crumbs = [
// {
// path:{
// path:'/',
// query:{uid: "2300"},
// params:{}
// },
// title:''
// },
// {
// path:{
// path: "/agent/siteList",
// query:{uid: "2300"},
// params:{}
// },
// title:""
// },
];
let currentRoute = this.$route;
////
while (currentRoute) {
//
// const matchedRoute = this.$router.options.routes.find(
// r => r.name === currentRoute.name
// );
//
const routeWithParams = {
path: currentRoute.path,
query: currentRoute.query,
params: currentRoute.params
};
crumbs.unshift({
path: routeWithParams,
title: this.getTitle(currentRoute)
});
// meta.breadcrumbParent
if (currentRoute.meta.breadcrumbParent) {
currentRoute = this.$router.options.routes.find(
r => r.name === currentRoute.meta.breadcrumbParent
);
// $route
if (currentRoute) {
currentRoute = {
...currentRoute,
path: currentRoute.path,
query: this.$route.query, //
params: this.$route.params, //
meta: currentRoute.meta || {}
};
}
} else {
currentRoute = null;
}
}
return crumbs;
},
breadRightText() {
return this.$store && this.$store.state.breadRightText
}
},
methods: {
getTitle(route) {
return typeof route.meta.title === 'function'
? route.meta.title(route)
: route.meta.title || route.name;
}
}
};
</script>

271
packages/CustomDropdown/src/index copy.vue

@ -1,271 +0,0 @@
<template>
<div class="custom-select" v-clickaway="closeDropdown" ref="dropdown" :class="{ 'is-open': isOpen }"
:style="{ width }">
<!-- 触发按钮 -->
<div class="select-trigger" @click="toggleDropdown">
<slot name="trigger">
{{ localSelected ? localSelected[displayKey] : placeholder }}
</slot>
<img class="arrow-icon"
:src="isOpen ? require('../../assets/dropDown_open.png') : require('../../assets/dropDown_expand.png')"
alt="">
</div>
<!-- 下拉内容 -->
<transition name="slide-fade">
<div v-if="isOpen" class="select-dropdown">
<slot v-if="isOpen" name="normal"></slot>
<div v-if="options">
<div v-for="(item, index) in options" :key="index" class="dropdown-item "
:class="{ 'is-selected': isSelected(item) }" @click="selectItem(item)">
<slot name="item" :item="item">
<div class="flex-between">
<div class="left">
<p class="one">{{ item[displayKey] }}</p>
</div>
<div class="right">
<img v-if="localSelected[displayKey] == item[displayKey]"
src="../../assets/drop-selected.svg" alt="">
</div>
</div>
</slot>
</div>
</div>
<div class="flex-between dropdown-item" v-if="options_null" @click="selectNullItem">
<div class="left">
<p class="one">暂无收款账号</p>
<p>暂时没有收款账号我想稍后配置</p>
</div>
<div class="right">
<img src="../../assets/drop-selected.svg" alt="">
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import { $emit, $on, $off } from '../../utils/eventBus'
export default {
name: 'CustomDropdown',
props: {
width: {
type: String,
default: "200px",
},
options: {
type: Array,
default: () => [],
},
options_null: {
type: Object,
default: () => { },
},
placeholder: {
type: String,
default: "请选择",
},
value: {
type: [String, Number, Object],
default: null,
},
valueKey: {
type: String,
default: "value",
},
displayKey: {
type: String,
default: "label",
},
},
data() {
return {
isOpen: false,
localSelected: null, //
isUpdating: false //
// selectedItem: null,
};
},
watch: {
value: {
immediate: true,
handler(val) {
//
if (!this.localSelected || this.localSelected[this.valueKey] !== val) {
this.localSelected = this.options.find(item => item[this.valueKey] === val);
}
}
}
},
computed: {
// selectedItem: {
// get() {
// // props
// return this.options.find(item => item[this.valueKey] === this.value) || null;
// },
// set(newVal) {
// //
// this.$emit('input', newVal ? newVal[this.valueKey] : null);
// this.$emit('change', newVal);
// }
// }
// selectedItem: {
// get() {
// if (this.isUpdating) return this._selectedItem;
// return this.options.find(item => item[this.valueKey] === this.value) || null;
// },
// set(newVal) {
// this.isUpdating = true;
// this._selectedItem = newVal;
// this.$nextTick(() => {
// this.$emit('input', newVal ? newVal[this.valueKey] : null);
// this.isUpdating = false;
// });
// }
// }
},
// data selectedItem watch
created() {
//
$on('close-all-dropdowns', this.closeDropdown)
},
beforeDestroy() {
//
$off('close-all-dropdowns', this.closeDropdown)
},
methods: {
closeDropdown() {
this.isOpen = false;
},
toggleDropdown(e) {
if (e) {
e.stopPropagation();
}
//
$emit('close-all-dropdowns')
this.isOpen = !this.isOpen;
},
// selectItem(item) {
// this.selectedItem = item;
// this.$emit("input", item[this.valueKey]); // Use the specified valueKey
// this.$emit("change", item);
// this.isOpen = false;
// },
// selectItem(item) {
// //
// this.$emit("input", item[this.valueKey]);
// this.$emit("change", item);
// //
// this.$nextTick(() => {
// this.selectedItem = item;
// this.isOpen = false;
// });
// },
selectItem(item) {
this.localSelected = item;
this.$emit('input', item[this.valueKey]);
this.$emit('change', item);
this.isOpen = false;
},
// selectItem(item) {
// this.selectedItem = item; // computed setter
// // this.$emit("change", item);
// this.isOpen = false;
// },
isSelected(item) {
return this.localSelected && this.localSelected[this.valueKey] === item[this.valueKey];
},
selectNullItem() {
this.$emit("changeNormal", '');
this.isOpen = false;
}
},
};
</script>
<style scoped>
/* Your existing styles remain the same */
.custom-select {
display: inline-block;
vertical-align: middle;
height: 38px;
position: relative;
font-family: Arial, sans-serif;
}
.select-trigger {
border-radius: 2px;
opacity: 1;
background: #FFFFFF;
border: 1px solid #DFE2E6;
width: 100%;
height: 40px;
box-sizing: border-box;
padding: 10px 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}
.is-open .select-trigger {
border: 1px solid #006AFF;
transition: all .5s;
outline: 3px solid #D8E9FA;
}
.select-trigger:hover {
border-color: #006AFF;
transition: all .5s;
}
.arrow-icon {
width: 12px;
}
.select-dropdown {
position: absolute;
top: 100%;
right: 0;
width: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-top: 4px;
max-height: 384px;
overflow-y: auto;
padding: 0 12px 12px 12px;
}
.dropdown-item {
padding: 12px 10px;
cursor: pointer;
}
.dropdown-item:hover {
background: #F6F7FA;
}
.dropdown-item.is-selected {
background-color: #F6F7FA;
color: #006AFF;
}
/* 展开收起动画 */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s ease;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
opacity: 0;
transform: translateY(-10px);
}
</style>

697
packages/CustomDropdown/src/index.vue

@ -1,328 +1,421 @@
<template>
<div class="custom-select"
v-clickaway="handleClickAway"
ref="dropdown"
:class="{ 'is-open': state.isOpen }"
:style="{ width: computedWidth }">
<!-- 触发按钮 -->
<div class="select-trigger" @click.stop="toggleDropdown">
<slot name="trigger">
{{ displayText }}
</slot>
<img class="arrow-icon"
:src="state.isOpen ? openIcon : expandIcon"
alt="dropdown indicator">
</div>
<!-- 下拉内容 -->
<transition name="slide-fade">
<div v-show="state.isOpen" class="select-dropdown">
<slot v-if="state.isOpen" name="normal"></slot>
<template v-if="filteredOptions.length">
<div v-for="(item, index) in filteredOptions"
:key="`option-${index}`"
class="dropdown-item"
:class="{ 'is-selected': isSelected(item) }"
@click.stop="selectItem(item)">
<slot name="item" :item="item">
<div class="flex-between">
<div class="left">
<p class="one">{{ item[displayKey] }}</p>
</div>
<div class="right">
<img v-if="isSelected(item)"
:src="selectedIcon"
alt="selected">
</div>
<div class="custom-select" v-clickaway="handleClickAway" ref="dropdown" :class="{ 'is-open': state.isOpen }"
:style="{ width: computedWidth }">
<!-- 触发按钮 -->
<div class="select-trigger" @click.stop="toggleDropdown">
<slot name="trigger">
{{ displayText }}
</slot>
<img class="arrow-icon" :src="state.isOpen ? openIcon : expandIcon" alt="dropdown indicator">
</div>
<!-- 下拉内容 -->
<transition name="slide-fade">
<div v-show="state.isOpen" class="select-dropdown">
<slot v-if="state.isOpen" name="normal"></slot>
<template v-if="filteredOptions.length">
<div v-for="(item, index) in filteredOptions" :key="`option-${index}`" class="dropdown-item"
:class="{ 'is-selected': isSelected(item) }" @click.stop="selectItem(item)">
<slot name="item" :item="item">
<div class="flex-between">
<div class="left">
<p class="one">{{ item[displayKey] }}</p>
</div>
<div class="right">
<img v-if="isSelected(item)" :src="selectedIcon" alt="selected">
</div>
</div>
</slot>
</div>
</template>
<div v-if="showNullOption" class="flex-between dropdown-item" @click.stop="selectNullItem">
<div class="left">
<p class="one">暂无收款账号</p>
<p>暂时没有收款账号我想稍后配置</p>
</div>
<div class="right">
<img :src="selectedIcon" alt="selected">
</div>
</div>
</slot>
</div>
</template>
<div v-if="showNullOption"
class="flex-between dropdown-item"
@click.stop="selectNullItem">
<div class="left">
<p class="one">暂无收款账号</p>
<p>暂时没有收款账号我想稍后配置</p>
</div>
<div class="right">
<img :src="selectedIcon" alt="selected">
</div>
</div>
</div>
</transition>
</transition>
</div>
</template>
<script>
// Webpack
const STATIC_ICONS = Object.freeze({
</template>
<script>
// Webpack
const STATIC_ICONS = Object.freeze({
expand: require('../../assets/dropDown_expand.png'),
open: require('../../assets/dropDown_open.png'),
selected: require('../../assets/drop-selected.svg')
})
export default {
})
export default {
name: 'CustomDropdown',
props: {
width: {
type: String,
default: "200px",
validator: (val) => /^\d+(px|%|rem|em|vw)$/.test(val)
},
options: {
type: Array,
default: () => [],
validator: (arr) => !arr.some(item => item === null || typeof item !== 'object')
},
nullOption: {
type: Object,
default: null
},
placeholder: {
type: String,
default: "请选择"
},
value: {
type: [String, Number, Object],
default: null
},
valueKey: {
type: String,
default: "value",
validator: (key) => typeof key === 'string' && key.trim().length > 0
},
displayKey: {
type: String,
default: "label",
validator: (key) => typeof key === 'string' && key.trim().length > 0
}
width: {
type: String,
default: "200px",
validator: (val) => /^\d+(px|%|rem|em|vw)$/.test(val)
},
options: {
type: Array,
default: () => [],
validator: (arr) => !arr.some(item => item === null || typeof item !== 'object')
},
nullOption: {
type: Object,
default: null
},
placeholder: {
type: String,
default: "请选择"
},
value: {
type: [String, Number, Object],
default: null
},
valueKey: {
type: String,
default: "value",
validator: (key) => typeof key === 'string' && key.trim().length > 0
},
displayKey: {
type: String,
default: "label",
validator: (key) => typeof key === 'string' && key.trim().length > 0
},
group: {
type: String,
default: null
},
},
// 使
data: () => ({
state: Object.seal({
isOpen: false,
lastEmittedValue: null,
updateDepth: 0,
eventLock: false
}),
icons: STATIC_ICONS
state: Object.seal({
isOpen: false,
lastEmittedValue: null,
updateDepth: 0,
eventLock: false
}),
icons: STATIC_ICONS
}),
computed: {
computedWidth() {
return this.width.endsWith('px') ? this.width : `${parseInt(this.width)}px`
},
filteredOptions() {
return Array.isArray(this.options) ? [...this.options] : []
},
showNullOption() {
return this.nullOption && !this.filteredOptions.length
},
displayText() {
const current = this.findOptionByValue(this.value)
return current ? current[this.displayKey] : this.placeholder
},
openIcon() {
return this.icons.open
},
expandIcon() {
return this.icons.expand
},
selectedIcon() {
return this.icons.selected
}
computedWidth() {
// console.log(this.width.endsWith('px'),this.width,'this.width.endsWith');
// return this.width.endsWith('px') ? this.width : `${parseInt(this.width)}px`
return this.width
},
filteredOptions() {
return Array.isArray(this.options) ? [...this.options] : []
},
showNullOption() {
return this.nullOption && !this.filteredOptions.length
},
displayText() {
const current = this.findOptionByValue(this.value)
return current ? current[this.displayKey] : this.placeholder
},
openIcon() {
return this.icons.open
},
expandIcon() {
return this.icons.expand
},
selectedIcon() {
return this.icons.selected
}
},
created() {
//
if (this.group) {
this.$busOn(`dropdown-group-${this.group}`, (openedId) => {
if (openedId !== this._uid && this.state.isOpen) {
this.closeDropdown();
}
});
}
// console.log(`Dropdown created with _uid:`, this._uid);
},
watch: {
value: {
immediate: true,
handler(newVal) {
if (this.state.eventLock) return
this.state.lastEmittedValue = JSON.stringify(newVal)
value: {
immediate: true,
handler(newVal) {
if (this.state.eventLock) return
this.state.lastEmittedValue = JSON.stringify(newVal)
}
}
}
},
methods: {
//
findOptionByValue(value) {
if (value === null || value === undefined) return null
return this.filteredOptions.find(item => {
return JSON.stringify(item[this.valueKey]) === JSON.stringify(value)
})
},
isSelected(item) {
if (!this.value) return false
return JSON.stringify(item[this.valueKey]) === JSON.stringify(this.value)
},
//
handleClickAway() {
if (!this.state.isOpen) return
//
findOptionByValue(value) {
if (value === null || value === undefined) return null
return this.filteredOptions.find(item => {
return JSON.stringify(item[this.valueKey]) === JSON.stringify(value)
})
},
isSelected(item) {
if (!this.value) return false
return JSON.stringify(item[this.valueKey]) === JSON.stringify(this.value)
},
//
// handleClickAway() {
// // console.log(this.state.isOpen,'1111----');
// // if (!this.state.isOpen) return
// // console.log(this.state.isOpen,'2222----');
// // this.state.isOpen = false
// // console.log(this.state.isOpen,'333----');
// // this.$nextTick(() => {
// // this.$busEmit('closed')
// // })
// //
// if (this.$refs.dropdown.contains(event.target)) return;
// if (this.state.isOpen) {
// this.state.isOpen = false;
// this.$busEmit('closed');
// }
// },
toggleDropdown() {
console.log('Toggling dropdown, current state:', this.state.isOpen)
if (this.state.eventLock) return
//
// this.state.isOpen = !this.state.isOpen
//
console.log('New state:', this.state.isOpen)
console.log('Dropdown element:', this.$refs.dropdown)
//
// if (this.state.isOpen) {
// // this.$busEmit('opened')
// this.openDropdown();
// } else {
// this.closeDropdown();
// this.$busEmit('closed')
// }
if (this.state.isOpen) {
this.closeDropdown();
} else {
this.openDropdown();
}
//
this.$forceUpdate()
},
//
closeDropdown() {
this.state.isOpen = false;
this.$busEmit('closed');
this.$emit('closed');
},
this.state.isOpen = false
this.$nextTick(() => {
this.$emit('closed')
})
},
//
toggleDropdown() {
if (this.state.eventLock) return
//
openDropdown() {
//
if (this.group) {
this.$busEmit(`dropdown-group-${this.group}`, this._uid);
}
this.state.isOpen = true;
this.$busEmit('opened');
this.$emit('opened');
},
if (this.state.isOpen) {
this.handleClickAway()
} else {
this.$emit('opened')
this.state.isOpen = true
}
},
//
selectItem(item) {
if (this.state.updateDepth > 1) {
console.error('Recursion detected in dropdown selection')
this.state.isOpen = false
this.state.updateDepth = 0
return
}
const newValue = item[this.valueKey]
//
// toggleDropdown() {
// if (this.state.eventLock) return;
// if (this.state.isOpen) {
// this.closeDropdown();
// } else {
// this.openDropdown();
// }
// },
//
if (this.state.lastEmittedValue === JSON.stringify(newValue)) {
this.state.isOpen = false
return
//
handleClickAway(event) {
//
// debugger
// const trigger = this.$el.querySelector('.select-trigger');
// if (trigger && trigger.contains(event.target)) return;
// if (this.state.isOpen) {
// this.closeDropdown();
// }
console.log('Before:', {
isOpen: this.state.isOpen,
display: this.$refs.dropdown.querySelector('.select-dropdown').style.display
});
//
const dropdownEl = this.$refs.dropdown.querySelector('.select-dropdown');
const isActuallyVisible = dropdownEl &&
(dropdownEl.style.display !== 'none');
if (isActuallyVisible && !this.state.isOpen) {
//
this.state.isOpen = true;
this.$nextTick(() => {
this.closeDropdown();
});
return;
}
//
if (this.state.isOpen) {
this.closeDropdown();
}
},
//
selectItem(item) {
if (this.state.updateDepth > 1) {
console.error('Recursion detected in dropdown selection')
this.state.isOpen = false
this.state.updateDepth = 0
return
}
const newValue = item[this.valueKey]
//
if (this.state.lastEmittedValue === JSON.stringify(newValue)) {
this.state.isOpen = false
return
}
this.state.updateDepth++
this.state.eventLock = true
this.state.lastEmittedValue = JSON.stringify(newValue)
// 使setTimeout
setTimeout(() => {
try {
this.$emit('input', newValue)
this.$emit('change', Object.freeze({ ...item }))
} catch (e) {
console.error('Dropdown emit error:', e)
} finally {
this.state.isOpen = false
this.state.updateDepth = 0
this.state.eventLock = false
}
}, 0)
},
selectNullItem() {
this.state.eventLock = true
this.state.lastEmittedValue = null
setTimeout(() => {
this.$emit('input', null)
this.$emit('change', null)
this.state.isOpen = false
this.state.eventLock = false
}, 0)
}
this.state.updateDepth++
this.state.eventLock = true
this.state.lastEmittedValue = JSON.stringify(newValue)
// 使setTimeout
setTimeout(() => {
try {
this.$emit('input', newValue)
this.$emit('change', Object.freeze({ ...item }))
} catch (e) {
console.error('Dropdown emit error:', e)
} finally {
this.state.isOpen = false
this.state.updateDepth = 0
this.state.eventLock = false
}
}, 0)
},
selectNullItem() {
this.state.eventLock = true
this.state.lastEmittedValue = null
setTimeout(() => {
this.$emit('input', null)
this.$emit('change', null)
this.state.isOpen = false
this.state.eventLock = false
}, 0)
}
},
//
created() {
this.$_performanceMark = `dropdown-${Date.now()}`
performance.mark(this.$_performanceMark)
},
beforeDestroy() {
performance.measure('dropdown-lifetime', this.$_performanceMark)
if (this.group) {
this.$busOff(`dropdown-group-${this.group}`);
}
// performance.measure('dropdown-lifetime', this.$_performanceMark)
}
}
</script>
<style scoped lang="scss">
/* Your existing styles remain the same */
.custom-select {
display: inline-block;
vertical-align: middle;
height: 38px;
position: relative;
font-family: Arial, sans-serif;
}
.select-trigger {
border-radius: 2px;
opacity: 1;
background: #FFFFFF;
border: 1px solid #DFE2E6;
width: 100%;
height: 40px;
box-sizing: border-box;
padding: 10px 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}
.is-open .select-trigger {
border: 1px solid #006AFF;
transition: all .5s;
outline: 3px solid #D8E9FA;
}
.select-trigger:hover {
border-color: #006AFF;
transition: all .5s;
}
.arrow-icon {
width: 12px;
}
.select-dropdown {
position: absolute;
top: 100%;
right: 0;
width: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-top: 4px;
max-height: 384px;
overflow-y: auto;
padding: 0 12px 12px 12px;
}
.dropdown-item {
padding: 12px 10px;
cursor: pointer;
}
.dropdown-item:hover {
background: #F6F7FA;
}
.dropdown-item.is-selected {
background-color: #F6F7FA;
color: #006AFF;
}
/* 展开收起动画 */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s ease;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
opacity: 0;
transform: translateY(-10px);
}
</style>
}
</script>
<style scoped lang="scss">
/* Your existing styles remain the same */
.custom-select {
display: inline-block;
vertical-align: middle;
height: 38px;
position: relative;
font-family: Arial, sans-serif;
}
.select-trigger {
border-radius: 2px;
opacity: 1;
background: #FFFFFF;
border: 1px solid #DFE2E6;
width: 100%;
height: 40px;
box-sizing: border-box;
padding: 10px 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}
.is-open .select-trigger {
border: 1px solid #006AFF;
transition: all .5s;
outline: 3px solid #D8E9FA;
}
.select-trigger:hover {
border-color: #006AFF;
transition: all .5s;
}
.arrow-icon {
width: 12px;
}
.select-dropdown {
position: absolute;
top: 100%;
right: 0;
width: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-top: 4px;
max-height: 384px;
overflow-y: auto;
padding: 0 12px 12px 12px;
}
.dropdown-item {
padding: 12px 10px;
cursor: pointer;
}
.dropdown-item:hover {
background: #F6F7FA;
}
.dropdown-item.is-selected {
background-color: #F6F7FA;
color: #006AFF;
}
/* 展开收起动画 */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s ease;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
opacity: 0;
transform: translateY(-10px);
}
</style>

64
packages/DevicePreview/src/index.scss

@ -0,0 +1,64 @@
.preview-container {
max-width: 800px;
min-width: 300px;
margin: 0 auto;
padding: 24px;
border-radius: 4px;
background: #FAFAFA;
.preview_top {
margin-bottom: 20px;
}
.preview-title {
text-align: center;
color: #1E2226;
}
.toggle-container {
display: flex;
height: 26px;
justify-content: center;
align-items: center;
padding: 3px 6px;
border-radius: 4px;
background: #F2F3F5;
}
.toggle-button {
padding: 1px 12px;
border-radius: 2px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.3s ease;
}
.toggle-button.active {
color: #006AFF;
background: #FFFFFF;
}
.toggle-button.active:after {
/* content: '';
position: absolute;
bottom: -11px;
left: 0;
width: 100%;
height: 2px;
background-color: #1890ff; */
}
.content-container {
/* min-height: 300px;
padding: 20px;
border: 2px solid #ffd700;
border-radius: 4px;
background-color: #fff; */
}
.desktop-view,
.mobile-view {
width: 100%;
}
}

69
packages/DevicePreview/src/index.vue

@ -1,5 +1,5 @@
<template>
<div class="preview-container">
<div class="guip-preview-container">
<div class="preview_top flex-between">
<b class="preview-title">实时预览</b>
<div class="toggle-container">
@ -52,69 +52,4 @@ export default {
}
}
}
</script>
<style scoped>
.preview-container {
max-width: 800px;
min-width: 300px;
margin: 0 auto;
padding: 24px;
border-radius: 4px;
background: #FAFAFA;
}
.preview_top{
margin-bottom: 20px;
}
.preview-title {
text-align: center;
color: #1E2226;
}
.toggle-container {
display: flex;
height: 26px;
justify-content: center;
align-items: center;
padding: 3px 6px;
border-radius: 4px;
background: #F2F3F5;
}
.toggle-button {
padding: 1px 12px;
border-radius: 2px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.3s ease;
}
.toggle-button.active {
color: #006AFF;
background: #FFFFFF;
}
.toggle-button.active:after {
/* content: '';
position: absolute;
bottom: -11px;
left: 0;
width: 100%;
height: 2px;
background-color: #1890ff; */
}
.content-container {
/* min-height: 300px;
padding: 20px;
border: 2px solid #ffd700;
border-radius: 4px;
background-color: #fff; */
}
.desktop-view,
.mobile-view {
width: 100%;
}
</style>
</script>

139
packages/GuipDialog/src/index.vue

@ -1,27 +1,33 @@
<template>
<el-dialog :visible.sync="dialogShow" :title="title" v-bind="$attrs" append-to-body :width="width"
:show-close="showCloseButton" :before-close="handleClose" :class="type == 'center' ? 'center' : 'normal'">
<!-- 自定义内容 -->
<slot></slot>
<!-- 底部按钮 -->
<span v-if="showFooterButton" slot="footer"
:class="[type == 'center' ? 'dialog-footer-center' : 'dialog-footer-normal', 'flex']"
style="justify-content: space-between;">
<GuipButton v-if="showCancelButton" @click="handleCancel" type="ignore">{{ cancelText }}</GuipButton>
<GuipButton type="primary" @click="handleConfirm">{{ confirmText }}</GuipButton>
</span>
<el-dialog
:visible.sync="dialogShow"
:title="title"
v-bind="$attrs"
append-to-body
:width="width"
:show-close="showCloseButton"
:before-close="handleClose"
:class="type == 'center' ?'center' : 'normal'"
>
<!-- 自定义内容 -->
<slot></slot>
<!-- 底部按钮 -->
<span v-if="showFooterButton" slot="footer" :class="[type == 'center' ? 'dialog-footer-center' : 'dialog-footer-normal', 'flex']" style="justify-content: space-between;">
<GuipButton v-if="showCancelButton" @click="handleCancel" type="ignore" >{{ cancelText }}</GuipButton>
<GuipButton type="primary" @click="handleConfirm">{{ confirmText }}</GuipButton>
</span>
</el-dialog>
</template>
<script>
import GuipButton from '../../GuipButton/src/index.vue';
import GuipButton from '../../GuipButton';
export default {
name: 'GuipDialog',
props: {
type: {
type: String,
default: 'normal'
type:{
type:String,
default:'normal'
},
//
dialogVisible: {
@ -38,17 +44,17 @@ export default {
type: String,
default: '599px',
},
//
showCloseButton: {
//
showCloseButton: {
type: Boolean,
default: true,
},
},
//
showCancelButton: {
type: Boolean,
default: true,
},
//
//
showFooterButton: {
type: Boolean,
default: true,
@ -64,68 +70,55 @@ export default {
default: '确定',
},
},
components: {
GuipButton
components:{
GuipButton
},
computed: {
dialogShow: {
get() {
return this.dialogVisible;
},
set(newVal) {
this.$emit('dialogVisibleChange', newVal);
dialogShow: {
get() {
return this.dialogVisible;
},
set(newVal) {
this.$emit('dialogVisibleChange', newVal);
}
}
}
},
data() {
return {
// visible
internalVisible: this.visible,
// dialogVisible:false,
};
return {
// visible
internalVisible: this.visible,
// dialogVisible:false,
};
},
watch: {
// // prop internalVisible
// visible(newVal) {
// this.internalVisible = newVal;
// },
// // internalVisible
// internalVisible(newVal) {
// this.$emit('update:visible', newVal);
// },
},
// // prop internalVisible
// visible(newVal) {
// this.internalVisible = newVal;
// },
// // internalVisible
// internalVisible(newVal) {
// this.$emit('update:visible', newVal);
// },
},
methods: {
//
handleClose(done) {
this.$emit('close');
this.internalVisible = false; //
if (done) {
done();
}
},
//
handleCancel() {
this.$emit('cancel');
this.internalVisible = false; //
},
//
handleConfirm() {
this.$emit('confirm');
this.internalVisible = false; //
},
//
handleClose(done) {
this.$emit('close');
this.internalVisible = false; //
if(done){
done();
}
},
//
handleCancel() {
this.$emit('cancel');
this.internalVisible = false; //
},
//
handleConfirm() {
this.$emit('confirm');
this.internalVisible = false; //
},
},
};
</script>
<style scoped lang="scss">
.el-dialog {
/* width: 599px; */
// min-height: 344px;
// .el-dialog__header{
// padding: 32px 32px 12px;
// }
// .el-dialog__body{
// padding: 0 32px 32px;
// }
}
</style>

17
packages/GuipInput/src/index.vue

@ -6,7 +6,7 @@
<el-input :type="type" v-bind="$attrs" :placeholder="placeholder1" :disabled="disabled" :maxlength="maxlength1"
:style="{ width: width, height: height }" :value="inputValue" :minLength="minLength1" :show-word-limit="showWordLimit"
@input="$emit('input', $event)" @keydown="handleKeydown" @change="$emit('change', $event)"
@blur="$emit('blur', inputValue)" @focus="$emit('focus', inputValue)" >
@blur="$emit('blur', inputValue)" @focus="$emit('focus', inputValue)" class="guip-input">
<!-- 自定义前面小图标 -->
<template v-slot:prepend>
<slot name="prependshow"></slot>
@ -28,7 +28,7 @@
<!-- <el-button slot="append" v-if="hasBtn" type="primary" @click="$emit('enter',value)">搜索</el-button> -->
</el-input>
<!-- 单位 -->
<span class="unit" v-if="unit">{{ unit }}</span>
<span class="guip-input-unit" v-if="unit">{{ unit }}</span>
</el-form-item>
</template>
@ -136,15 +136,4 @@ export default {
},
}
}
</script>
<style lang="scss" scoped>
.unit {
position: absolute;
right: 12px;
/* 根据需要调整位置 */
top: 50%;
transform: translateY(-50%);
pointer-events: none;
/* 防止单位文本影响输入框的点击事件 */
}
</style>
</script>

65
packages/GuipMessage/index.js

@ -0,0 +1,65 @@
import Vue from 'vue'
import GuipMessage from './src/index.vue'
const defaultIcons = {
success: 'icon-success',
info: 'icon-info',
warning: 'icon-warning',
error: 'icon-error'
}
const defaultImages = {
success: require('../assets/message_Success.png'),
info: require('../assets/message_Warning.png'),
warning: require('../assets/message_Warning.png'),
error: require('../assets/message_error.png')
}
const MessageConstructor = Vue.extend(GuipMessage)
let messageQueue = []
const showMessage = (options) => {
if (typeof options === 'string') {
options = { message: options }
}
const config = {
type: 'info',
duration: 3000,
position: 'top-center',
showImage: true,
...options
}
if (config.showImage) {
config.imageUrl = options.imageUrl || defaultImages[config.type]
} else {
config.iconClass = options.iconClass || defaultIcons[config.type]
}
const instance = new MessageConstructor({
propsData: config
}).$mount()
document.body.appendChild(instance.$el)
messageQueue.push(instance)
return {
close: () => instance.close()
}
}
// 添加类型快捷方法
['success', 'info', 'warning', 'error'].forEach(type => {
showMessage[type] = (message, options = {}) => {
return showMessage({ message, type, ...options })
}
})
// 添加关闭所有方法
showMessage.closeAll = () => {
messageQueue.forEach(instance => instance.close())
messageQueue = []
}
export default showMessage

72
packages/GuipMessage/src/index.vue

@ -0,0 +1,72 @@
<template>
<transition name="fade">
<div v-if="visible" class="guip-custom-message" :class="[type, position]">
<img v-if="showImage" :src="imageUrl" class="message-image" />
<i v-else :class="iconClass"></i>
<span class="message-content">{{ message }}</span>
</div>
</transition>
</template>
<script>
export default {
name: 'GuipMessage',
props: {
type: {
type: String,
default: 'info',
validator: value => ['success', 'warning', 'error', 'info'].includes(value)
},
message: {
type: String,
required: true
},
duration: {
type: Number,
default: 3000
},
position: {
type: String,
default: 'top-center',
validator: value => ['top-center', 'top-right', 'top-left', 'bottom-center', 'bottom-right', 'bottom-left'].includes(value)
},
showImage: {
type: Boolean,
default: false
},
imageUrl: {
type: String,
default: ''
},
iconClass: {
type: String,
default: ''
}
},
data() {
return {
visible: false
}
},
mounted() {
this.visible = true
this.startTimer()
},
methods: {
startTimer() {
if (this.duration > 0) {
setTimeout(() => {
this.close()
}, this.duration)
}
},
close() {
this.visible = false
setTimeout(() => {
this.$destroy()
this.$el.parentNode.removeChild(this.$el)
}, 300)
}
}
}
</script>

22
packages/GuipRadio/src/index.vue

@ -12,7 +12,7 @@
<script>
export default {
name: 'MyRadioGroup',
name: 'GuipRadio',
props: {
//
column: {
@ -138,10 +138,16 @@ export default {
//
const isSelected = this.getValue(option) === this.selectedValue;
// selectedLabellabelKey
return isSelected && option[this.selectedLabelKey]
? option[this.selectedLabelKey]
: option[this.labelKey] || option;
// selectedLabel
if (isSelected && option[this.selectedLabelKey]) {
return option[this.selectedLabelKey];
}
// labelKey
if (typeof option === 'object' && this.labelKey in option) {
return option[this.labelKey];
}
return option;
},
getValue(option) {
//
@ -149,7 +155,11 @@ export default {
return option.key;
}
return option[this.valueKey] || option;
// valueKey
if (typeof option === 'object' && this.valueKey in option) {
return option[this.valueKey];
}
return option;
},
//
isDisabled(key) {

20
packages/GuipSelect/src/index.vue

@ -18,7 +18,7 @@ export default {
props: {
value: [String, Number, Array],
options: {
type: Array,
type: [Array,Object],
default: () => []
},
//
@ -58,9 +58,25 @@ export default {
}
},
computed: {
// options
processedOptions() {
// options
let options = this.options || [];
// [1,12,22]
if (Array.isArray(options) && options.every(item => typeof item !== 'object')) {
return options.map((item, index) => ({
[this.valueKey]: index,
[this.labelKey]: item
}));
}
//
if (options && !Array.isArray(options)) {
options = Object.keys(options).map(key => ({
[this.valueKey]: key,
[this.labelKey]: options[key]
}));
}
// extraItemoptions
if (this.extraItem && Object.keys(this.extraItem).length > 0) {
return [

7
packages/GuipSwitch/index.js

@ -0,0 +1,7 @@
import GuipSwitch from './src/index.vue'
GuipSwitch.install = function(Vue) {
Vue.component(GuipSwitch.name || 'GuipSwitch', GuipSwitch)
}
export default GuipSwitch

109
packages/GuipSwitch/src/index.vue

@ -0,0 +1,109 @@
<template>
<el-form-item :prop="prop" :label="label" :rules="rules">
<div class="guip_switchWrap">
<span :class="['switchDesc', { 'fl': float == 'left' }, { 'fr': float == 'right' }]"
v-if="activeText || inactiveText">
{{ internalValue === activeValue ? activeText : inactiveText
}}</span>
<el-switch v-model="internalValue" :active-color="activeColor" :inactive-color="inactiveColor"
v-bind="$attrs" :disabled="disabled" :active-value="activeValue" :inactive-value="inactiveValue"
@change="handleChange">
<!-- 自定义开启时的图标 -->
<template #active-icon>
</template>
<!-- 自定义关闭时的图标 -->
<template #inactive-icon>
</template>
</el-switch>
</div>
</el-form-item>
</template>
<script>
export default {
name: 'GuipSwitch',
inheritAttrs: false,
props: {
// modelValue: { type: [Boolean, String, Number], default: undefined },
value: { type: [Boolean, String, Number], default: undefined },
prop: String,
label: String,
rules: Array,
labelWidth: String,
activeText: {
type: String,
default: '',
},
inactiveText: {
type: String,
default: '',
},
activeValue: {
type: [Boolean, String, Number],
default: true,
},
inactiveValue: {
type: [Boolean, String, Number],
default: false,
},
activeColor: {
type: String,
default: '#00C261',
},
inactiveColor: {
type: String,
default: '#BABDC2',
},
float: {
type: String,
default: 'left',
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
internalValue: this.value,
errorMsg: ''
}
},
computed: {
// internalValue: {
// get() {
// return this.modelValue !== undefined ? this.modelValue : this.value
// },
// set(val) {
// this.$emit('update:modelValue', val)
// this.$emit('input', val)
// }
// }
},
watch: {
value(newVal) {
this.internalValue = newVal
},
// modelValue(newVal) {
// this.internalValue = newVal
// },
},
methods: {
handleChange(val) {
// this.$emit('update:modelValue', val)
this.$emit('input', val)
this.$emit('change', val)
this.validateField()
},
validateField() {
if (this.prop && this.$parent.validateField) {
this.$parent.validateField(this.prop, (error) => {
this.errorMsg = error || ''
})
}
}
}
}
</script>

7
packages/GuipTable/index.js

@ -0,0 +1,7 @@
import GuipTable from './src/index.vue'
GuipTable.install = function(Vue) {
Vue.component(GuipTable.name || 'GuipTable', GuipTable)
}
export default GuipTable

145
packages/GuipTable/src/index.vue

@ -0,0 +1,145 @@
<template>
<div class="table-container">
<el-table ref="guiptable" v-bind="$attrs" :data="tableData" v-on="$listeners" :border="border" @selection-change="handleSelectionChange"
:style="{ width: width ? width : '100%', height: height ? height : '100%' }" v-loading="loading" empty-text=" ">
<!-- 多选 -->
<template v-if="multiple">
<el-table-column type="selection" width="55">
</el-table-column>
</template>
<!-- 自定义header -->
<slot></slot>
<!-- 通过json数据遍历渲染 -->
<template v-if="columns">
<el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
:width="column.width">
<template #default="{ row }" v-if="column.popover">
<el-popover :visible="row[`popoverVisible_${column.prop}`]" class="tablePopover" placement="top"
trigger="click">
<!-- 自定义内容插槽 -->
<slot :name="`popover-content-${column.prop}`" :row="row" :column="column">
<div>
<p>默认内容{{ `popoverVisible_${column.prop}` }}</p>
<el-input v-model="row[`edit_${column.prop}`]" :placeholder="`请输入${column.label}`" />
</div>
</slot>
<!-- 确定和取消按钮 -->
<div class="flex" style="text-align: right; margin-top: 32px;justify-content: flex-end;">
<GuipButton size="medium" @click="handleCancel(row, column.prop)">取消</GuipButton>
<GuipButton type="primary" @click="handleConfirm(row, column.prop)" size="medium">确定</GuipButton>
</div>
<!-- 单元格内容 -->
<template #reference>
<span style="cursor: pointer">{{ row[column.prop] }}</span>
</template>
</el-popover>
</template>
</el-table-column>
</template>
</el-table>
<div v-if="tableData && tableData.length === 0" class="custom-empty">
<img :src="emptyImg" alt="无数据" />
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import GuipButton from '../../GuipButton/src/index.vue';
export default {
name: 'GuipTextarea',
props: ['tableData', 'loading', 'width', 'height', 'autoColumn', 'columns', 'border', 'multiple'],
data() {
return {
emptyImg:require('../../assets/table_empty.png')
// loading:false
}
},
components: {
GuipButton,
},
mounted() {
},
methods: {
handleSelectionChange(row) {
//
console.log(row, '======');
this.$emit('selectChange', row)
},
//
handleConfirm(row, prop) {
//
row[prop] = row[`edit_${prop}`];
row[`popoverVisible_${prop}`] = false; //
this.$emit('confirm', row, prop); //
},
//
handleCancel(row, prop) {
//
row[`edit_${prop}`] = row[prop];
row[`popoverVisible_${prop}`] = false; //
this.$emit('cancel', row, prop); //
},
}
}
</script>
<style scoped lang="scss">
/* 外层容器需设为 relative,以便空状态定位 */
.table-container {
position: relative;
width: 100%;
}
/* 空状态固定定位(不随滚动移动) */
.custom-empty {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -35%);
width: 200px;
text-align: center;
background-color: #fff; /* 避免透明背景被表格线干扰 */
// padding: 20px;
z-index: 10; /* 确保显示在表格上方 */
img{
width: 80px;
height: 80px;
}
p{
font-size: 12px;
font-weight: normal;
line-height: 13px;
letter-spacing: 0.08em;
color: #626573;
}
}
/* 确保表格有最小高度(避免高度塌陷) */
.el-table ::v-deep .el-table__body-wrapper {
min-height: 162px !important;
}
.empty-image {
width: 160px;
height: 160px;
}
.empty-text {
color: #626573;
letter-spacing: 0.08em;
height: 18px;
line-height: 18px;
}
.el-empty{
padding: 0;
}
.guip-table ::v-deep .el-empty__description{
line-height: 20px;
margin-top: 0;
}
</style>

7
packages/GuipToolTip/index.js

@ -0,0 +1,7 @@
import GuipToolTip from './src/index.vue'
GuipToolTip.install = function(Vue) {
Vue.component(GuipToolTip.name || 'GuipToolTip', GuipToolTip)
}
export default GuipToolTip;

104
packages/GuipToolTip/src/index.vue

@ -0,0 +1,104 @@
<template>
<el-tooltip
v-bind="mergedProps"
:disabled="disabled"
:visible="controlledVisible"
@show="handleShow"
@hide="handleHide"
>
<slot></slot>
<!-- 用于自定义提示内容 -->
<template v-if="$slots.content" #content>
<slot name="content"></slot>
</template>
</el-tooltip>
</template>
<script>
export default {
name: 'GuipToolTip',
props: {
content: String,
placement: {//
type: String,
default: 'top'
},
effect: {//
type: String,
default: 'dark'
},
disabled: Boolean,
// true/
manual: Boolean,
// /
openDelay: {
type: Number,
default: 0
},
closeDelay: {
type: Number,
default: 0
},
//
hideAfterClick: {
type: Boolean,
default: false
}
},
data() {
return {
controlledVisible: false
}
},
computed: {
mergedProps() {
return {
effect: this.effect,
placement: this.placement,
content: this.content,
openDelay: this.openDelay,
closeDelay: this.closeDelay,
hideAfterClick: this.hideAfterClick,
...this.$attrs
}
}
},
methods: {
handleShow() {
if (this.manual) {
this.controlledVisible = true
}
this.$emit('show')
},
handleHide() {
if (this.manual) {
this.controlledVisible = false
}
this.$emit('hide')
},
//
show() {
if (this.manual && !this.disabled) {
this.controlledVisible = true
}
},
//
hide() {
if (this.manual) {
this.controlledVisible = false
}
},
// /
toggle() {
if (this.manual && !this.disabled) {
this.controlledVisible = !this.controlledVisible
}
}
}
}
</script>
<style scoped>
/* 可以添加一些自定义样式 */
</style>

1
packages/PromptText/index.js

@ -1,5 +1,4 @@
import PromptText from './src/index.vue'
PromptText.install = function(Vue) {
Vue.component(PromptText.name || 'PromptText', PromptText)
}

41
packages/PromptText/src/index.scss

@ -0,0 +1,41 @@
.prompt-text {
padding: 8px 13px;
border-radius: 4px;
.flex-text {
display: flex;
align-items: center;
align-self: stretch;
justify-content: space-between;
z-index: 1;
}
.prompt-icon {
width: 16px;
height: 16px;
;
margin-right: 8px;
}
.prompt-desc {
color: #1E2226;
letter-spacing: 0.08em;
}
.prompt-extra {}
}
.prompt-text.info {
background: #F2F7FF;
border: 1px solid #BFDAFF;
}
.prompt-text.notice {
background: #FEFCE8;
border: 1px solid rgba(255, 140, 0, 0.3);
}
.prompt-text.warning {
background: #FFF1F0;
border: 1px solid #FFA39E;
}

49
packages/PromptText/src/index.vue

@ -1,5 +1,5 @@
<template>
<div class="prompt-text" :class="typeClass">
<div class="guip-prompt-text" :class="typeClass">
<div class="flex-text">
<div class="flex">
<img class="prompt-icon" :src="typeIcon" alt="">
@ -15,7 +15,7 @@
</div>
</template>
<script>
import './index.scss'
export default {
name: 'PromptText',
props: {
@ -55,47 +55,4 @@ export default {
}
}
</script>
<style scoped lang="scss">
.prompt-text {
padding: 8px 13px;
border-radius: 4px;
}
.flex-text {
display: flex;
align-items: center;
align-self: stretch;
justify-content: space-between;
z-index: 1;
}
.info {
background: #F2F7FF;
border: 1px solid #BFDAFF;
}
.notice {
background: #FEFCE8;
border: 1px solid rgba(255, 140, 0, 0.3);
}
.warning {
background: #FFF1F0;
border: 1px solid #FFA39E;
}
.prompt-icon {
width: 16px;
height: 16px;
;
margin-right: 8px;
}
.prompt-desc {
color: #1E2226;
letter-spacing: 0.08em;
}
.prompt-extra {}
</style>
</script>

7
packages/SvgIcon/index.js

@ -0,0 +1,7 @@
import SvgIcon from './src/index.vue'
SvgIcon.install = function(Vue) {
Vue.component(SvgIcon.name || 'SvgIcon', SvgIcon)
}
export default SvgIcon

126
packages/SvgIcon/src/index.vue

@ -0,0 +1,126 @@
<template>
<div
class="guip-svg-icon-wrapper"
:style="{ width: size + 'px', height: size + 'px' }"
@click="handleClick"
@mouseenter="isHovered = true"
@mouseleave="isHovered = false"
>
<div
class="svg-icon"
v-html="svgContent"
:style="{
'--icon-color': isHovered ? hoverColor : color,
'--icon-hover-color': hoverColor
}"
></div>
</div>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
// SVG
path: {
type: String,
required: true,
validator: value => value.endsWith('.svg')
},
//
size: {
type: Number,
default: 24
},
//
color: {
type: String,
default: '#333333'
},
//
hoverColor: {
type: String,
default: '#409EFF'
},
//
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
svgContent: '',
isHovered: false
}
},
watch: {
path: {
immediate: true,
handler: 'loadSvg'
}
},
methods: {
async loadSvg() {
try {
// 使importSVG
const response = await fetch(this.path)
if (!response.ok) throw new Error('SVG加载失败')
this.svgContent = await response.text()
// SVGfillcurrentColor便CSS
this.svgContent = this.svgContent.replace(/fill="[^"]*"/g, 'fill="currentColor"')
} catch (error) {
console.error('加载SVG图标失败:', error)
this.svgContent = ''
}
},
handleClick(event) {
if (!this.disabled) {
this.$emit('click', event)
}
}
}
}
</script>
<style scoped>
/* .svg-icon-wrapper1 {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s;
}
.svg-icon-wrapper1:hover {
opacity: 0.8;
}
.svg-icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--icon-color);
transition: color 0.3s;
}
.svg-icon:hover {
color: var(--icon-hover-color);
}
.svg-icon-wrapper1[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
.svg-icon >>> path {
fill: currentColor;
}
.svg-icon >>> circle {
fill: currentColor;
} */
</style>

7
packages/SvgIcon1/index.js

@ -0,0 +1,7 @@
import SvgIcon1 from './src/index.vue'
SvgIcon1.install = function(Vue) {
Vue.component(SvgIcon1.name || 'SvgIcon1', SvgIcon1)
}
export default SvgIcon1

167
packages/SvgIcon1/src/index.vue

@ -0,0 +1,167 @@
<template>
<div class="guip-svg-icon-wrapper1" :style="wrapperStyle" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
<div class="svg-icon" v-html="svgContent" :style="{
'--icon-color': (hoverEffect || isActive) ? activeColor : defaultColor,
'--icon-hover-color': activeColor
}"></div>
<!-- :style="iconStyle" -->
</div>
</template>
<script>
export default {
name: 'SvgIcon1',
props: {
//
iconPath: {
type: String,
required: true
},
//
defaultColor: {
type: String,
default: '#606266'
},
//
activeColor: {
type: String,
default: null
},
//
hoverEffect: {
type: Boolean,
default: false
},
//
size: {
type: [String, Number],
default: '14px'
},
//
isActive: {
type: Boolean,
default: false
}
},
data() {
return {
svgContent: '',
isHovering: false,
currentColor: this.defaultColor
}
},
computed: {
wrapperStyle() {
return {
width: typeof this.size === 'number' ? `${this.size}px` : this.size,
height: typeof this.size === 'number' ? `${this.size}px` : this.size,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center'
}
},
iconStyle() {
return {
width: '100%',
height: '100%',
color: this.currentColor,
transition: 'color 0.3s ease'
}
},
shouldChangeColor() {
return this.activeColor && (this.hoverEffect || this.isActive)
}
},
watch: {
isActive(newVal) {
console.log(newVal, 'newVal---');
if (this.shouldChangeColor) {
this.currentColor = newVal ? this.activeColor : this.defaultColor
console.log(this.currentColor, 'this.currentColor--');
}
},
defaultColor(newVal) {
if (!this.isHovering && !this.isActive) {
this.currentColor = newVal
}
},
activeColor() {
this.updateColorState()
}
},
methods: {
async loadSvg() {
try {
const response = await fetch(this.iconPath)
this.svgContent = await response.text()
this.processSvg()
} catch (error) {
console.error('Failed to load SVG:', error)
}
},
processSvg() {
// SVG便CSS
this.$nextTick(() => {
const svgElement = this.$el.querySelector('svg')
if (svgElement) {
//
svgElement.removeAttribute('fill')
svgElement.removeAttribute('style')
const paths = svgElement.querySelectorAll('path, circle, rect, polygon')
paths.forEach(el => {
el.removeAttribute('fill')
})
svgElement.style.fill = 'currentColor'
svgElement.style.width = '100%'
svgElement.style.height = '100%'
}
})
},
handleMouseEnter() {
this.isHovering = true
this.updateColorState()
},
handleMouseLeave() {
this.isHovering = false
this.updateColorState()
},
updateColorState() {
if (this.activeColor) {
if (this.isActive) {
this.currentColor = this.activeColor
} else {
this.currentColor = this.isHovering && this.hoverEffect ?
this.activeColor :
this.defaultColor
}
} else {
this.currentColor = this.defaultColor
}
}
},
created() {
this.loadSvg()
}
}
</script>
<style scoped>
/* .svg-icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--icon-color);
transition: color 0.3s;
}
.svg-icon:hover {
color: var(--icon-hover-color);
}
.svg-icon {
display: inline-flex;
} */
</style>

1
packages/assets/bind_sites.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_166_49091"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_166_49091)"><g><path d="M3.993058,2.326391373069763Q2.333333,3.986113373069763,2.333333,6.333333373069763Q2.333333,10.987083373069764,7.58354,15.187233373069763Q7.62755,15.222433373069762,7.67685,15.249733373069763Q7.72614,15.277133373069763,7.77933,15.295733373069764Q7.83251,15.314433373069763,7.88808,15.323833373069764Q7.94364,15.333333373069763,8,15.333333373069763Q8.05636,15.333333373069763,8.111930000000001,15.323833373069764Q8.16749,15.314433373069763,8.22067,15.295733373069764Q8.273859999999999,15.277133373069763,8.32315,15.249733373069763Q8.37245,15.222433373069762,8.41646,15.187233373069763Q13.6667,10.987083373069764,13.6667,6.333333373069763Q13.6667,3.986113373069763,12.00694,2.326391373069763Q10.34721,0.6666663730697632,8,0.6666663730697632Q5.65278,0.6666663730697632,3.993058,2.326391373069763ZM8,13.804833373069764Q3.666667,10.166283373069763,3.666667,6.333333373069763Q3.666667,4.538403373069763,4.9358699999999995,3.269203373069763Q6.20507,2.000000373069763,8,2.000000373069763Q9.79493,2.000000373069763,11.06413,3.269203373069763Q12.33333,4.538403373069763,12.33333,6.333333373069763Q12.33333,10.166293373069763,8,13.804833373069764Z" fill-rule="evenodd" fill="#8A9099" fill-opacity="1"/></g><g><path d="M6.114383,4.447716492279053Q5.333333,5.228765492279052,5.333333,6.333333492279053Q5.333333,7.437903492279053,6.114383,8.218953492279052Q6.895433,9.000003492279053,8,9.000003492279053Q9.104569999999999,9.000003492279053,9.88562,8.218953492279052Q10.66667,7.437903492279053,10.66667,6.333333492279053Q10.66667,5.228765492279052,9.88562,4.447716492279053Q9.104569999999999,3.666666492279053,8,3.666666492279053Q6.895432,3.666666492279053,6.114383,4.447716492279053ZM7.05719,7.276143492279052Q6.666667,6.885613492279052,6.666667,6.333333492279053Q6.666667,5.781053492279053,7.05719,5.390523492279053Q7.44772,5.000000492279053,8,5.000000492279053Q8.55228,5.000000492279053,8.94281,5.390523492279053Q9.33333,5.781053492279053,9.33333,6.333333492279053Q9.33333,6.885613492279052,8.94281,7.276143492279052Q8.55228,7.666663492279053,8,7.666663492279053Q7.44772,7.666663492279053,7.05719,7.276143492279052Z" fill-rule="evenodd" fill="#8A9099" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
packages/assets/dropDown_expand.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 297 B

BIN
packages/assets/home-bread.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

1
packages/assets/home-bread.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

BIN
packages/assets/message_Success.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

BIN
packages/assets/message_Warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

BIN
packages/assets/message_error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

BIN
packages/assets/separator.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

BIN
packages/assets/table_empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

129
packages/index.js

@ -1,24 +1,52 @@
import GuipButton from './GuipButton';
import GroupFormBtns from './GroupFormBtns';
import GuipInput from './GuipInput';
import PromptText from './PromptText';
import GuipTextarea from './GuipTextarea';
import DevicePreview from './DevicePreview';
import GuipRadio from './GuipRadio';
import GuipSelect from './GuipSelect';
import Breadcrumb from './Breadcrumb';
import SvgIcon1 from './SvgIcon1';
import SvgIcon from './SvgIcon';
import GuipTable from './GuipTable';
import GuipSwitch from './GuipSwitch';
import GuipTooltip from './GuipToolTip';
import GuipDialog from './GuipDialog';
import GuipMessage from './GuipMessage';
// import CustomDropdown from './CustomDropdown';
import GuipFormItem from './GuipFormItem';
import {
directive as clickaway
} from 'vue-clickaway';
// 表格头部 添加自定义小图标 *
// import HeaderIcon from './utils/headerIcon'
// Vue.mixin(HeaderIcon)
// 复制到粘贴板
import clipboard from './utils/dirClipBoard';
import {
modernCopyToClipboard
} from './utils/clipboard';
import 'core-js/stable';
import 'element-ui/lib/theme-chalk/index.css'; // 如果依赖Element
import './styles/index.css'; // 全局引入
import './styles/common.scss'; // 全局引入
import './styles/component.scss'; // 全局引入
import EventBus, {
$on,
$once,
$off,
$emit
$busOn,
$busOnce,
$busOff,
$busEmit
} from './utils/eventBus'
import GuipButton from './GuipButton'
import GroupFormBtns from './GroupFormBtns'
import GuipInput from './GuipInput'
import PromptText from './PromptText'
import GuipTextarea from './GuipTextarea'
import DevicePreview from './DevicePreview'
import GuipRadio from './GuipRadio'
import GuipSelect from './GuipSelect'
import GuipFormItem from './GuipFormItem'
import CustomDropdown from './CustomDropdown'
import GuipDialog from './GuipDialog'
import 'element-ui/lib/theme-chalk/index.css' // 如果依赖Element
import './styles/index.css' // 全局引入
import './styles/common.scss' // 全局引入
import { directive as clickaway } from 'vue-clickaway'
const components = [
GuipButton,
GroupFormBtns,
@ -28,19 +56,33 @@ const components = [
DevicePreview,
GuipRadio,
GuipSelect,
Breadcrumb,
SvgIcon1,
SvgIcon,
GuipTable,
GuipTooltip,
GuipSwitch,
GuipDialog,
GuipFormItem,
CustomDropdown,
GuipDialog
]
// CustomDropdown
];
const install = function (Vue) {
const install = function (Vue, options = {}) {
// 为了避免冲突 名字要和特殊api 区分
// 挂载到Vue原型
Vue.prototype.$eventBus = EventBus
Vue.prototype.$on = $on
Vue.prototype.$emit = $emit
Vue.prototype.$off = $off
Vue.prototype.$once = $once
Vue.directive('clickaway', clickaway)
Vue.prototype.$busOn = $busOn
Vue.prototype.$busEmit = $busEmit
Vue.prototype.$busOff = $busOff
Vue.prototype.$busOnce = $busOnce
Vue.prototype.$Message = GuipMessage
// 复制
Vue.prototype.$copy = modernCopyToClipboard;
Vue.use(clipboard);
Vue.directive('clickaway', clickaway);
components.forEach(component => {
if (!component.name) {
throw new Error(`Component name is required: ${component}`)
@ -49,6 +91,26 @@ const install = function (Vue) {
})
}
export {
GuipButton,
GroupFormBtns,
GuipInput,
PromptText,
GuipTextarea,
DevicePreview,
GuipRadio,
GuipSelect,
Breadcrumb,
SvgIcon1,
SvgIcon,
GuipTable,
GuipTooltip,
GuipSwitch,
GuipDialog,
GuipFormItem,
GuipMessage,
// CustomDropdown
}
export default {
install,
GuipButton,
@ -59,7 +121,14 @@ export default {
DevicePreview,
GuipRadio,
GuipSelect,
Breadcrumb,
SvgIcon1,
SvgIcon,
GuipTable,
GuipTooltip,
GuipSwitch,
GuipDialog,
GuipFormItem,
CustomDropdown,
GuipDialog
GuipMessage,
// CustomDropdown
}

63
packages/styles/common.scss

@ -40,22 +40,35 @@ body {
text-align: left;
}
/* 隐藏全局滚动条 */
::-webkit-scrollbar {
display: none;
}
body {
scrollbar-width: none;
-ms-overflow-style: none;
}
.element {
overflow: hidden; /* 通用方法 */
scrollbar-width: none; /* Firefox */
}
/* 全局隐藏滚动条但排除el-table */
// *:not(.el-table)::-webkit-scrollbar {
// display: none;
// }
// body {
// scrollbar-width: none;
// -ms-overflow-style: none;
// }
// .element {
// overflow: hidden; /* 通用方法 */
// scrollbar-width: none; /* Firefox */
// }
/* 对于WebKit浏览器 */
.element::-webkit-scrollbar {
display: none; /* Chrome, Safari, Edge */
}
// .element::-webkit-scrollbar {
// display: none; /* Chrome, Safari, Edge */
// }
// .el-table__body-wrapper::-webkit-scrollbar {
// display: block !important;
// width: 6px;
// height: 6px;
// }
// .el-table__body-wrapper::-webkit-scrollbar-thumb {
// background: #c1c1c1;
// border-radius: 3px;
// }
.common_title{
font-weight: bold;
letter-spacing: 0.08em;
@ -174,14 +187,14 @@ body {
div {
width: 16px;
height: 16px;
background-image: url('../assets/addIcon.svg');
background-image: url(../assets/addIcon.svg);
margin-right: 12px;
}
&:hover {
transition: all .3s;
div {
background-image: url('../assets/addIcon_light.svg');
background-image: url(../assets/addIcon_light.svg);
}
border-color: #006AFF;
@ -647,10 +660,9 @@ body {
// textarea start
.el-textarea__inner {
padding: 10px 12px 30px;
padding: 10px 12px;
border-radius: 2px;
height: 100% !important;
font-family: Microsoft YaHei UI;
}
.el-textarea__inner:hover {
@ -672,8 +684,9 @@ body {
.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label::after,
.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label::after {
content: url('../assets/require.svg');
content: url(../assets/require.svg);
display: inline-block;
// background-image: url(../../assets/require.svg);
color: #ff4d4f;
margin-right: 4px;
margin-left: 4px;
@ -814,7 +827,7 @@ body {
overflow: hidden;
text-overflow: ellipsis;
}
.el-table .svg-icon-wrapper{
.el-table .guip-svg-icon-wrapper{
width: 12px !important;
height: 12px !important;
}
@ -864,7 +877,7 @@ body {
white-space: normal;
max-width: none;
}
.svg-icon-wrapper{
.guip-svg-icon-wrapper{
// width: 12px !important;
// height: 12px !important;
}
@ -918,7 +931,9 @@ body {
background: #F6F7FA;
padding: 10px 0;
}
.el-table__header th{
background: #F6F7FA;
}
.el-table th.el-table__cell>.cell {
padding-left: 16px;
padding-right: 16px;
@ -937,13 +952,13 @@ body {
}
// 表格行内小图标 默认隐藏
.el-table .svg-icon-wrapper{
.el-table .guip-svg-icon-wrapper{
display: none !important;
margin-left: 8px;
}
//划过时 显示
.el-table__row:hover{
.svg-icon-wrapper{
.guip-svg-icon-wrapper{
margin-left: 8px;
display: block !important;
}

539
packages/styles/component.scss

@ -0,0 +1,539 @@
// 提示框组件
.guip-prompt-text {
padding: 8px 13px;
border-radius: 4px;
.flex-text {
display: flex;
align-items: center;
align-self: stretch;
justify-content: space-between;
z-index: 1;
}
.prompt-icon {
width: 16px;
height: 16px;
;
margin-right: 8px;
}
.prompt-desc {
color: #1E2226;
letter-spacing: 0.08em;
}
.prompt-extra {}
}
.guip-prompt-text.info {
background: #F2F7FF;
border: 1px solid #BFDAFF;
}
.guip-prompt-text.notice {
background: #FEFCE8;
border: 1px solid rgba(255, 140, 0, 0.3);
}
.guip-prompt-text.warning {
background: #FFF1F0;
border: 1px solid #FFA39E;
}
// 实时预览外框组件
.guip-preview-container {
max-width: 800px;
min-width: 300px;
margin: 0 auto;
padding: 24px;
border-radius: 4px;
background: #FAFAFA;
.preview_top {
margin-bottom: 20px;
}
.preview-title {
text-align: center;
color: #1E2226;
}
.toggle-container {
display: flex;
height: 26px;
justify-content: center;
align-items: center;
padding: 3px 6px;
border-radius: 4px;
background: #F2F3F5;
}
.toggle-button {
padding: 1px 12px;
border-radius: 2px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.3s ease;
}
.toggle-button.active {
color: #006AFF;
background: #FFFFFF;
}
.toggle-button.active:after {
/* content: '';
position: absolute;
bottom: -11px;
left: 0;
width: 100%;
height: 2px;
background-color: #1890ff; */
}
.content-container {
/* min-height: 300px;
padding: 20px;
border: 2px solid #ffd700;
border-radius: 4px;
background-color: #fff; */
}
.desktop-view,
.mobile-view {
width: 100%;
}
}
// 面包屑组件
.guip-breadcrumb-container {
padding: 16px 12px;
background-color: #f5f5f5;
border-radius: 4px;
.breadRight {
a {
text-decoration: none;
color: #006AFF;
}
}
.home-icon {
width: 16px;
height: 16px;
}
.breadcrumb {
display: flex;
flex-wrap: wrap;
height: 22px;
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
.breadcrumb-item {
display: flex;
align-items: center;
height: 100%;
cursor: pointer;
}
.router-link-active {
height: 100%;
display: flex;
align-items: center;
}
.breadcrumb-item a {
color: #626573;
text-decoration: none;
&:hover {
color: #006AFF;
}
}
.breadcrumb-item.active span {
color: #1E2226;
;
}
.separator {
width: 12px;
height: 12px;
}
}
// 图标组件 svgicon1
.guip-svg-icon-wrapper1 {
cursor: pointer;
.svg-icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--icon-color);
transition: color 0.3s;
}
.svg-icon:hover {
color: var(--icon-hover-color);
}
.svg-icon {
display: inline-flex;
}
}
// 图标组件 svgicon
.guip-svg-icon-wrapper {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s;
.svg-icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--icon-color);
transition: color 0.3s;
}
.svg-icon:hover {
color: var(--icon-hover-color);
}
}
.guip-svg-icon-wrapper .svg-icon ::v-deep path {
fill: currentColor;
}
.guip-svg-icon-wrapper .svg-icon ::v-deep circle {
fill: currentColor;
}
.guip-svg-icon-wrapper:hover {
opacity: 0.8;
}
.guip-svg-icon-wrapper[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
// .guip-svg-icon-wrapper .svg-icon ::v-deep svg {
// fill: currentColor;
// }
// 表格组件
.guip-table {
.custom-empty {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
.empty-image {
width: 160px;
height: 160px;
}
.empty-text {
color: #626573;
letter-spacing: 0.08em;
height: 18px;
line-height: 18px;
}
.el-empty {
padding: 0;
}
}
.guip-table ::v-deep .el-empty__description {
line-height: 20px;
margin-top: 0;
}
// switch组件
.guip_switchWrap {
.fl {
float: left;
margin-right: 12px;
}
.fr {
float: right;
margin-left: 12px;
}
.switchDesc {
font-size: 12px;
font-weight: normal;
line-height: 20px;
letter-spacing: 0.08em;
font-variation-settings: "opsz"auto;
/* text/text_3 */
color: #626573;
display: inline-block;
}
.error-msg {
color: #f56c6c;
font-size: 12px;
margin-left: 10px;
}
}
// 自定义下拉选择框组件 start
.guip-custom-select {
height: 38px;
position: relative;
font-family: Arial, sans-serif;
.select-trigger {
border-radius: 2px;
opacity: 1;
background: #FFFFFF;
border: 1px solid #DFE2E6;
width: 100%;
height: 40px;
box-sizing: border-box;
padding: 10px 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
}
.is-open .select-trigger {
border: 1px solid #006AFF;
transition: all .5s;
outline: 3px solid #D8E9FA;
}
.select-trigger:hover {
border-color: #006AFF;
transition: all .5s;
}
.arrow-icon {
width: 12px;
}
.select-dropdown {
position: absolute;
top: 100%;
right: 0;
width: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-top: 4px;
max-height: 384px;
overflow-y: auto;
padding: 0 12px 12px 12px;
}
.dropdown-item {
padding: 12px 10px;
cursor: pointer;
}
.dropdown-item:hover {
background: #F6F7FA;
}
.dropdown-item.is-selected {
background-color: #F6F7FA;
color: #006AFF;
}
/* 展开收起动画 */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s ease;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
opacity: 0;
transform: translateY(-10px);
}
}
// 自定义下拉选择框组件 end
// input 组件 start
.guip-input-unit {
position: absolute;
right: 12px;
/* 根据需要调整位置 */
top: 50%;
transform: translateY(-50%);
pointer-events: none;
/* 防止单位文本影响输入框的点击事件 */
}
// input 组件 end
// 提示信息组件 start
.guip-custom-message {
position: fixed;
z-index: 9999;
display: flex;
align-items: center;
padding: 14px 21px;
transition: all 0.3s;
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #626573;
border-radius: 4px;
background: #FFFFFF;
/* 阴影/低阴影 */
box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.16);
.message-image {
width: 18px;
height: 18px;
margin-right: 10px;
}
}
/* 位置样式 */
.guip-custom-message.top-center {
top: 20px;
left: 50%;
transform: translateX(-50%);
}
.guip-custom-message.top-right {
top: 20px;
right: 20px;
}
.guip-custom-message.top-left {
top: 20px;
left: 20px;
}
.guip-custom-message.bottom-center {
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.guip-custom-message.bottom-right {
bottom: 20px;
right: 20px;
}
.guip-custom-message.bottom-left {
bottom: 20px;
left: 20px;
}
/* 动画效果 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s, transform 0.3s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-enter.top-center,
.fade-leave-to.top-center {
transform: translate(-50%, -20px);
}
.fade-enter.top-right,
.fade-leave-to.top-right,
.fade-enter.top-left,
.fade-leave-to.top-left {
transform: translateY(-20px);
}
.fade-enter.bottom-center,
.fade-leave-to.bottom-center {
transform: translate(-50%, 20px);
}
.fade-enter.bottom-right,
.fade-leave-to.bottom-right,
.fade-enter.bottom-left,
.fade-leave-to.bottom-left {
transform: translateY(20px);
}
// 提示信息组件 end
// 自定义下拉框input+下拉组合框
.combo-formItem {
::v-deep {
.form-item-bottom {
position: relative;
}
.select-trigger {
background: #F6F7FA;
border-color: transparent;
}
.is-open .select-trigger {
border-color: #006AFF;
}
.el-input__inner {
border-radius: 2px 0 0 2px;
}
}
.self-drop-wrap {
position: absolute;
z-index: 1;
width: 100%;
}
.appendDrop {
height: 38px;
align-items: center;
border-radius: 0 2px 2px 0;
border: 1px solid #DFE2E6;
border-left-color: transparent;
justify-content: center;
box-sizing: border-box;
padding: 0 30px 0 12px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
&:hover {
border: 1px solid #006AFF;
}
}
}
// 组合框样式 end

22
packages/styles/index.css

@ -4120,7 +4120,7 @@ border-color:#006AFF !important;
}
.el-menu {
border-right: solid 1px #e6e6e6;
border: none;
list-style: none;
position: relative;
margin: 0;
@ -7645,10 +7645,10 @@ border-color:#006AFF !important;
background-color: #e6f0ff
}
.el-table__body tr.hover-row.current-row>td.el-table__cell,
.el-table__body tr.hover-row.el-table__row--striped.current-row>td.el-table__cell,
.el-table__body tr.hover-row.el-table__row--striped>td.el-table__cell,
.el-table__body tr.hover-row>td.el-table__cell {
.el-table__body tr.hover-row.current-row>td,
.el-table__body tr.hover-row.el-table__row--striped.current-row>td,
.el-table__body tr.hover-row.el-table__row--striped>td,
.el-table__body tr.hover-row>td {
background-color: #f5f7fa
}
@ -7679,12 +7679,12 @@ border-color:#006AFF !important;
transform: scale(.75)
}
.el-table--enable-row-transition .el-table__body td.el-table__cell {
.el-table--enable-row-transition .el-table__body td {
-webkit-transition: background-color .25s ease;
transition: background-color .25s ease
}
.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
.el-table--enable-row-hover .el-table__body tr:hover>td {
background-color: #f5f7fa
}
@ -11827,7 +11827,7 @@ border-color:#006AFF !important;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
line-height: 18px;
outline: 0;
padding: 0 15px;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
@ -14648,7 +14648,7 @@ border-color:#006AFF !important;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
line-height: 18px;
outline: 0;
padding: 0 15px;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
@ -20599,7 +20599,7 @@ border-color:#006AFF !important;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
line-height: 18px;
outline: 0;
padding: 0 15px;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
@ -22718,7 +22718,7 @@ border-color:#006AFF !important;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
line-height: 18px;
outline: 0;
padding: 0 15px;
-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);

6
packages/utils/clipboard.js

@ -4,7 +4,7 @@
* @param {Object} options 配置选项
* @param {string} options.successMsg 成功提示信息
* @param {string} options.errorMsg 失败提示信息
* @param {Vue} options.vm Vue实例(用于调用$message)
* @param {Vue} options.vm Vue实例(用于调用$Message)
* @returns {Promise<boolean>} 是否复制成功
*/
export function copyToClipboard(text, options = {}) {
@ -36,7 +36,6 @@ export function copyToClipboard(text, options = {}) {
throw new Error('Copy command was unsuccessful');
}
} catch (err) {
console.error('复制失败:', err);
if (vm && vm.$Message) {
vm.$Message.error(errorMsg);
} else {
@ -61,7 +60,8 @@ export async function modernCopyToClipboard(text, options = {}) {
vm = null
} = options;
if (navigator.clipboard && window.isSecureContext) {
await navigator?.clipboard?.writeText(text);
// 注意:localhost 可能会无效 或者 提示复制失败,但是其实已经复制到粘贴板
await navigator.clipboard.writeText(text);
if (vm && vm.$Message) {
vm.$Message.success(successMsg);
} else {

2
packages/utils/dirClipBoard.js

@ -1,4 +1,4 @@
import modernCopyToClipboard from '@/utils/clipboard';
import modernCopyToClipboard from './clipboard';
export default {
install(Vue) {

8
packages/utils/eventBus.js

@ -3,9 +3,9 @@ import Vue from 'vue'
const EventBus = new Vue()
// 封装常用方法
export const $on = EventBus.$on.bind(EventBus)
export const $once = EventBus.$once.bind(EventBus)
export const $off = EventBus.$off.bind(EventBus)
export const $emit = EventBus.$emit.bind(EventBus)
export const $busOn = EventBus.$on.bind(EventBus)
export const $busOnce = EventBus.$once.bind(EventBus)
export const $busOff = EventBus.$off.bind(EventBus)
export const $busEmit = EventBus.$emit.bind(EventBus)
export default EventBus

5
postcss.config.js

@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('autoprefixer')({ grid: true })
]
}
Loading…
Cancel
Save