
@ -0,0 +1 @@ |
|||
/packages/ |
@ -0,0 +1,22 @@ |
|||
// .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' |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
# 根目录 .gitignore |
|||
|
|||
# 依赖目录 |
|||
node_modules/ |
|||
examples/node_modules/ # 显式忽略 examples 下的 node_modules |
|||
|
|||
# 构建产物 |
|||
dist/ |
|||
packages/dist/ |
|||
*.log |
|||
.DS_Store |
|||
|
|||
# 环境文件 |
|||
.env |
|||
.env.local |
|||
|
|||
# IDE 配置 |
|||
.idea/ |
|||
.vscode/ |
|||
*.swp |
|||
|
|||
# 调试文件 |
|||
debug.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
|
|||
# 其他 |
|||
*.tmp |
|||
*.bak |
@ -0,0 +1,8 @@ |
|||
# 忽略文件 |
|||
examples/ |
|||
node_modules/ |
|||
*.log |
|||
*.md |
|||
*.yml |
|||
webpack.config.js |
|||
.gitignore |
@ -0,0 +1,93 @@ |
|||
const path = require('path') |
|||
const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
|||
const { |
|||
VueLoaderPlugin |
|||
} = require('vue-loader') |
|||
|
|||
module.exports = { |
|||
mode: 'production', |
|||
stats: 'verbose', |
|||
entry: { |
|||
'zhicheng-components': './packages/index.js' |
|||
}, |
|||
output: { |
|||
path: path.resolve(__dirname, '../dist'), |
|||
filename: '[name].umd.js', |
|||
library: 'ZhichengUI', |
|||
libraryTarget: 'umd', |
|||
umdNamedDefine: true, |
|||
globalObject: `(typeof self !== 'undefined' ? self : this)` |
|||
}, |
|||
resolve: { |
|||
alias: { |
|||
'@': path.resolve(__dirname, './packages') // 确保别名指向正确
|
|||
} |
|||
}, |
|||
module: { |
|||
rules: [ |
|||
{ |
|||
test: /\.vue$/, |
|||
loader: 'vue-loader', |
|||
options: { |
|||
compilerOptions: { |
|||
preserveWhitespace: false |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
test: /\.css$/, |
|||
use: [MiniCssExtractPlugin.loader, 'css-loader'] // 替换style-loader
|
|||
}, |
|||
{ |
|||
test: /\.scss$/, |
|||
use: [MiniCssExtractPlugin.loader, 'css-loader', { |
|||
loader: 'sass-loader', |
|||
options: { |
|||
implementation: require('sass') // 显式指定 sass
|
|||
} |
|||
}] |
|||
}, |
|||
{ |
|||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, |
|||
use: [{ |
|||
loader: 'url-loader', |
|||
options: { |
|||
limit: 4096, |
|||
name: 'fonts/[name].[hash:8].[ext]', |
|||
esModule: false, |
|||
publicPath: '../', // 关键:修正 CSS 中的引用路径
|
|||
} |
|||
}] |
|||
}, |
|||
{ |
|||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, |
|||
use: [{ |
|||
loader: 'url-loader', |
|||
options: { |
|||
limit: 4096, |
|||
name: 'img/[name].[hash:8].[ext]', |
|||
esModule: false, |
|||
publicPath: '../' |
|||
} |
|||
}] |
|||
} |
|||
] |
|||
}, |
|||
plugins: [ |
|||
new VueLoaderPlugin(), |
|||
new MiniCssExtractPlugin({ |
|||
filename: 'css/[name].css' // 输出到dist/css/
|
|||
}) |
|||
], |
|||
optimization: { |
|||
splitChunks: false |
|||
}, |
|||
externals: { |
|||
vue: { |
|||
root: 'Vue', |
|||
commonjs: 'vue', |
|||
commonjs2: 'vue', |
|||
amd: 'vue' |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
// build/webpack.dev.js
|
|||
const path = require('path') |
|||
const { merge } = require('webpack-merge') |
|||
const baseConfig = require('./webpack.config.js') |
|||
const HtmlWebpackPlugin = require('html-webpack-plugin') |
|||
const VueLoaderPlugin = require('vue-loader/lib/plugin'); |
|||
module.exports = merge(baseConfig, { |
|||
mode: 'development', |
|||
entry: path.resolve(__dirname, '../examples/src/main.js'), |
|||
output: { |
|||
path: path.resolve(__dirname, '../examples/dist'), |
|||
filename: 'bundle.js', |
|||
publicPath: '/' |
|||
}, |
|||
resolve: { |
|||
alias: { |
|||
'vue$': 'vue/dist/vue.esm.js' // 明确指定完整版Vue
|
|||
} |
|||
}, |
|||
module: { |
|||
rules: [ |
|||
{ |
|||
test: /\.vue$/, |
|||
loader: 'vue-loader', |
|||
options: { |
|||
compilerOptions: { |
|||
preserveWhitespace: false |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
test: /\.js$/, |
|||
exclude: /node_modules/, |
|||
use: { |
|||
loader: 'babel-loader' |
|||
} |
|||
}, |
|||
{ |
|||
test: /\.css$/, |
|||
use: ['style-loader', 'css-loader'] |
|||
}, |
|||
{ |
|||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, |
|||
type: 'asset/resource', |
|||
generator: { |
|||
filename: 'fonts/[name].[hash:8][ext]' |
|||
} |
|||
}, |
|||
{test: /\.vue$/, use: 'vue-loader'} |
|||
] |
|||
}, |
|||
plugins: [ |
|||
new HtmlWebpackPlugin({ |
|||
template: path.resolve(__dirname, '../examples/public/index.html'), |
|||
filename: 'index.html' |
|||
}), |
|||
new VueLoaderPlugin() |
|||
], |
|||
devServer: { |
|||
static: { |
|||
directory: path.join(__dirname, '../examples/dist') |
|||
}, |
|||
compress: true, |
|||
port: 9000, |
|||
hot: true, |
|||
open: true |
|||
} |
|||
}) |
@ -0,0 +1,17 @@ |
|||
module.exports = { |
|||
env: { |
|||
browser: true, |
|||
es2021: true |
|||
}, |
|||
extends: [ |
|||
'eslint:recommended', |
|||
'plugin:vue/essential' |
|||
], |
|||
parserOptions: { |
|||
ecmaVersion: 12, |
|||
sourceType: 'module' |
|||
}, |
|||
rules: { |
|||
'vue/multi-word-component-names': 'off' |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
# examples/.gitignore |
|||
|
|||
# 开发缓存 |
|||
.vuepress/dist/ |
|||
.temp/ |
|||
.cache/ |
|||
|
|||
# 测试报告 |
|||
coverage/ |
|||
__tests__/__snapshots__/ |
|||
|
|||
# 本地调试文件 |
|||
.local-* |
@ -0,0 +1,8 @@ |
|||
# 忽略文件 |
|||
examples/ |
|||
node_modules/ |
|||
*.log |
|||
*.md |
|||
*.yml |
|||
webpack.config.js |
|||
.gitignore |
@ -0,0 +1,49 @@ |
|||
{ |
|||
"name": "examples", |
|||
"private": true, |
|||
"version": "1.0.0", |
|||
"description": "Demo project for vue2 component library", |
|||
"scripts": { |
|||
"serve": "vue-cli-service serve", |
|||
"build": "vue-cli-service build", |
|||
"lint": "vue-cli-service lint" |
|||
}, |
|||
"dependencies": { |
|||
"core-js": "^3.8.3", |
|||
"my-components": "file:../", |
|||
"vue": "^2.6.14", |
|||
"element-ui": "^2.15.13", |
|||
"vue-loader": "^17.4.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "^4.5.19", |
|||
"@vue/cli-plugin-eslint": "^4.5.19", |
|||
"@vue/cli-service": "^4.5.19", |
|||
"sass": "^1.89.2", |
|||
"babel-eslint": "^10.1.0", |
|||
"sass-loader": "^10.2.0", |
|||
"vue-template-compiler": "^2.6.14", |
|||
"css-loader": "^5.2.7", |
|||
"eslint": "^6.8.0", |
|||
"eslint-plugin-vue": "^6.2.2" |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not dead" |
|||
], |
|||
"eslintConfig": { |
|||
"root": true, |
|||
"env": { |
|||
"node": true |
|||
}, |
|||
"extends": [ |
|||
"plugin:vue/essential", |
|||
"eslint:recommended" |
|||
], |
|||
"parserOptions": { |
|||
"parser": "babel-eslint" |
|||
}, |
|||
"rules": {} |
|||
} |
|||
} |
@ -0,0 +1,809 @@ |
|||
<template> |
|||
<div id="app" class="demo-container"> |
|||
<el-form :model="form" :rules="rules" class="el-row demo-ruleForm" ref="formRef"> |
|||
|
|||
<!-- 按钮组件示例 --> |
|||
<section class="demo-section"> |
|||
<h2>页面提示框集合</h2> |
|||
<PromptText text='这是一个提示框' :type="1" /> |
|||
<PromptText text='这是一个提示框' :type="2" /> |
|||
<PromptText text='这是一个提示框' :type="3" /> |
|||
<PromptText text="前期准备事项" :type="1" class="beforeNotice"> |
|||
<template #next_desc> |
|||
<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智慧平台 |
|||
</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智慧平台 |
|||
</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投放包”按钮。注意转换类型只能选择“订单”,其他的根据表单提示填写。 |
|||
</p> |
|||
</template> |
|||
</PromptText> |
|||
</section> |
|||
<section class="demo-section"> |
|||
<h2>按钮组件集合</h2> |
|||
<div class="ele-item"> |
|||
<label for="">按钮尺寸:</label> |
|||
<GuipButton size="superBig">加盟并进入后台</GuipButton> |
|||
<GuipButton size="big">准备完毕,验证自有域名</GuipButton> |
|||
<GuipButton size="page">下一步</GuipButton> |
|||
<GuipButton size="primary">保存</GuipButton> |
|||
<GuipButton size="table">新增站点</GuipButton> |
|||
<GuipButton size="form">前往添加</GuipButton> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">强按钮:</label> |
|||
<!-- 默认 type= primary normal 样式 --> |
|||
<GuipButton>默认</GuipButton> |
|||
<GuipButton loading>按钮</GuipButton> |
|||
<GuipButton disabled>按钮</GuipButton> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">弱按钮:</label> |
|||
<GuipButton type="ignore">按钮</GuipButton> |
|||
<GuipButton type="ignore" loading>按钮</GuipButton> |
|||
<GuipButton type="ignore" disabled>按钮</GuipButton> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">中按钮:</label> |
|||
<GuipButton type="system">按钮</GuipButton> |
|||
<GuipButton type="system" loading>按钮</GuipButton> |
|||
<GuipButton type="system" disabled>按钮</GuipButton> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">文字按钮:</label> |
|||
<GuipButton type="text">强引导</GuipButton> |
|||
<GuipButton type="grey">弱引导</GuipButton> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">按钮套餐:</label> |
|||
<GroupFormBtns /> |
|||
</div> |
|||
</section> |
|||
<section class="demo-section"> |
|||
<h2>输入框集合</h2> |
|||
<div class="ele-item"> |
|||
<label for="">输入框:</label> |
|||
<GuipInput ref="GuipInput" v-model="form.input1" width="200px" height="30px" placeholder="这是自定义默认提示语" /> |
|||
|
|||
<div style="width: 20px;height: 10px;"></div> |
|||
|
|||
<GuipInput ref="GuipInput" v-model="form.input2" :maxlength="100" @change="handleInput" @blur="handleInput" |
|||
@input="handleInput" @focus="handleInput" placeholder="这是自定义默认提示语" /> |
|||
|
|||
<div style="width: 20px;height: 10px;"></div> |
|||
|
|||
<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> |
|||
<GuipTextarea :styleObject="{ width: '450px' }" placeholder="固定行数" :rows="1" /> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">文本域:自适应高度</label> |
|||
<GuipTextarea :styleObject="{ width: '450px' }" placeholder="自适应高度" autosize /> |
|||
</div> |
|||
|
|||
<div class="ele-item"> |
|||
<label for="">文本域:自定义label、描述</label> |
|||
<GuipTextarea label="详细介绍" column="column" prop="doctor_detail" width="400px" height="40px" |
|||
placeholder="请输入描述内容" desc="啊哈哈哈哈哈哈哈哈" show-word-limit /> |
|||
</div> |
|||
</section> |
|||
<section class="demo-section"> |
|||
<h2>实时预览tab组件</h2> |
|||
<DevicePreview> |
|||
<template #desktop> |
|||
电脑端内容-内容自定义 |
|||
</template> |
|||
<template #mobile> |
|||
内容自定义 |
|||
手机端端内容-- 手机端端内容 |
|||
</template> |
|||
</DevicePreview> |
|||
</section> |
|||
<section> |
|||
<h2>单选框组件集合</h2> |
|||
<div class="ele-item"> |
|||
<label for="">单选框(对象格式):</label> |
|||
<GuipRadio v-model="form.language" :options="languageOptions" label="选择语言" prop="language" |
|||
@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" :rules="rules.language" label-key="name" :disabledKeys="['1']" value-key="id" /> |
|||
</div> |
|||
<div class="ele-item"> |
|||
<label for="">单选框:</label> |
|||
<el-radio v-model="radio1" :label="1">选项一</el-radio> |
|||
<el-radio v-model="radio1" :label="2">选项二</el-radio> |
|||
</div> |
|||
|
|||
<div class="ele-item"> |
|||
<label for="">单选框组:</label> |
|||
<el-radio-group v-model="radio" @input="radioChange"> |
|||
<el-radio :label="3">备选项</el-radio> |
|||
<el-radio :label="6">备选项</el-radio> |
|||
<el-radio :label="9">备选项</el-radio> |
|||
</el-radio-group> |
|||
</div> |
|||
</section> |
|||
|
|||
</el-form> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
content: '测试一下', |
|||
domainOptions: [ |
|||
{ |
|||
value: '.chachongz.com', |
|||
label: '111.chachongz.com', |
|||
id: '11', |
|||
name: '测试一下自定义名称111' |
|||
}, |
|||
{ |
|||
value: '.turnitin.org.cn', |
|||
label: '222.turnitin.org.cn', |
|||
id: '22', |
|||
name: '测试一下自定义名称222' |
|||
}, |
|||
{ |
|||
value: '.jishu.chachongz.com', |
|||
label: '333.jishu.chachongz.com', |
|||
id: '33', |
|||
name: '测试一下自定义名称333' |
|||
}, |
|||
], |
|||
tableData3: [{ |
|||
id: '12987122', |
|||
name: '王小虎', |
|||
amount1: '234', |
|||
amount2: '3.2', |
|||
amount3: 10 |
|||
}, { |
|||
id: '12987123', |
|||
name: '王小虎', |
|||
amount1: '165', |
|||
amount2: '4.43', |
|||
amount3: 12 |
|||
}, { |
|||
id: '12987124', |
|||
name: '王小虎', |
|||
amount1: '324', |
|||
amount2: '1.9', |
|||
amount3: 9 |
|||
}, { |
|||
id: '12987125', |
|||
name: '王小虎', |
|||
amount1: '621', |
|||
amount2: '2.2', |
|||
amount3: 17 |
|||
}, { |
|||
id: '12987126', |
|||
name: '王小虎', |
|||
amount1: '539', |
|||
amount2: '4.1', |
|||
amount3: 15 |
|||
}], |
|||
tableWidth: 0, |
|||
currentPage: 1, //当前页 |
|||
pageSize: 5, //每页的容量 |
|||
total: 0, //列表总数 |
|||
tableLoading: false, |
|||
timer: null, |
|||
date1: '', |
|||
switchValue: true, |
|||
switchValue1: 1, |
|||
switchValue2: '0', |
|||
dialogVisible1: false, |
|||
dialogVisible: false,//是否展示弹框 |
|||
showCancelButton: true, // 控制是否显示取消按钮 |
|||
showCloseButton: true, // 控制是否显示关闭按钮 |
|||
form: { |
|||
username: '', |
|||
language: '', |
|||
domain_set: '', |
|||
domainSuffix: '11', |
|||
domainSuffix1: '.chachongz.com', |
|||
card: '1', |
|||
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: '王俊凯' }, |
|||
], |
|||
languageOptions: { |
|||
'20': '查重站', |
|||
'31': 'AI站' |
|||
}, |
|||
rules: { |
|||
username: [ |
|||
{ required: true, message: '请输入用户名', trigger: 'blur' } |
|||
], |
|||
card: [ |
|||
{ required: true, message: '请选择有效信息', trigger: 'blur' } |
|||
], |
|||
language: [ |
|||
{ required: true, message: '请选择语言', trigger: 'blur' }, |
|||
], |
|||
phone: [ |
|||
{ required: true, message: '请输入手机号', trigger: 'blur' } |
|||
], |
|||
age: [ |
|||
{ required: true, message: '请输入年龄', trigger: 'blur' } |
|||
] |
|||
}, |
|||
usernameRules: [{ required: true, message: 'Username is required', trigger: 'blur' }],//单独自定义rules |
|||
msg: "测试", |
|||
title: "相关附件", |
|||
edit: false, |
|||
action: true, |
|||
header: false, |
|||
width: 1920, |
|||
height: 1080, |
|||
dataList: [ |
|||
{ name: "张三", age: 19, id: 1 }, |
|||
{ name: "李四", age: 20, id: 2 }, |
|||
], |
|||
formList: [], |
|||
// 模拟数据 详细 测试 |
|||
fromItem: { |
|||
id: "Shanghai", |
|||
id1: "选项4", |
|||
name: "用户名", |
|||
radioId: "2", |
|||
checkboxId: ["上海", "北京"], |
|||
textareaIner: "textarea", |
|||
dateTime: "2023-09-12 00:00:00", |
|||
uploadList: [ |
|||
{ |
|||
name: "小梨猫.jpg", |
|||
size: 160517, |
|||
uid: 1695291434025, |
|||
url: "https://ts1.cn.mm.bing.net/th?id=OIP-C.Zte3ljd4g6kqrWWyg-8fhAHaEo&w=316&h=197&c=8&rs=1&qlt=90&o=6&dpr=1.5&pid=3.1&rm=2", |
|||
}, |
|||
], |
|||
}, |
|||
// 表格数据 |
|||
tableData2: [{ |
|||
date: '2016-05-03', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄', |
|||
price: '20', |
|||
age: 20, |
|||
// 在支持修改的项目中,需要主动保留一份原始数据 |
|||
edit_name: '王小虎', edit_address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-02', |
|||
name: '王小虎11', |
|||
address: '上海市普陀区金沙江路 151811 弄', |
|||
price: '10', |
|||
age: 30, |
|||
edit_name: '王小虎11', edit_address: '上海市普陀区金沙江路 151811 弄' |
|||
|
|||
}, { |
|||
date: '2016-05-04', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄', |
|||
price: '200', |
|||
}, { |
|||
date: '2016-05-01', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-08', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-06', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-07', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}], |
|||
tableData4: [{ |
|||
date: '2016-05-03', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄', |
|||
price: '20', |
|||
age: 20, |
|||
// 在支持修改的项目中,需要主动保留一份原始数据 |
|||
edit_name: '王小虎', edit_address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-02', |
|||
name: '王小虎11', |
|||
address: '上海市普陀区金沙江路 151811 弄', |
|||
price: '10', |
|||
age: 30, |
|||
edit_name: '王小虎11', edit_address: '上海市普陀区金沙江路 151811 弄' |
|||
|
|||
}, { |
|||
date: '2016-05-04', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄', |
|||
price: '200', |
|||
}, { |
|||
date: '2016-05-01', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-08', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-06', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}, { |
|||
date: '2016-05-07', |
|||
name: '王小虎', |
|||
address: '上海市普陀区金沙江路 1518 弄' |
|||
}], |
|||
// 表格列配置 |
|||
columns: [ |
|||
{ prop: 'name', label: '姓名(带气泡)', popover: true }, // 支持气泡框 |
|||
{ prop: 'age', label: '年龄', popover: true }, // 不支持气泡框 |
|||
{ prop: 'address', label: '地址(带气泡)', popover: true }, // 支持气泡框 |
|||
], |
|||
optionss: [ |
|||
{ |
|||
value: "选项1", |
|||
label: "黄金糕", |
|||
}, |
|||
{ |
|||
value: "选项2", |
|||
label: "双皮奶", |
|||
}, |
|||
{ |
|||
value: "选项3", |
|||
label: "蚵仔煎", |
|||
}, |
|||
{ |
|||
value: "选项4", |
|||
label: "龙须面", |
|||
}, |
|||
{ |
|||
value: "选项5", |
|||
label: "北京烤鸭", |
|||
}, |
|||
], |
|||
cities: [ |
|||
{ |
|||
value: "Beijing", |
|||
label: "北京", |
|||
}, |
|||
{ |
|||
value: "Shanghai", |
|||
label: "上海", |
|||
}, |
|||
{ |
|||
value: "Nanjing", |
|||
label: "南京", |
|||
}, |
|||
{ |
|||
value: "Chengdu", |
|||
label: "成都", |
|||
}, |
|||
{ |
|||
value: "Shenzhen", |
|||
label: "深圳", |
|||
}, |
|||
{ |
|||
value: "Guangzhou", |
|||
label: "广州", |
|||
} |
|||
], |
|||
tableData: [], |
|||
input: 'hahhahah', |
|||
defaultValue: 'asdasda', |
|||
radio: 3, |
|||
radio1: 5, |
|||
btnstyleObj: { |
|||
width: '388px', |
|||
height: '46px', |
|||
borderRadius: '4px', |
|||
background: '#006AFF', |
|||
}, |
|||
btnstyleObj1: { |
|||
width: '247px', |
|||
height: '46px', |
|||
borderRadius: '4px', |
|||
}, |
|||
styleObject: { |
|||
minWidth: '200px', |
|||
maxWidth: '400px', |
|||
// height: '40px' |
|||
}, |
|||
styleObject1: { |
|||
width: '600px', |
|||
height: '50px' |
|||
}, |
|||
plain: false, |
|||
|
|||
options: [{ |
|||
value: '选项1', |
|||
label1: '黄金hhhhhh', |
|||
id1: '1', |
|||
id2: '啊11哈哈', |
|||
label: '黄金糕' |
|||
}, { |
|||
value: '选项2', |
|||
id1: '12', |
|||
id2: '啊22哈哈', |
|||
label1: '双皮奶hhhhhhhhh', |
|||
label: '双皮奶' |
|||
}, { |
|||
value: '选项3', |
|||
id1: '13', |
|||
id2: '啊33哈哈', |
|||
label1: '蚵仔煎hhhhhhhhh', |
|||
label: '蚵仔煎' |
|||
}, { |
|||
value: '选项4', |
|||
id1: '14', |
|||
id2: '啊444哈哈', |
|||
label1: '双皮奶hhhhhhhhh', |
|||
label: '龙须面' |
|||
}, { |
|||
value: '选项5', |
|||
id1: '155', |
|||
id2: '啊55哈哈', |
|||
label1: '双皮奶hhhhhhhhh', |
|||
label: '北京烤鸭' |
|||
}], |
|||
} |
|||
}, |
|||
created() { |
|||
console.log('当前组件注册情况:', this.$options.components) |
|||
}, |
|||
computed: { |
|||
currentDomainItem() { |
|||
return this.findItemById('id', 'domainSuffix'); |
|||
} |
|||
}, |
|||
methods: { |
|||
// 手动copy内容 |
|||
handleClickCopy() { |
|||
this.$copy(this.form.input1, { |
|||
successMsg: '内容已复制到剪贴板', |
|||
errorMsg: '复制失败,请按Ctrl+C手动复制', |
|||
vm: this |
|||
}); |
|||
}, |
|||
// 自定义的radio label 展示内容 |
|||
formatLabel(option) { |
|||
return `${option.name} (ID: ${option.id})`; |
|||
}, |
|||
findItemById(valueKey, key) { |
|||
// 自动查找选中项 |
|||
return this.domainOptions.find(item => item[valueKey] === this.form[key]); |
|||
}, |
|||
toggleDrop1(e) { |
|||
this.$refs.dropDomain1.toggleDropdown(e) |
|||
}, |
|||
toggleDrop(e) { |
|||
this.$refs.dropDomain.toggleDropdown(e) |
|||
}, |
|||
changeInputtest(e) { |
|||
console.log(e, '---000changeInputtest'); |
|||
}, |
|||
changeSelectIp(item) { |
|||
// 选中项 |
|||
// this.selectedItem1 = { ...item }; |
|||
console.log(item, this.form.domainSuffix, this.form.domainSuffix1, '选中的项-值-'); |
|||
}, |
|||
arraySpanMethod({ row, column, rowIndex, columnIndex }) { |
|||
console.log(row, column); |
|||
if (rowIndex % 2 === 0) { |
|||
if (columnIndex === 0) { |
|||
return [1, 2]; |
|||
} else if (columnIndex === 1) { |
|||
return [0, 0]; |
|||
} |
|||
} |
|||
}, |
|||
|
|||
objectSpanMethod({ row, column, rowIndex, columnIndex }) { |
|||
console.log(row, column); |
|||
|
|||
if (columnIndex === 0) { |
|||
if (rowIndex % 2 === 0) { |
|||
return { |
|||
rowspan: 2, |
|||
colspan: 1 |
|||
}; |
|||
} else { |
|||
return { |
|||
rowspan: 0, |
|||
colspan: 0 |
|||
}; |
|||
} |
|||
} |
|||
}, |
|||
openMessage(type) { |
|||
console.log(type); |
|||
// 单独指定方法调用 |
|||
switch (type) { |
|||
case 'success': |
|||
this.$Message.success('成功,文案自定义') |
|||
break; |
|||
case 'error': |
|||
this.$Message.error('失败,文案自定义') |
|||
break; |
|||
case 'info': |
|||
this.$Message.info('提示,文案自定义') |
|||
break; |
|||
} |
|||
// 自定义选项 |
|||
// this.$Message({ |
|||
// type: 'success', |
|||
// title: '成功标题', |
|||
// message: '这是一条成功的提示消息', |
|||
// duration: 5000, |
|||
// showClose: true, |
|||
// center: true |
|||
// }) |
|||
}, |
|||
showTooltip() { |
|||
this.$refs.tooltip.show() |
|||
}, |
|||
hideTooltip() { |
|||
this.$refs.tooltip.hide() |
|||
}, |
|||
handleSizeChange(val) { |
|||
this.pageSize = val |
|||
this.getStagePurchase() |
|||
}, |
|||
handleCurrentChange(val) { |
|||
this.currentPage = val |
|||
this.getStagePurchase() |
|||
}, |
|||
getStagePurchase() { |
|||
this.tableLoading = true |
|||
const that = this |
|||
that.tableData = [] |
|||
this.$http('POST', '/supernew/ajax_get_stage_purchase', { |
|||
type: 0, |
|||
cur_page: 1, |
|||
page_size: 5, |
|||
}, { |
|||
headers: { |
|||
'AUTH': '3c901fa4a19a7ad9d01238890863d499' |
|||
} |
|||
}).then(response => { |
|||
this.tableLoading = false |
|||
this.$nextTick(() => { |
|||
that.tableData = response.data.list |
|||
// console.log(that.tableData,'---that.tableData'); |
|||
// that.type2name = response.data.type2name |
|||
that.total = response.data.total |
|||
}) |
|||
}).catch(error => { |
|||
console.error(error, 'error') |
|||
}) |
|||
}, |
|||
btnClick() { |
|||
|
|||
}, |
|||
openLoading() { |
|||
this.$store.dispatch('showLoading') |
|||
setTimeout(() => { |
|||
this.$store.dispatch('hideLoading') |
|||
}, 2000) |
|||
|
|||
}, |
|||
handleFilter(column) { |
|||
// 在这里处理筛选逻辑 |
|||
console.log('筛选列:', column); |
|||
}, |
|||
// 部分情况可能导致页面不更新,增加 key 强制重新渲染 |
|||
random() { |
|||
var randomNumber = Math.random(); |
|||
return randomNumber |
|||
}, |
|||
onSwitchChange(value) { |
|||
console.log('Switch 状态变化:', this.switchValue, value); |
|||
}, |
|||
// 弹框相关方法---start |
|||
openDialog() { |
|||
this.dialogVisible = true; |
|||
}, |
|||
openDialog1() { |
|||
this.dialogVisible1 = true; |
|||
}, |
|||
// 确认按钮事件 |
|||
handleConfirm() { |
|||
this.$message.success('点击了确认按钮'); |
|||
this.dialogVisible = false; |
|||
}, |
|||
// 取消按钮事件 |
|||
handleCancel() { |
|||
this.$message.warning('点击了取消按钮'); |
|||
this.dialogVisible = false; |
|||
this.dialogVisible1 = false; |
|||
}, |
|||
// 关闭弹框事件 |
|||
handleClose() { |
|||
this.$message.info('弹框已关闭'); |
|||
this.dialogVisible = false; |
|||
}, |
|||
dialogVisibleChange(data) { |
|||
console.log(data, 'data098908090'); |
|||
}, |
|||
// 弹框相关方法---end |
|||
|
|||
// 选择表格某一项 点击 |
|||
handlePriceClick(row) { |
|||
this.currentRow = row; |
|||
this.editedPrice = row.price; |
|||
this.dialogVisible = true; |
|||
}, |
|||
|
|||
// 表格气泡框----- |
|||
// 确认事件 |
|||
onConfirm(row, prop) { |
|||
console.log('确认修改:', row, prop); |
|||
this.$message.success('修改成功'); |
|||
this.$set(this.tableData4, row) |
|||
console.log(this.tableData4, 'this.tableData====='); |
|||
}, |
|||
// 取消事件 |
|||
onCancel(row, prop) { |
|||
console.log('取消修改:', row, prop); |
|||
this.$message.info('已取消'); |
|||
this.$set(this.tableData, row) |
|||
}, |
|||
// 表格气泡框----- |
|||
|
|||
// 监听单选框组变化 |
|||
radioChange(data) { |
|||
console.log(data, 'radio--data'); |
|||
}, |
|||
handleClick(row) { |
|||
console.log(row); |
|||
}, |
|||
submitForm() { |
|||
this.$refs.formRef.validate((valid) => { |
|||
console.log(this.form, '======formxinxi'); |
|||
if (valid) { |
|||
alert('提交成功!'); |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
}, |
|||
// 重置表单 |
|||
resetForm() { |
|||
this.$refs.form.resetFields(); |
|||
}, |
|||
triggerError() { |
|||
this.$refs.formRef.validateField('username', (error) => { |
|||
if (error) { |
|||
console.log('错误信息:', error); |
|||
} else { |
|||
console.log('无错误'); |
|||
} |
|||
}); |
|||
}, |
|||
getFormdata() { |
|||
console.log(this.$refs.GuipInput.value); |
|||
}, |
|||
handleInput(value) { |
|||
console.log(value, 'value===输入框输入得知'); |
|||
}, |
|||
handleClear(value) { |
|||
this.form.input3 = '这是我清除后给的文案' |
|||
// 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; |
|||
}, |
|||
save() { |
|||
this.$refs.VabForm.submitForm("ruleForm"); |
|||
}, |
|||
//取消 |
|||
cancellation() { |
|||
this.$refs.VabForm.resetForm("ruleForm"); |
|||
}, |
|||
// 表格点击、选择 |
|||
handleSelectionChange(data) { |
|||
// 多选模式下的时候 data 为数组格式 |
|||
// 单选的时候是 对象 |
|||
console.log(data, '表格行信息'); |
|||
}, |
|||
// 全选按钮 |
|||
toggleAllSelection() { |
|||
// console.log(this.$refs.multipleTable,'this.$refs.multipleTable'); |
|||
this.$refs.multipleTable.$refs.guiptable.toggleAllSelection(); |
|||
}, |
|||
}, |
|||
beforeDestroy() { |
|||
if (this.timer) { |
|||
clearTimeout(this.timer) |
|||
// 确保离开组件时关闭 loading |
|||
this.$store.dispatch('hideContentLoading') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.demo-container { |
|||
padding: 20px; |
|||
max-width: 90%; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.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; |
|||
} |
|||
} |
|||
|
|||
.demo-section { |
|||
margin: 30px 0; |
|||
padding: 20px; |
|||
border: 1px solid #eee; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
h2 { |
|||
color: #333; |
|||
margin-bottom: 15px; |
|||
padding-bottom: 10px; |
|||
border-bottom: 1px solid #f0f0f0; |
|||
} |
|||
</style> |
@ -0,0 +1,14 @@ |
|||
import Vue from 'vue/dist/vue.esm.js' // 必须用完整版
|
|||
import App from './App.vue' |
|||
import ElementUI from 'element-ui'; |
|||
import MyComponents from '../../packages' // 本地引用组件库
|
|||
// import 'element-ui/lib/theme-chalk/index.css' // 如果依赖Element
|
|||
// import './style/theme/index.css'
|
|||
// import './style/theme/common.scss'
|
|||
Vue.use(MyComponents) |
|||
Vue.use(ElementUI); |
|||
|
|||
Vue.config.productionTip = false |
|||
new Vue({ |
|||
render: h => h(App) |
|||
}).$mount('#app') |
@ -0,0 +1,19 @@ |
|||
const path = require('path') |
|||
|
|||
module.exports = { |
|||
chainWebpack: config => { |
|||
config.devServer.watchOptions({ |
|||
ignored: /node_modules/, |
|||
poll: 1000 // 检查文件变化的频率
|
|||
}) |
|||
}, |
|||
lintOnSave: false, |
|||
configureWebpack: { |
|||
resolve: { |
|||
alias: { |
|||
// 别名
|
|||
'@assets': path.resolve(__dirname, '../packages/assets') |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,63 @@ |
|||
{ |
|||
"name": "@zhicheng1012/zhicheng-components", |
|||
"version": "1.0.9", |
|||
"description": "A Vue 2 component library", |
|||
"main": "dist/zhicheng-components.umd.js", |
|||
"publishConfig": { |
|||
"access": "public" |
|||
}, |
|||
"sideEffects": [ |
|||
"**/*.css", |
|||
"**/*.scss" |
|||
], |
|||
"module": "dist/zhicheng-components.esm.js", |
|||
"files": [ |
|||
"dist", |
|||
"packages" |
|||
], |
|||
"scripts": { |
|||
"build": "webpack --config build/webpack.config.js", |
|||
"serve": "cd examples && npm run serve", |
|||
"lint": "eslint --ext .js,.vue packages", |
|||
"prepublishOnly": "npm run build", |
|||
"release": "npm version patch && npm publish" |
|||
}, |
|||
"devDependencies": { |
|||
"babel-eslint": "~10.1.0", |
|||
"css-loader": "~5.2.7", |
|||
"eslint": "~6.8.0", |
|||
"eslint-plugin-vue": "~6.2.2", |
|||
"file-loader": "^6.2.0", |
|||
"mini-css-extract-plugin": "^1.6.2", |
|||
"sass": "^1.32.13", |
|||
"sass-loader": "^8.0.2", |
|||
"style-loader": "~2.0.0", |
|||
"url-loader": "^4.1.1", |
|||
"vue": "^2.6.14", |
|||
"vue-loader": "^15.9.8", |
|||
"vue-svg-loader": "^0.16.0", |
|||
"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" |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not dead", |
|||
"not ie 11" |
|||
], |
|||
"engines": { |
|||
"node": ">=12.0.0 <=16.x", |
|||
"npm": ">=6.0.0" |
|||
}, |
|||
"keywords": [ |
|||
"vue2", |
|||
"component-library", |
|||
"ui-components" |
|||
], |
|||
"license": "MIT" |
|||
} |
@ -0,0 +1,17 @@ |
|||
module.exports = { |
|||
env: { |
|||
browser: true, |
|||
es2021: true |
|||
}, |
|||
extends: [ |
|||
'eslint:recommended', |
|||
'plugin:vue/essential' |
|||
], |
|||
parserOptions: { |
|||
ecmaVersion: 12, |
|||
sourceType: 'module' |
|||
}, |
|||
rules: { |
|||
'vue/multi-word-component-names': 'off' |
|||
} |
|||
} |
@ -0,0 +1,7 @@ |
|||
import DevicePreview from './src/index.vue' |
|||
|
|||
DevicePreview.install = function(Vue) { |
|||
Vue.component(DevicePreview.name || 'DevicePreview', DevicePreview) |
|||
} |
|||
|
|||
export default DevicePreview |
@ -0,0 +1,120 @@ |
|||
<template> |
|||
<div class="preview-container"> |
|||
<div class="preview_top flex-between"> |
|||
<b class="preview-title">实时预览</b> |
|||
<div class="toggle-container"> |
|||
<div class="toggle-button" v-if="showPc" :class="{ active: activeView === 'desktop' }" |
|||
@click="switchView('desktop')"> |
|||
电脑端 |
|||
</div> |
|||
<div class="toggle-button" v-if="showMobile" :class="{ active: activeView === 'mobile' }" |
|||
@click="switchView('mobile')"> |
|||
手机端 |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="content-container"> |
|||
<!-- 电脑端内容 --> |
|||
<div v-show="activeView === 'desktop'" class="desktop-view"> |
|||
<slot name="desktop"></slot> |
|||
</div> |
|||
|
|||
<!-- 手机端内容 --> |
|||
<div v-show="activeView === 'mobile'" class="mobile-view"> |
|||
<slot name="mobile"></slot> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'DevicePreview', |
|||
props:{ |
|||
showMobile:{ |
|||
type:Boolean, |
|||
default:true |
|||
}, |
|||
showPc:{ |
|||
type:Boolean, |
|||
default:true |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
activeView: 'desktop' // 默认显示电脑端 |
|||
} |
|||
}, |
|||
methods: { |
|||
switchView(view) { |
|||
this.activeView = view; |
|||
} |
|||
} |
|||
} |
|||
</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> |
@ -0,0 +1,7 @@ |
|||
import GroupFormBtns from './src/index.vue' |
|||
|
|||
GroupFormBtns.install = function(Vue) { |
|||
Vue.component(GroupFormBtns.name || 'GroupFormBtns', GroupFormBtns) |
|||
} |
|||
|
|||
export default GroupFormBtns |
@ -0,0 +1,38 @@ |
|||
|
|||
|
|||
<template> |
|||
<div class="btns-wrap flex"> |
|||
<GuipButton type="ignore" @click="cancelClick">取消</GuipButton> |
|||
<GuipButton type="primary" @click="confirmClick">保存</GuipButton> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import GuipButton from '../../GuipButton/src/index.vue'; |
|||
|
|||
export default { |
|||
name: 'GroupFormBtns', |
|||
props: [''], |
|||
components: { |
|||
GuipButton |
|||
}, |
|||
data(){ |
|||
return{ |
|||
|
|||
} |
|||
}, |
|||
methods:{ |
|||
cancelClick(){ |
|||
this.$emit('cancel') |
|||
}, |
|||
confirmClick(){ |
|||
this.$emit('confirm') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped lang="scss"> |
|||
.btns-wrap{ |
|||
margin-top: 24px; |
|||
justify-content: flex-end; |
|||
} |
|||
</style> |
@ -0,0 +1,7 @@ |
|||
import GuipButton from './src/index.vue' |
|||
|
|||
GuipButton.install = function(Vue) { |
|||
Vue.component(GuipButton.name || 'GuipButton', GuipButton) |
|||
} |
|||
|
|||
export default GuipButton |
@ -0,0 +1,79 @@ |
|||
<template> |
|||
<el-button |
|||
:type="type" |
|||
v-bind="$attrs" |
|||
:plain="plain" |
|||
:loading="loading" |
|||
:size="size" |
|||
:disabled="disabled" |
|||
@click="$emit('click')" |
|||
:style="{...btnstyle}" |
|||
> |
|||
<slot></slot> |
|||
</el-button> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'GuipButton', |
|||
props:{ |
|||
type:{ |
|||
type:String, |
|||
default:'primary' |
|||
}, |
|||
size:{ |
|||
type:String, |
|||
default:'normal' |
|||
}, |
|||
// 为false 的可以不需要传参 |
|||
plain:{ |
|||
type:Boolean, |
|||
default:false |
|||
}, |
|||
loading:{ |
|||
type:Boolean, |
|||
default:false |
|||
}, |
|||
disabled:{ |
|||
type:Boolean, |
|||
default:false |
|||
}, |
|||
btnstyle:Object |
|||
}, |
|||
data() { |
|||
return { |
|||
radio: '' |
|||
} |
|||
}, |
|||
render(h) { |
|||
return h('el-button', { |
|||
attrs: this.$attrs, |
|||
on: { |
|||
click: e => this.$emit('click', e) |
|||
} |
|||
}, this.$slots.default) |
|||
}, |
|||
mounted(){ |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
<style scoped lang="scss"> |
|||
button span{ |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.rotating-svg { |
|||
animation: rotate 2s linear infinite; |
|||
} |
|||
|
|||
@keyframes rotate { |
|||
from { |
|||
transform: rotate(0deg); |
|||
} |
|||
to { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,7 @@ |
|||
import GuipInput from './src/index.vue' |
|||
|
|||
GuipInput.install = function(Vue) { |
|||
Vue.component(GuipInput.name || 'GuipInput', GuipInput) |
|||
} |
|||
|
|||
export default GuipInput |
@ -0,0 +1,150 @@ |
|||
<template> |
|||
<el-form-item :style="{ ...styleObject }" :required="required" |
|||
:class="[{ 'column': column }, { 'w510': addClass == 'w510' }, { 'w388': addClass == 'w388' }, 'form-item']" :label="label" |
|||
:prop="prop" :rules="rules"> |
|||
<p v-if="desc" class="desc_right">{{ desc }}</p> |
|||
<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)" > |
|||
<!-- 自定义前面小图标 --> |
|||
<template v-slot:prepend> |
|||
<slot name="prependshow"></slot> |
|||
</template> |
|||
<template v-slot:prefix> |
|||
<slot name="prefix"></slot> |
|||
</template> |
|||
<!-- 清除小图标 --> |
|||
<template v-slot:suffix> |
|||
<slot name="suffix"></slot> |
|||
</template> |
|||
<template v-slot:append> |
|||
<slot name="appendshow"></slot> |
|||
</template> |
|||
|
|||
<!-- :error="errorMessage" show-message --> |
|||
|
|||
<!-- <i slot="suffix" v-if="empty" class="el-icon-close" @click="handleClear">h</i> --> |
|||
<!-- <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> |
|||
</el-form-item> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'GuipInput', |
|||
props: ['value', 'styleObject', 'disabled', 'defaultValue', 'placeholder','required', |
|||
'maxlength', 'minLength', 'clear', 'width', 'height', 'showWordLimit', |
|||
'label', 'type', 'prop', 'rules', 'column', 'addClass', 'desc', 'unit'], |
|||
data() { |
|||
return { |
|||
inputValue: this.value || this.defaultValue, |
|||
maxlength1: '', |
|||
minLength1: 0, |
|||
style: { |
|||
width: '510px', |
|||
height: '38px' |
|||
}, |
|||
placeholder1: '' |
|||
} |
|||
}, |
|||
watch: { // 监听外部传来的 value prop 的变化,以便同步到内部状态 inputValue 上(可选) |
|||
// defaultValue(newVal) { |
|||
// console.log(newVal,'newVal'); |
|||
// this.inputValue = newVal; |
|||
// }, |
|||
value(newVal) { |
|||
this.inputValue = newVal; |
|||
}, |
|||
defaultValue(newVal) { |
|||
// 如果没有value但有defaultValue变化时更新 |
|||
if (!this.value && newVal !== this.inputValue) { |
|||
this.inputValue = newVal; |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
// 默认值赋值 |
|||
// if (this.defaultValue != null) { |
|||
// this.inputValue = this.defaultValue; |
|||
// } |
|||
// 默认提示语 |
|||
if (this.placeholder) { |
|||
this.placeholder1 = this.placeholder; |
|||
} |
|||
// 默认提示语 |
|||
if (this.maxlength) { |
|||
this.maxlength1 = this.maxlength; |
|||
} |
|||
// 默认提示语 |
|||
if (this.minLength) { |
|||
this.minLength1 = this.minLength; |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
let els = document.querySelectorAll('.el-input'); |
|||
els.forEach(item => { |
|||
item.onmouseover = function () { |
|||
item.classList.add("hoverclass") |
|||
} |
|||
item.onmouseout = function () { |
|||
item.classList.remove("hoverclass") |
|||
} |
|||
// item.addEventListener('mouseover',function(){ |
|||
// console.log('滑过'); |
|||
// item.classList.add("hoverclass") |
|||
// }) |
|||
// item.addEventListener('mouseoout',function(){ |
|||
// console.log('滑出'); |
|||
// item.classList.remove("hoverclass") |
|||
// }) |
|||
// item.addEventListener('mouseoenter',function(){ |
|||
// console.log('滑---'); |
|||
// item.classList.add("hoverclass") |
|||
// }) |
|||
// item.addEventListener('mouseoleave',function(){ |
|||
// console.log('滑出'); |
|||
// item.classList.remove("hoverclass") |
|||
// }) |
|||
}) |
|||
// console.log(el,'====9999'); |
|||
// if(els&& this.styleObject){ |
|||
// for(var key in this.styleObject){ |
|||
// els.style[key] = this.styleObject[key] |
|||
// } |
|||
// } |
|||
}) |
|||
}, |
|||
methods: { |
|||
// input 事件 |
|||
// changeInput(event){ |
|||
// this.$emit('input', event); |
|||
// } |
|||
// handleClear(){ |
|||
// console.log('清除---'); |
|||
// this.$emit('clear', '清楚逻辑') |
|||
// } |
|||
handleKeydown(e) { |
|||
console.log(e); |
|||
// if (e.key === '1') { |
|||
e.preventDefault(); // 阻止默认行为 |
|||
// } |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.unit { |
|||
position: absolute; |
|||
right: 12px; |
|||
/* 根据需要调整位置 */ |
|||
top: 50%; |
|||
transform: translateY(-50%); |
|||
pointer-events: none; |
|||
/* 防止单位文本影响输入框的点击事件 */ |
|||
} |
|||
</style> |
@ -0,0 +1,7 @@ |
|||
import GuipRadio from './src/index.vue' |
|||
|
|||
GuipRadio.install = function(Vue) { |
|||
Vue.component(GuipRadio.name || 'GuipRadio', GuipRadio) |
|||
} |
|||
|
|||
export default GuipRadio |
@ -0,0 +1,157 @@ |
|||
<template> |
|||
<el-form-item :class="[{ 'column': column }, 'form-item']" :label="label" :prop="prop" :rules="rules" |
|||
:required="required"> |
|||
<el-radio-group v-model="selectedValue" v-bind="$attrs" @change="handleChange"> |
|||
<el-radio v-for="(optionValue, optionKey) in normalizedOptions" :key="optionKey" |
|||
:label="getValue(optionValue)" :disabled="isDisabled(optionValue[valueKey])"> |
|||
{{ getLabel(optionValue) }} |
|||
</el-radio> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'GuipRadio', |
|||
props: { |
|||
// 是否是纵向排列 |
|||
column: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
required: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
// 选项列表,支持多种格式: |
|||
// 1. 数组格式: [{ label: '显示文本', value: '值', disabled: false }] |
|||
// 2. 对象格式: { key1: 'value1', key2: 'value2' } |
|||
// 3.null |
|||
// 4.‘’ |
|||
options: { |
|||
// type: [Array, Object], |
|||
default: () => null, |
|||
validator: (value) => { |
|||
// 自定义验证器,允许 null、数组或非空对象 |
|||
return value == null || |
|||
value === '' || |
|||
Array.isArray(value) || |
|||
(typeof value === 'object' && value !== null) |
|||
}, |
|||
required: true, |
|||
}, |
|||
// 当前选中的值,使用 v-model 绑定 |
|||
value: { |
|||
type: [String, Number, Boolean], |
|||
default: '', |
|||
}, |
|||
// 表单项的 label |
|||
label: { |
|||
type: String, |
|||
default: '', |
|||
}, |
|||
// 表单项的 prop(用于表单校验) |
|||
prop: { |
|||
type: String, |
|||
default: '', |
|||
}, |
|||
// 校验规则 |
|||
rules: { |
|||
type: Array, |
|||
default: () => [], |
|||
}, |
|||
labelKey: { |
|||
type: String, |
|||
default: 'label' |
|||
}, |
|||
// 自定义value的字段名 |
|||
valueKey: { |
|||
type: String, |
|||
default: 'value' |
|||
}, |
|||
// 格式化label的函数 |
|||
formatter: { |
|||
type: Function, |
|||
default: null |
|||
}, |
|||
// 禁用选项的key数组 |
|||
disabledKeys: { |
|||
type: Array, |
|||
default: () => [] |
|||
} |
|||
}, |
|||
computed: { |
|||
// 统一处理数组和对象格式 |
|||
normalizedOptions() { |
|||
// 处理null或undefined、‘’情况 |
|||
if (this.options == null || !this.options) { |
|||
return []; |
|||
} |
|||
|
|||
// 处理数组 |
|||
if (Array.isArray(this.options)) { |
|||
return this.options.length ? this.options : []; |
|||
} |
|||
|
|||
// 处理对象 |
|||
if (typeof this.options === 'object') { |
|||
const keys = Object.keys(this.options); |
|||
return keys.length ? keys.map(key => ({ |
|||
key, |
|||
value: this.options[key] |
|||
})) : []; |
|||
} |
|||
|
|||
// 其他意外情况返回空数组 |
|||
return []; |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
selectedValue: this.value, // 内部维护的选中值 |
|||
}; |
|||
}, |
|||
watch: { |
|||
// 监听外部传入的 value 变化,更新内部 selectedValue |
|||
value(newVal) { |
|||
this.selectedValue = newVal; |
|||
}, |
|||
}, |
|||
methods: { |
|||
// 选中值变化时触发 |
|||
handleChange(value) { |
|||
this.$emit('input', value); // 更新 v-model |
|||
this.$emit('change', value); // 触发 change 事件 |
|||
}, |
|||
getLabel(option) { |
|||
if (this.formatter) return this.formatter(option); |
|||
|
|||
// 处理对象格式的选项 |
|||
if (typeof option === 'object' && 'key' in option && 'value' in option) { |
|||
return option.value; |
|||
} |
|||
|
|||
return option[this.labelKey] || option; |
|||
}, |
|||
getValue(option) { |
|||
// 处理对象格式的选项 |
|||
if (typeof option === 'object' && 'key' in option && 'value' in option) { |
|||
return option.key; |
|||
} |
|||
|
|||
return option[this.valueKey] || option; |
|||
}, |
|||
// 判断选项是否禁用 |
|||
isDisabled(key) { |
|||
return this.disabledKeys.includes(key); |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 自定义样式 */ |
|||
.el-radio-group { |
|||
margin: 10px 0; |
|||
} |
|||
</style> |
@ -0,0 +1,7 @@ |
|||
import GuipTextarea from './src/index.vue' |
|||
|
|||
GuipTextarea.install = function(Vue) { |
|||
Vue.component(GuipTextarea.name || 'GuipTextarea', GuipTextarea) |
|||
} |
|||
|
|||
export default GuipTextarea |
@ -0,0 +1,90 @@ |
|||
<template> |
|||
<el-form-item :label="label" :prop="prop" :rules="rules" :class="[{ 'column': column }]" :required="required"> |
|||
<p v-if="desc" class="desc_right">{{ desc }}</p> |
|||
<el-input |
|||
type="textarea" |
|||
v-bind="$attrs" |
|||
v-model="innerValue" |
|||
:style="{ width: width, height: height }" |
|||
:rows="rows" |
|||
@input="handleInput" |
|||
@change="handleChange" |
|||
></el-input> |
|||
</el-form-item> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'GuipTextarea', |
|||
inheritAttrs: false, |
|||
props: { |
|||
// v-model 绑定的值 |
|||
value: { |
|||
type: [String, Number], |
|||
default: '' |
|||
}, |
|||
// 宽度,可以是 '100px' 或 '100%' 等形式 |
|||
width: { |
|||
type: String, |
|||
default: '100%' |
|||
}, |
|||
desc: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// 高度,可以是 '100px' 或 '100%' 等形式 |
|||
height: { |
|||
type: String, |
|||
default: 'auto' |
|||
}, |
|||
// 默认行数 |
|||
rows: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
// 表单标签 |
|||
label: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
column: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// 表单校验的 prop |
|||
prop: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// 表单校验规则 |
|||
rules: { |
|||
type: [Object, Array], |
|||
default: () => [] |
|||
}, |
|||
required:{ |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
innerValue: this.value |
|||
} |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
if (newVal !== this.innerValue) { |
|||
this.innerValue = newVal |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
handleInput(value) { |
|||
this.$emit('input', value) |
|||
}, |
|||
handleChange(value) { |
|||
this.$emit('change', value) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,7 @@ |
|||
import PromptText from './src/index.vue' |
|||
|
|||
PromptText.install = function(Vue) { |
|||
Vue.component(PromptText.name || 'PromptText', PromptText) |
|||
} |
|||
|
|||
export default PromptText |
@ -0,0 +1,101 @@ |
|||
<template> |
|||
<div class="prompt-text" :class="typeClass"> |
|||
<div class="flex-text"> |
|||
<div class="flex"> |
|||
<img class="prompt-icon" :src="typeIcon" alt=""> |
|||
<span class="prompt-desc">{{ text }}</span> |
|||
</div> |
|||
<div class="flex"> |
|||
<slot name="next_desc" /> |
|||
</div> |
|||
</div> |
|||
<div class="prompt-extra"> |
|||
<slot name="desc" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
|
|||
export default { |
|||
name: 'PromptText', |
|||
props: { |
|||
text: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
type: { |
|||
type: [Number, String], |
|||
default: 2 |
|||
}, |
|||
}, |
|||
components: { |
|||
}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
computed: { |
|||
typeClass() { |
|||
switch (parseInt(this.type)) { |
|||
case 1: return 'info'; |
|||
case 2: return 'notice'; |
|||
case 3: return 'warning'; |
|||
default: return 'notice'; |
|||
} |
|||
}, |
|||
typeIcon() { |
|||
switch (parseInt(this.type)) { |
|||
case 1: return require('../../assets/prompt-icon-1.svg'); |
|||
case 2: return require('../../assets/prompt-icon-2.svg'); |
|||
case 3: return require('../../assets/prompt-icon-3.svg'); |
|||
default: return require('../../assets/prompt-icon-2.svg'); |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
} |
|||
} |
|||
</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> |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 771 B |
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,40 @@ |
|||
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 'element-ui/lib/theme-chalk/index.css' // 如果依赖Element
|
|||
import './styles/index.css' // 全局引入
|
|||
import './styles/common.scss' // 全局引入
|
|||
|
|||
const components = [ |
|||
GuipButton, |
|||
GroupFormBtns, |
|||
GuipInput, |
|||
PromptText, |
|||
GuipTextarea, |
|||
DevicePreview, |
|||
GuipRadio |
|||
] |
|||
|
|||
const install = function (Vue) { |
|||
components.forEach(component => { |
|||
if (!component.name) { |
|||
throw new Error(`Component name is required: ${component}`) |
|||
} |
|||
Vue.component(component.name, component) |
|||
}) |
|||
} |
|||
|
|||
export default { |
|||
install, |
|||
GuipButton, |
|||
GroupFormBtns, |
|||
GuipInput, |
|||
PromptText, |
|||
GuipTextarea, |
|||
DevicePreview, |
|||
GuipRadio |
|||
} |