├── public ├── pages │ ├── sdk-sdk.json │ ├── console.json │ ├── crud-dynamic.json │ ├── iframe-iframe.json │ ├── editor.json │ ├── start.json │ ├── rich-text.json │ ├── form.json │ ├── error.json │ ├── video-video.json │ ├── event-action-custom.json │ ├── tabs-dynamic.json │ ├── tabs-tab2.json │ ├── tabs-tab1.json │ ├── linkpage-form-submit.json │ ├── task-task.json │ ├── crud-popover.json │ ├── event-switch.json │ ├── ide.json │ ├── tabs-form.json │ ├── audio-audio.json │ ├── crud-view.json │ ├── crud-edit.json │ ├── linkpage-page.json │ ├── services-schema.json │ ├── crud-new.json │ ├── linkpage-options.json │ ├── linkpage-form.json │ ├── event-action-logic.json │ ├── sub-form.json │ ├── custom.json │ ├── crud-item-action.json │ ├── services-form.json │ ├── crud-columns.json │ ├── hint.json │ ├── crud-keyboards.json │ ├── wizard.json │ ├── event-tabs.json │ ├── event-input-excel.json │ ├── carousel-carousel.json │ ├── event-input-rating.json │ ├── reaction.json │ ├── crud-merge-cell.json │ ├── crud-header-group.json │ ├── validation.json │ ├── formula.json │ ├── crud-list.json │ ├── horizontal-horizontal.json │ ├── event-action-dataflow.json │ ├── tabs-tab3.json │ ├── services-data.json │ ├── event-action-stop.json │ ├── echarts-echarts.json │ ├── table.json │ ├── remote.json │ ├── anchor-nav.json │ ├── wizard-wizard.json │ ├── fieldset.json │ ├── fields-tabs.json │ ├── crud-jump-next.json │ ├── condition-builder.json │ └── my-custom.jsx ├── robots.txt ├── logo.png ├── favicon.ico ├── img │ ├── markdown │ │ ├── edit.png │ │ └── preview.png │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ └── msapplication-icon-144x144.png └── index.html ├── .gitattributes ├── .browserslistrc ├── .github ├── renovate.json ├── PULL_REQUEST_TEMPLATE.md ├── codecov.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.md │ ├── need-help-issue.md │ └── bug_report.md ├── SECURITY.md ├── release-drafter.yml └── workflows │ ├── release.yml │ ├── clear.yml │ └── setup │ └── lighthouse-audit.json ├── .eslintignore ├── babel.config.js ├── src ├── assets │ └── logo.png ├── App.vue ├── views │ ├── amis │ │ ├── View.vue │ │ └── Editor.vue │ ├── NotFound │ │ └── index.vue │ └── Login │ │ └── index.vue ├── store │ ├── index.js │ └── modules │ │ └── amis.js ├── router │ └── index.js ├── main.js ├── registerServiceWorker.js └── components │ ├── Editor │ └── index.vue │ ├── View │ └── index.vue │ └── Amis │ └── index.vue ├── .npmrc ├── .stylelintrc.js ├── webstorm.config.js ├── .lintstagedrc.json ├── .prettierrc ├── tea.yaml ├── tsconfig.json ├── .editorconfig ├── jsconfig.json ├── vercel.json ├── .gitignore ├── prettier.config.js ├── api └── proxy.js ├── CHANGELOG.md ├── README.md ├── .eslintrc.js ├── package.json └── vue.config.js /public/pages/sdk-sdk.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/assets 2 | src/icons 3 | public 4 | dist 5 | node_modules 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'] 3 | } 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /public/img/markdown/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/markdown/edit.png -------------------------------------------------------------------------------- /public/pages/console.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "Dashboard", 4 | "body": "body..." 5 | } 6 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict = true 2 | shamefully-hoist = true 3 | hoist = true 4 | registry = https://registry.npmjs.org/ 5 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['stylelint-config-recess-order', 'stylelint-config-prettier'] 3 | } 4 | -------------------------------------------------------------------------------- /public/img/markdown/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/markdown/preview.png -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /webstorm.config.js: -------------------------------------------------------------------------------- 1 | const webpackConfig = require('@vue/cli-service/webpack.config.js') 2 | module.exports = webpackConfig 3 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: '30...100' 3 | 4 | status: 5 | project: 6 | default: 7 | threshold: 1 8 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.{js,jsx,ts,tsx}": ["prettier --write .", "eslint --fix"], 3 | "*.md": ["prettier --write"] 4 | } 5 | -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "tabWidth": 2, 4 | "trailingComma": "none", 5 | "singleQuote": true, 6 | "arrowParens": "avoid" 7 | } 8 | -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dext7r/amis-admin-vue/HEAD/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /tea.yaml: -------------------------------------------------------------------------------- 1 | # https://tea.xyz/what-is-this-file 2 | --- 3 | version: 1.0.0 4 | codeOwners: 5 | - '0xBC99fC607a02790fc46c7e77F55fECAb120B9896' 6 | quorum: 1 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: h7ml issues template 4 | url: https://github.com/h7ml 5 | about: h7ml 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "allowJs": true 7 | }, 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /public/pages/crud-dynamic.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "动态表格", 3 | "subTitle": "返回表格数据的同时返回列信息", 4 | "body": { 5 | "type": "crud", 6 | "api": "/amis/api/crud/dynamic?waitSeconds=1" 7 | } 8 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "es6", 5 | "allowSyntheticDefaultImports": true, 6 | "baseUrl": "./", 7 | "paths": { 8 | "@/*": ["src/*"] 9 | } 10 | }, 11 | "exclude": ["node_modules"] 12 | } 13 | -------------------------------------------------------------------------------- /public/pages/iframe-iframe.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "IFrame 可以用来嵌入其他网站", 3 | "body": [ 4 | { 5 | "type": "iframe", 6 | "className": "b-a", 7 | "src": "https://amis-admin-vue.vercel.app/index#/Editor", 8 | "height": "90vh" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 请求新功能 3 | about: 提出你期待的功能特性 4 | labels: Feature 5 | assignees: h7ml 6 | --- 7 | 8 | ### 你在什么场景下需要该功能? 9 | 10 | 11 | 12 | ### 描述最优的解决方案 13 | 14 | 15 | 16 | ### 描述候选解决方案 17 | 18 | 19 | 20 | ### 其他信息 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # 安全报告 Security report 2 | 3 | 如果你发现安全相关漏洞请通过如下任意一种方式告知我们:\ 4 | If you find security-related vulnerabilities, please inform us in any of the following ways: 5 | 6 | - 直接开 Issue(请隐去站点、实际项目等敏感信息)\ 7 | Open Issue directly (please hide sensitive information such as site and actual project) 8 | - 发邮件至 h7ml@qq.com\ 9 | Send an email to h7ml@qq.com 10 | 11 | 非常感谢!\ 12 | Thank you very much! 13 | -------------------------------------------------------------------------------- /public/pages/editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "代码编辑器", 4 | "subTitle": "使用的monaco-editor,用到了 worker, 如果控制台没有报错,说明一起正常。", 5 | "body": [ 6 | { 7 | "type": "form", 8 | "controls": [ 9 | { 10 | "type": "editor", 11 | "name": "js", 12 | "label": "Javascript", 13 | "size": "md" 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { 4 | "source": "/amis/(.*)", 5 | "destination": "/api/proxy" 6 | } 7 | ], 8 | "headers": [ 9 | { 10 | "source": "/(.*).(ttf|otf|woff2|woff|eot|json)", 11 | "headers" : [ 12 | { 13 | "key" : "Cache-Control", 14 | "value" : "public, max-age=31536000, immutable" 15 | } 16 | ] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # lock files 17 | yarn.lock 18 | #pnpm-lock.yaml 19 | package-lock.json 20 | 21 | # Editor directories and files 22 | .idea 23 | .vscode 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | tabWidth: 2, 4 | useTabs: false, 5 | semi: false, 6 | singleQuote: true, 7 | quoteProps: 'as-needed', 8 | jsxSingleQuote: false, 9 | trailingComma: 'es5', 10 | bracketSpacing: true, 11 | bracketSameLine: false, 12 | arrowParens: 'always', 13 | htmlWhitespaceSensitivity: 'ignore', 14 | vueIndentScriptAndStyle: true, 15 | endOfLine: 'lf' 16 | } 17 | -------------------------------------------------------------------------------- /src/views/amis/View.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 21 | -------------------------------------------------------------------------------- /public/pages/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "标题", 4 | "remark": { 5 | "title": "标题", 6 | "body": "这是一段描述问题,注意到了没,还可以设置标题。而且只有点击了才弹出来。", 7 | "icon": "question-mark", 8 | "placement": "right", 9 | "trigger": "click", 10 | "rootClose": true 11 | }, 12 | "body": "内容部分. 可以使用 \\${var} 获取变量。如: `\\$date`: ${date}", 13 | "aside": "边栏部分", 14 | "toolbar": "工具栏", 15 | "initApi": "/amis/api/mock2/page/initData" 16 | } -------------------------------------------------------------------------------- /api/proxy.js: -------------------------------------------------------------------------------- 1 | // 该服务为 vercel serve跨域处理 2 | const { createProxyMiddleware } = require('http-proxy-middleware') 3 | 4 | module.exports = (req, res) => { 5 | let target = '' 6 | if (req.url.startsWith('/amis')) { 7 | target = 'https://aisuda.bce.baidu.com/amis/' 8 | } 9 | // 创建代理对象并转发请求 10 | createProxyMiddleware({ 11 | target, 12 | changeOrigin: true, 13 | pathRewrite: { 14 | '^/amis/': '/' 15 | } 16 | })(req, res) 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/need-help-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Need help issue 3 | about: Question for use(问题求助) 4 | title: '' 5 | labels: question 6 | assignees: h7ml 7 | --- 8 | 9 | **Question (问题描述)** 10 | How to use component `s-table` paging 11 | 12 | **Describe the solution you'd like (你期待的是什么?)** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Additional context(附加信息)** 16 | Add any other context or screenshots about the feature request here. 17 | -------------------------------------------------------------------------------- /public/pages/rich-text.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "富文本编辑器", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 7 | "title": "Form elements", 8 | "body": [ 9 | { 10 | "name": "html", 11 | "type": "input-rich-text", 12 | "label": "富文本", 13 | "value": "

Just do IT

" 14 | } 15 | ] 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vuex from 'vuex' 2 | import createPersistedState from 'vuex-persistedstate' 3 | import Vue from 'vue' 4 | Vue.use(Vuex) 5 | const files = require.context('./modules', false, /\.js$/) 6 | const modules = {} 7 | files.keys().forEach(key => { 8 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default 9 | }) 10 | Object.keys(modules).forEach(key => { 11 | modules[key]['namespaced'] = true 12 | }) 13 | const store = new Vuex.Store({ 14 | modules, 15 | plugins: [createPersistedState()] 16 | }) 17 | export default store 18 | -------------------------------------------------------------------------------- /public/pages/form.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单页面", 4 | "body": [ 5 | { 6 | "type": "form", 7 | "mode": "horizontal", 8 | "api": "/amis/api/mock2/form/saveForm", 9 | "body": [ 10 | { 11 | "label": "Name", 12 | "type": "input-text", 13 | "name": "name" 14 | }, 15 | { 16 | "label": "Email", 17 | "type": "input-email", 18 | "placeholder": "请输入邮箱地址", 19 | "name": "email" 20 | } 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | categories: 2 | - title: 新功能 3 | label: feat 4 | - title: Bugfix 5 | label: fix 6 | - title: 依赖更新 7 | label: dep 8 | - title: 日常维护 9 | label: chore 10 | - title: 文档 11 | label: doc 12 | 13 | autolabeler: 14 | - label: 'feat' 15 | title: 16 | - '/feat/i' 17 | - label: 'fix' 18 | title: 19 | - '/fix/i' 20 | - label: 'chore' 21 | title: 22 | - '/chore/i' 23 | - label: 'doc' 24 | title: 25 | - '/doc/i' 26 | 27 | template: | 28 | 29 | ## 更新记录 30 | $CHANGES 31 | -------------------------------------------------------------------------------- /public/pages/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "标题", 4 | "remark": "提示 Tip", 5 | "body": [ 6 | "\n

`initApi` 拉取失败时,页面内容区会显示对应的错误信息。

\n\n

其他提示示例

\n ", 7 | { 8 | "type": "alert", 9 | "level": "success", 10 | "body": "温馨提示:对页面功能的提示说明,绿色为正向类的消息提示" 11 | }, 12 | { 13 | "type": "alert", 14 | "level": "warning", 15 | "body": "您的私有网络已达到配额,如需更多私有网络,可以通过工单申请" 16 | } 17 | ], 18 | "aside": "边栏", 19 | "toolbar": "工具栏", 20 | "initApi": "/amis/api/mock2/page/initDataError" 21 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 报告缺陷 3 | about: 报告缺陷以帮助我们改进 4 | labels: bug 5 | assignees: h7ml 6 | --- 7 | 8 | ### 描述问题 9 | 10 | 11 | 12 | ```markdown 13 | 如果是解析渲染问题的话请在此处贴入 Markdown 原文 14 | ``` 15 | 16 | ### 期待的结果 17 | 18 | 19 | 20 | ### 截屏或录像 21 | 22 | 27 | 28 | ### 版本信息 29 | 30 | - 版本: 31 | - 操作系统: 32 | - 浏览器: 33 | 34 | ### 其他信息 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/views/NotFound/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /public/pages/video-video.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "视频播放器", 3 | "body": [ 4 | "

另外还支持直播流, flv 和 hls 格式

", 5 | { 6 | "type": "video", 7 | "autoPlay": false, 8 | "rates": [ 9 | 1, 10 | 1.5, 11 | 2 12 | ], 13 | "jumpFrame": true, 14 | "jumpBufferDuration": 5, 15 | "frames": { 16 | "00:10": "", 17 | "00:20": "", 18 | "00:30": "" 19 | }, 20 | "src": "/amis/static/video/trailer_hd.mp4", 21 | "poster": "/amis/static/photo/da6376bf988c_3360340.jpg" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Login from '@/views/Login' 4 | import NotFound from '@/views/NotFound' 5 | import View from '@/views/amis/View' 6 | import Editor from '@/views/amis/Editor' 7 | Vue.use(Router) 8 | 9 | export default new Router({ 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'View', 14 | component: View 15 | }, 16 | { 17 | path: '/Login', 18 | name: 'Login', 19 | component: Login 20 | }, 21 | { 22 | path: '/Editor', 23 | name: 'Editor', 24 | component: Editor 25 | }, 26 | { 27 | path: '*', 28 | name: 'NotFound', 29 | component: NotFound 30 | } 31 | ] 32 | }) 33 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import '@fortawesome/fontawesome-free/css/all.css' 4 | import 'bootstrap/dist/css/bootstrap.css' 5 | import 'bootstrap/dist/js/bootstrap.js' 6 | import 'amis/lib/helper.css' 7 | import ElementUI from 'element-ui' 8 | import 'element-ui/lib/theme-chalk/index.css' 9 | require('./registerServiceWorker') 10 | import VueAmisSdk from 'vue-amis-sdk/packages/index' 11 | Vue.use(VueAmisSdk) 12 | console.log(VueAmisSdk) 13 | import { VuePlugin } from 'vuera' 14 | Vue.use(VuePlugin) 15 | Vue.config.productionTip = false 16 | Vue.use(ElementUI) 17 | import store from './store' 18 | import router from './router' 19 | new Vue({ 20 | render: h => h(App), 21 | router, 22 | store 23 | }).$mount('#app') 24 | -------------------------------------------------------------------------------- /public/pages/event-action-custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "自定义JS", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "button", 12 | "label": "发送个请求", 13 | "className": "ml-2", 14 | "onEvent": { 15 | "click": { 16 | "actions": [ 17 | { 18 | "actionType": "custom", 19 | "script": "doAction({actionType: 'ajax',api: '/amis/api/mock2/form/saveForm'});\n //event.stopPropagation();" 20 | } 21 | ] 22 | } 23 | } 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 12 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /public/pages/tabs-dynamic.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "动态选项卡", 4 | "subTitle": "根据变量动态生成", 5 | "data": { 6 | "arr": [ 7 | { 8 | "label": "收入", 9 | "value": 123 10 | }, 11 | { 12 | "label": "支出", 13 | "value": 233 14 | } 15 | ] 16 | }, 17 | "body": [ 18 | { 19 | "type": "tabs", 20 | "source": "${arr}", 21 | "mode": "card", 22 | "tabs": [ 23 | { 24 | "title": "${label}-A", 25 | "body": "选项卡内容 ${value}" 26 | }, 27 | { 28 | "title": "${label}-B", 29 | "body": "选项卡内容 ${value}" 30 | } 31 | ] 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /public/pages/tabs-tab2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "选项卡2页面", 4 | "body": [ 5 | "

也可以多个页面,利用导航nav渲染期模拟 tabs 的效果。

", 6 | { 7 | "type": "nav", 8 | "links": [ 9 | { 10 | "label": "选项卡1", 11 | "icon": "fa fa-cloud", 12 | "to": "./tab1" 13 | }, 14 | { 15 | "label": "选项卡2", 16 | "to": "./tab2" 17 | }, 18 | { 19 | "label": "选项卡3", 20 | "icon": "fa fa-youtube", 21 | "to": "./tab3" 22 | } 23 | ] 24 | }, 25 | { 26 | "type": "wrapper", 27 | "className": "wrapper bg-white b-l b-b b-r", 28 | "body": "选项卡2的内容" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/actions/create-release 2 | name: release 3 | 4 | on: 5 | push: 6 | tags: 7 | - 'v*' 8 | workflow_dispatch: 9 | 10 | # 设置上海时区 11 | env: 12 | TZ: Asia/Shanghai 13 | 14 | jobs: 15 | publish: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | - name: Use Node 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: '14.15.4' 24 | registry-url: https://registry.npmjs.org/ 25 | - run: npm publish --access=public 26 | env: 27 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 28 | - name: Prepare the changelog from the tag message 29 | run: | 30 | VERSION=${GITHUB_REF/refs\/tags\//} 31 | echo "Setting release version to $VERSION" 32 | echo "release_version=$VERSION" >> $GITHUB_ENV 33 | -------------------------------------------------------------------------------- /public/pages/tabs-tab1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "选项卡1页面", 4 | "body": [ 5 | "

也可以多个页面,利用导航nav渲染期模拟 tabs 的效果。这样可以让 url 更加友好,而不是只能用 hash。

", 6 | { 7 | "type": "nav", 8 | "links": [ 9 | { 10 | "label": "选项卡1", 11 | "icon": "fa fa-cloud", 12 | "to": "./tab1" 13 | }, 14 | { 15 | "label": "选项卡2", 16 | "to": "./tab2" 17 | }, 18 | { 19 | "label": "选项卡3", 20 | "icon": "fa fa-youtube", 21 | "to": "./tab3" 22 | } 23 | ] 24 | }, 25 | { 26 | "type": "wrapper", 27 | "className": "wrapper bg-white b-l b-b b-r", 28 | "body": "选项卡1的内容" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /.github/workflows/clear.yml: -------------------------------------------------------------------------------- 1 | name: claer 2 | on: 3 | push: 4 | branches: [check] 5 | workflow_dispatch: 6 | env: 7 | TZ: Asia/Shanghai 8 | 9 | jobs: 10 | clean: 11 | name: Clean 12 | runs-on: ubuntu-latest 13 | timeout-minutes: 60 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | with: 18 | repository: 'Apocalypsor/Workflows-Cleaner' 19 | - name: Set up Python 20 | uses: actions/setup-python@v2 21 | with: 22 | python-version: '3.9' 23 | - name: Install pipenv 24 | run: python -m pip install --upgrade pipenv wheel 25 | - name: Install dependencies 26 | run: | 27 | pipenv requirements > requirements.txt 28 | pip install -r requirements.txt 29 | - name: Clean 30 | env: 31 | GITHUB_REPO: ${{ github.repository }} 32 | GITHUB_TOKEN: ${{ secrets.ACTION_SECRET }} 33 | EXPIRE_TIME: '12h' 34 | run: python run.py 35 | -------------------------------------------------------------------------------- /public/pages/linkpage-form-submit.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单提交后显示结果", 4 | "body": { 5 | "type": "form", 6 | "api": "/amis/api/mock2/form/saveForm", 7 | "title": "查询用户 ID", 8 | "body": [ 9 | { 10 | "type": "input-group", 11 | "name": "input-group", 12 | "body": [ 13 | { 14 | "type": "input-text", 15 | "name": "name", 16 | "label": "姓名" 17 | }, 18 | { 19 | "type": "submit", 20 | "label": "查询", 21 | "level": "primary" 22 | } 23 | ] 24 | }, 25 | { 26 | "type": "static", 27 | "name": "id", 28 | "visibleOn": "typeof data.id !== 'undefined'", 29 | "label": "返回 ID" 30 | } 31 | ], 32 | "actions": [] 33 | } 34 | } -------------------------------------------------------------------------------- /public/pages/task-task.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "异步任务", 3 | "body": [ 4 | "

", 5 | { 6 | "type": "tasks", 7 | "name": "tasks", 8 | "items": [ 9 | { 10 | "label": "hive 任务", 11 | "key": "hive", 12 | "status": 4, 13 | "remark": "查看详情日志。" 14 | }, 15 | { 16 | "label": "小流量", 17 | "key": "partial", 18 | "status": 4 19 | }, 20 | { 21 | "label": "全量", 22 | "key": "full", 23 | "status": 4 24 | } 25 | ] 26 | }, 27 | { 28 | "type": "tasks", 29 | "name": "tasks", 30 | "className": "b-a bg-white table-responsive m-t", 31 | "checkApi": "/amis/api/mock2/task" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /public/pages/crud-popover.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "列展示详情", 3 | "body": { 4 | "type": "crud", 5 | "title": "", 6 | "api": "/amis/api/sample/list", 7 | "columnsTogglable": false, 8 | "columns": [ 9 | { 10 | "name": "id", 11 | "label": "ID", 12 | "width": 20, 13 | "type": "text" 14 | }, 15 | { 16 | "name": "engine", 17 | "label": "Rendering engine", 18 | "type": "text", 19 | "popOver": { 20 | "trigger": "hover", 21 | "showIcon": false, 22 | "body": "Popover 内容:${platform}", 23 | "popOverClassName": "min-w-0", 24 | "position": "left-center-right-center right-center-left-center" 25 | } 26 | }, 27 | { 28 | "name": "browser", 29 | "label": "Browser", 30 | "type": "text" 31 | } 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /.github/workflows/setup/lighthouse-audit.json: -------------------------------------------------------------------------------- 1 | { 2 | "ci": { 3 | "collect": { 4 | "staticDistDir": "." 5 | }, 6 | "assert": { 7 | "assertions": { 8 | "categories:performance": [ 9 | "error", 10 | { 11 | "minScore": 0.8 12 | } 13 | ], 14 | "first-contentful-paint": [ 15 | "error", 16 | { 17 | "maxNumericValue": 1000 18 | } 19 | ], 20 | "interactive": [ 21 | "error", 22 | { 23 | "maxNumericValue": 1500 24 | } 25 | ], 26 | "resource-summary:font:count": [ 27 | "error", 28 | { 29 | "maxNumericValue": 1 30 | } 31 | ], 32 | "resource-summary:script:size": [ 33 | "error", 34 | { 35 | "maxNumericValue": 150000 36 | } 37 | ], 38 | "resource-summary:stylesheet:size": [ 39 | "error", 40 | { 41 | "maxNumericValue": 100000 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /public/pages/event-switch.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "开关组件事件", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "tpl", 12 | "tpl": "Switch组件", 13 | "inline": false, 14 | "wrapperComponent": "h2" 15 | }, 16 | { 17 | "type": "form", 18 | "debug": true, 19 | "body": [ 20 | { 21 | "name": "switch", 22 | "type": "switch", 23 | "option": "开关事件", 24 | "onEvent": { 25 | "change": { 26 | "actions": [ 27 | { 28 | "actionType": "toast", 29 | "msgType": "info", 30 | "msg": "派发change事件" 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import { register } from 'register-service-worker' 3 | // import Vue from 'vue' 4 | if (process.env.NODE_ENV === 'production') { 5 | register(`${process.env.BASE_URL}service-worker.js`, { 6 | ready() { 7 | console.log( 8 | 'App is being served from cache by a service worker.\n' + 9 | 'For more details, visit https://goo.gl/AFskqB' 10 | ) 11 | }, 12 | registered() { 13 | console.log('Service worker has been registered.') 14 | }, 15 | cached() { 16 | console.log('Content has been cached for offline use.') 17 | }, 18 | updatefound() { 19 | console.log('New content is downloading.') 20 | }, 21 | updated() { 22 | console.log('New content is available; please refresh.') 23 | setTimeout(() => { 24 | window.location.reload() 25 | }, 10000) 26 | }, 27 | offline() { 28 | console.log( 29 | 'No internet connection found. App is running in offline mode.' 30 | ) 31 | }, 32 | error(error) { 33 | console.error('Error during service worker registration:', error) 34 | } 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /public/pages/ide.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Editor", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 7 | "title": "", 8 | "body": [ 9 | { 10 | "name": "javascript", 11 | "type": "editor", 12 | "label": "Javascript", 13 | "language": "javascript", 14 | "value": "console.log(1, 2, 3);" 15 | }, 16 | { 17 | "name": "html", 18 | "type": "editor", 19 | "language": "html", 20 | "label": "Html", 21 | "value": "Hello

world

" 22 | }, 23 | { 24 | "name": "css", 25 | "type": "editor", 26 | "language": "css", 27 | "label": "CSS", 28 | "value": "body {color: red;}" 29 | }, 30 | { 31 | "name": "json", 32 | "type": "editor", 33 | "language": "json", 34 | "label": "JSON", 35 | "value": "{\"a\": 1, \"b\": 2}" 36 | } 37 | ] 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 (2022-05-09) 2 | 3 | ### Bug Fixes 4 | 5 | - action ([0390248](https://github.com/h7ml/amis-admin-vue/commit/03902488211de72875e575172b2572b0d7ee6739)) 6 | - action ([1567186](https://github.com/h7ml/amis-admin-vue/commit/15671860d2369c1f12e202a3f7acd61ffd6d46e4)) 7 | - action ([26718fb](https://github.com/h7ml/amis-admin-vue/commit/26718fbab262e176256c14b35814f0e373d97a15)) 8 | - action ([ec9fb16](https://github.com/h7ml/amis-admin-vue/commit/ec9fb1619c892554d53aa7488fa714a61bf413fa)) 9 | - steps ([9fcb345](https://github.com/h7ml/amis-admin-vue/commit/9fcb345cf9638def6463c28d58645624fce5fd7f)) 10 | - yarn.lock ([5a8cdf8](https://github.com/h7ml/amis-admin-vue/commit/5a8cdf8b6024fe0fc76c95e7d21d18cb76148c8a)) 11 | 12 | ### Features 13 | 14 | - 表单(表单展示模式) ([f88f0ab](https://github.com/h7ml/amis-admin-vue/commit/f88f0abd4fed0e390190bd75966a36fc3e8796c5)) 15 | - 表单(所有类型汇总) ([1712f87](https://github.com/h7ml/amis-admin-vue/commit/1712f8773bead8b0d8ec75dc359125ec5f56d209)) 16 | - 引入 vuex 和 elment-ui ([e8f99d2](https://github.com/h7ml/amis-admin-vue/commit/e8f99d2379deccd218e35bd1cc56275fb7b228e7)) 17 | - amis env enableAMISDebug ([50c5093](https://github.com/h7ml/amis-admin-vue/commit/50c50937dfe0b7271a912448e045556d742cd669)) 18 | - icon ([b00268e](https://github.com/h7ml/amis-admin-vue/commit/b00268ebd7a18e0821b94baeecff3f827284ca0a)) 19 | - sync(amis-admin-vue) ([059ff7c](https://github.com/h7ml/amis-admin-vue/commit/059ff7cb462aa5a3f4a95e7229833588a6c8f42f)) 20 | -------------------------------------------------------------------------------- /public/pages/tabs-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单中选项卡分组", 4 | "subTitle": "", 5 | "body": [ 6 | "

多个 controls 可以通过 tabs 来分组展示,表单将作为一个整体提交。

", 7 | { 8 | "type": "form", 9 | "title": "", 10 | "tabs": [ 11 | { 12 | "title": "选项卡1", 13 | "hash": "tab1", 14 | "body": [ 15 | { 16 | "type": "input-text", 17 | "label": "文本1", 18 | "name": "a" 19 | } 20 | ] 21 | }, 22 | { 23 | "title": "选项卡2", 24 | "hash": "tab2", 25 | "body": [ 26 | { 27 | "type": "input-text", 28 | "label": "文本2", 29 | "name": "b" 30 | } 31 | ] 32 | }, 33 | { 34 | "title": "选项卡3", 35 | "hash": "tab3", 36 | "body": [ 37 | { 38 | "type": "input-text", 39 | "label": "文本3", 40 | "name": "c" 41 | } 42 | ] 43 | } 44 | ] 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /public/pages/audio-audio.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "音频播放器", 3 | "body": [ 4 | { 5 | "type": "audio", 6 | "autoPlay": false, 7 | "rates": [ 8 | 1, 9 | 1.5, 10 | 2 11 | ], 12 | "src": "/amis/static/audio/chicane-poppiholla-original-radio-edit.mp3" 13 | }, 14 | { 15 | "type": "form", 16 | "title": "", 17 | "actions": [], 18 | "className": "b v-middle inline w-lg h-xs", 19 | "body": [ 20 | { 21 | "type": "card", 22 | "className": "v-middle w inline no-border", 23 | "header": { 24 | "title": "歌曲名称", 25 | "subTitle": "专辑名称", 26 | "description": "description", 27 | "avatarClassName": "pull-left thumb-md avatar m-r no-border", 28 | "avatar": "/amis/static/photo/bd3eb13533fa828b13b24500f31f4134960a5a44_81bbc2d.jpg" 29 | } 30 | }, 31 | { 32 | "type": "audio", 33 | "className": "v-middle no-border", 34 | "src": "/amis/static/audio/chicane-poppiholla-original-radio-edit.mp3", 35 | "controls": [ 36 | "play" 37 | ] 38 | } 39 | ] 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /public/pages/crud-view.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "查看详情 ${params.id}", 4 | "remark": null, 5 | "toolbar": [ 6 | { 7 | "type": "button", 8 | "actionType": "link", 9 | "link": "/crud/list", 10 | "label": "返回列表" 11 | } 12 | ], 13 | "body": [ 14 | { 15 | "type": "form", 16 | "initApi": "/api/sample/${params.id}", 17 | "controls": [ 18 | { 19 | "type": "static", 20 | "name": "engine", 21 | "label": "Engine" 22 | }, 23 | { 24 | "type": "divider" 25 | }, 26 | { 27 | "type": "static", 28 | "name": "browser", 29 | "label": "Browser" 30 | }, 31 | { 32 | "type": "divider" 33 | }, 34 | { 35 | "type": "static", 36 | "name": "platform", 37 | "label": "Platform(s)" 38 | }, 39 | { 40 | "type": "divider" 41 | }, 42 | { 43 | "type": "static", 44 | "name": "version", 45 | "label": "Engine version" 46 | }, 47 | { 48 | "type": "divider" 49 | }, 50 | { 51 | "type": "static", 52 | "name": "grade", 53 | "label": "CSS grade" 54 | }, 55 | { 56 | "type": "divider" 57 | }, 58 | { 59 | "type": "html", 60 | "html": "

添加其他 Html 片段 需要支持变量替换(todo).

" 61 | } 62 | ] 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /public/pages/crud-edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "修改 ${params.id}", 4 | "remark": null, 5 | "toolbar": [ 6 | { 7 | "type": "button", 8 | "actionType": "link", 9 | "link": "/crud/list", 10 | "label": "返回列表" 11 | } 12 | ], 13 | "body": [ 14 | { 15 | "type": "form", 16 | "initApi": "/api/sample/${params.id}", 17 | "api": "/api/sample/$id", 18 | "redirect": "/crud/list", 19 | "controls": [ 20 | { 21 | "type": "text", 22 | "name": "engine", 23 | "label": "Engine", 24 | "required": true 25 | }, 26 | { 27 | "type": "divider" 28 | }, 29 | { 30 | "type": "text", 31 | "name": "browser", 32 | "label": "Browser", 33 | "required": true 34 | }, 35 | { 36 | "type": "divider" 37 | }, 38 | { 39 | "type": "text", 40 | "name": "platform", 41 | "label": "Platform(s)", 42 | "required": true 43 | }, 44 | { 45 | "type": "divider" 46 | }, 47 | { 48 | "type": "text", 49 | "name": "version", 50 | "label": "Engine version" 51 | }, 52 | { 53 | "type": "divider" 54 | }, 55 | { 56 | "type": "select", 57 | "name": "grade", 58 | "label": "CSS grade", 59 | "options": ["A", "B", "C", "D", "X"] 60 | } 61 | ] 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /public/pages/linkpage-page.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "地址栏变化自动更新", 4 | "initApi": "/amis/api/mock2/form/initData?id=${id}", 5 | "aside": { 6 | "type": "wrapper", 7 | "size": "xs", 8 | "className": "", 9 | "body": { 10 | "type": "nav", 11 | "stacked": true, 12 | "links": [ 13 | { 14 | "label": "页面1", 15 | "to": "?id=1" 16 | }, 17 | { 18 | "label": "页面2", 19 | "children": [ 20 | { 21 | "label": "页面2-1", 22 | "to": "?id=2-1" 23 | }, 24 | { 25 | "label": "页面2-2", 26 | "to": "?id=2-2" 27 | }, 28 | { 29 | "label": "页面2-3(disabled)", 30 | "disabled": true, 31 | "to": "?id=2-3" 32 | } 33 | ] 34 | }, 35 | { 36 | "label": "页面3", 37 | "to": "?id=3" 38 | } 39 | ] 40 | } 41 | }, 42 | "body": [ 43 | "

注意 page 渲染器的 `initApi` 中有变量跟地址栏中变量关联,只要值发生了变化,就会重新拉取一次 initApi。

", 44 | "

这些数据是通过 initApi 拉取到的数据。 `\\$infoId`: ${infoId|default:空}

" 45 | ] 46 | } -------------------------------------------------------------------------------- /public/pages/services-schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "动态加载页面", 4 | "body": [ 5 | "可以通过 serviceschemaApi 动态控制内容。", 6 | { 7 | "type": "form", 8 | "title": "条件输入", 9 | "panelClassName": "panel-info m-t", 10 | "target": "service1", 11 | "mode": "inline", 12 | "submitOnInit": true, 13 | "body": [ 14 | { 15 | "label": "加载页面类型", 16 | "required": true, 17 | "type": "button-group-select", 18 | "submitOnChange": true, 19 | "value": "crud", 20 | "name": "type", 21 | "options": [ 22 | { 23 | "label": "Crud", 24 | "value": "crud" 25 | }, 26 | { 27 | "label": "Form", 28 | "value": "form" 29 | }, 30 | { 31 | "label": "Tabs", 32 | "value": "tabs" 33 | } 34 | ] 35 | } 36 | ] 37 | }, 38 | { 39 | "name": "service1", 40 | "type": "service", 41 | "className": "m-t", 42 | "initFetchSchema": false, 43 | "schemaApi": "/amis/api/mock2/service/schema?type=$type" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /public/pages/crud-new.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "新增", 4 | "remark": null, 5 | "toolbar": [ 6 | { 7 | "type": "button", 8 | "actionType": "link", 9 | "link": "/crud/list", 10 | "label": "返回列表" 11 | } 12 | ], 13 | "body": [ 14 | { 15 | "title": "", 16 | "type": "form", 17 | "redirect": "/crud/list", 18 | "name": "sample-edit-form", 19 | "api": "/api/sample", 20 | "controls": [ 21 | { 22 | "type": "text", 23 | "name": "engine", 24 | "label": "Engine", 25 | "required": true, 26 | "inline": false, 27 | "description": "", 28 | "descriptionClassName": "help-block", 29 | "placeholder": "", 30 | "addOn": null 31 | }, 32 | { 33 | "type": "divider" 34 | }, 35 | { 36 | "type": "text", 37 | "name": "browser", 38 | "label": "Browser", 39 | "required": true 40 | }, 41 | { 42 | "type": "divider" 43 | }, 44 | { 45 | "type": "text", 46 | "name": "platform", 47 | "label": "Platform(s)", 48 | "required": true 49 | }, 50 | { 51 | "type": "divider" 52 | }, 53 | { 54 | "type": "text", 55 | "name": "version", 56 | "label": "Engine version" 57 | }, 58 | { 59 | "type": "divider" 60 | }, 61 | { 62 | "type": "text", 63 | "name": "grade", 64 | "label": "CSS grade" 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /public/pages/linkpage-options.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单选线之间的远程联动", 4 | "body": { 5 | "type": "form", 6 | "mode": "horizontal", 7 | "title": "", 8 | "actions": [], 9 | "body": [ 10 | "

表单选项可以设置 source 通过 API 远程拉取,同时如果 source 中有变量的话,变量值发生变化就会重新拉取,达到联动效果。

", 11 | { 12 | "type": "divider" 13 | }, 14 | { 15 | "label": "选项1", 16 | "type": "select", 17 | "labelClassName": "text-muted", 18 | "name": "a", 19 | "inline": true, 20 | "options": [ 21 | { 22 | "label": "选项1", 23 | "value": 1 24 | }, 25 | { 26 | "label": "选项2", 27 | "value": 2 28 | }, 29 | { 30 | "label": "选项3", 31 | "value": 3 32 | } 33 | ] 34 | }, 35 | { 36 | "label": "选项2", 37 | "type": "select", 38 | "labelClassName": "text-muted", 39 | "name": "b", 40 | "inline": true, 41 | "source": "/amis/api/mock2/options/level2?a=${a}", 42 | "initFetchOn": "data.a" 43 | }, 44 | { 45 | "label": "选项3", 46 | "type": "select", 47 | "labelClassName": "text-muted", 48 | "name": "c", 49 | "inline": true, 50 | "visibleOn": "data.b", 51 | "source": "/amis/api/mock2/options/level3?b=${b}" 52 | } 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # amis-admin-vue 2 | 3 |
4 | 5 | [![deploy](https://github.com/h7ml/amis-admin-vue/actions/workflows/deploy.yml/badge.svg?branch=master)](https://github.com/h7ml/amis-admin-vue/actions/workflows/deploy.yml) 6 | [![license](https://img.shields.io/github/license/h7ml/amis-admin-vue.svg)](https://github.com/h7ml/amis-admin-vue/blob/master/LICENSE#L1) 7 | [![version](https://img.shields.io/npm/v/vue-amis-sdk/latest)](https://github.com/h7ml/vue-amis-sdk) 8 | [![language](https://img.shields.io/github/languages/top/h7ml/amis-admin-vue)](https://github.com/h7ml/amis-admin-vue/search?l=css) 9 | [![last](https://img.shields.io/github/last-commit/h7ml/amis-admin-vue.svg)](https://github.com/h7ml/amis-admin-vue/commits) 10 | [![stars](https://img.shields.io/badge/Hosted-Vercel-brightgreen?style=flat&logo=Vercel)](https://amis.vercel.app/) 11 |
12 | 13 | 基于[amis](https://github.com/baidu/amis) 渲染器,快速搭建自己的管理系统。 14 | 这是基于官方应用模板[amis-admin](https://github.com/aisuda/amis-admin)的vue实现版本。 15 | 支持最新版本的[amis](https://github.com/h7ml/amis-admin-vue/blob/master/package.json#L3) 16 | 17 | ## [项目预览](https://amis-admin-vue.vercel.app/index) 18 | [![preview](https://amis-admin-vue.vercel.app/img/markdown/preview.png)](https://amis-admin-vue.vercel.app/img/markdown/preview.png) 19 | ## [项目在线编辑器](https://amis-admin-vue.vercel.app/#/Editor) 20 | [![edit](https://amis-admin-vue.vercel.app/img/markdown/edit.png)](https://amis-admin-vue.vercel.app/img/markdown/edit.png) 21 | ## Project setup 22 | 23 | ``` 24 | npm install 25 | ``` 26 | 27 | ### Compiles and hot-reloads for development 28 | 29 | ``` 30 | npm run serve 31 | ``` 32 | 33 | ### Compiles and minifies for production 34 | 35 | ``` 36 | npm run build 37 | ``` 38 | 39 | ### Lints and fixes files 40 | 41 | ``` 42 | npm run lint 43 | ``` 44 | 45 | ### Customize configuration 46 | 47 | See [Configuration Reference](https://cli.vuejs.org/config/). 48 | -------------------------------------------------------------------------------- /public/pages/linkpage-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单与表单之间的联动", 4 | "aside": { 5 | "type": "form", 6 | "target": "detailForm", 7 | "className": "wrapper-sm", 8 | "wrapWithPanel": false, 9 | "body": [ 10 | { 11 | "type": "input-text", 12 | "placeholder": "关键字", 13 | "name": "keywords", 14 | "addOn": { 15 | "type": "submit", 16 | "label": "搜索", 17 | "primary": true 18 | } 19 | }, 20 | "请在此输入内容后点击搜索" 21 | ] 22 | }, 23 | "body": { 24 | "name": "detailForm", 25 | "type": "form", 26 | "mode": "horizontal", 27 | "title": "", 28 | "initApi": "/amis/api/mock2/form/initData?keywords=${keywords}", 29 | "actions": [], 30 | "body": [ 31 | "Form 模型除了用来提交数据外,还比较适合用来做详情数据的展示", 32 | { 33 | "type": "divider" 34 | }, 35 | { 36 | "label": "名称", 37 | "type": "static", 38 | "labelClassName": "text-muted", 39 | "name": "name" 40 | }, 41 | { 42 | "label": "作者", 43 | "type": "static", 44 | "labelClassName": "text-muted", 45 | "name": "author" 46 | }, 47 | { 48 | "label": "输入信息", 49 | "type": "static", 50 | "labelClassName": "text-muted", 51 | "name": "info" 52 | }, 53 | { 54 | "label": "请求时间", 55 | "type": "static-datetime", 56 | "labelClassName": "text-muted", 57 | "format": "YYYY-MM-DD HH:mm:ss", 58 | "name": "date" 59 | } 60 | ] 61 | } 62 | } -------------------------------------------------------------------------------- /src/store/modules/amis.js: -------------------------------------------------------------------------------- 1 | const state = () => ({ 2 | config: {}, 3 | enableAMISDebug: false, 4 | theme: 'default', 5 | component: 'AmisView', 6 | editor: { isMobile: false, isPreview: false, theme: 'antd' } 7 | }) 8 | const getters = { 9 | config: state => state.config, 10 | theme: state => state.theme, 11 | component: state => state.component, 12 | enableAMISDebug: state => state.enableAMISDebug, 13 | editor: state => state.editor 14 | } 15 | const mutations = { 16 | setEditor(state, config) { 17 | state.editor = config 18 | }, 19 | changeMobile(state, Mobile) { 20 | state.editor.isMobile = Mobile 21 | }, 22 | changePreview(state, Preview) { 23 | state.editor.isPreview = Preview 24 | }, 25 | changeTheme(state, theme) { 26 | // import (`amis/lib/themes/${theme}.css`) 27 | state.editor.theme = theme 28 | }, 29 | setComponent(state, component) { 30 | state.component = component 31 | }, 32 | setTheme(state, theme) { 33 | state.theme = theme 34 | }, 35 | setProtocol(state, config) { 36 | state.config = config 37 | }, 38 | enableAMISDebug(state, enable) { 39 | state.enableAMISDebug = enable 40 | } 41 | } 42 | const actions = { 43 | setEditor(state, config) { 44 | state.commit('setEditor', config) 45 | }, 46 | changeMobile(state, Mobile) { 47 | state.commit('changeMobile', Mobile) 48 | }, 49 | changePreview(state, Preview) { 50 | state.commit('changePreview', Preview) 51 | }, 52 | changeTheme({ commit }, Theme) { 53 | commit('changeTheme', Theme) 54 | }, 55 | setComponent(state, component) { 56 | state.commit('setComponent', component) 57 | }, 58 | setTheme(state, theme) { 59 | state.commit('setTheme', theme) 60 | }, 61 | enableAMISDebug({ commit }, enable) { 62 | commit('enableAMISDebug', enable) 63 | }, 64 | setProtocol({ commit }, config) { 65 | commit('config', config) 66 | } 67 | } 68 | export default { 69 | state, 70 | getters, 71 | mutations, 72 | actions 73 | } 74 | -------------------------------------------------------------------------------- /public/pages/event-action-logic.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单选线的联动", 4 | "body": { 5 | "type": "form", 6 | "mode": "horizontal", 7 | "title": "", 8 | "actions": [], 9 | "body": [ 10 | "

表单选项内也能联动,通过配置 visibleOn、hiddenOn或者disabledOn

", 11 | { 12 | "type": "divider" 13 | }, 14 | { 15 | "label": "选项1", 16 | "type": "list-select", 17 | "multiple": false, 18 | "labelClassName": "text-muted", 19 | "name": "a", 20 | "inline": true, 21 | "options": [ 22 | { 23 | "label": "选项1", 24 | "value": 1 25 | }, 26 | { 27 | "label": "选项2", 28 | "value": 2 29 | }, 30 | { 31 | "label": "选项3", 32 | "value": 3 33 | } 34 | ] 35 | }, 36 | { 37 | "label": "选项2", 38 | "type": "radios", 39 | "labelClassName": "text-muted", 40 | "name": "b", 41 | "inline": true, 42 | "options": [ 43 | { 44 | "label": "选项1", 45 | "value": 1, 46 | "disabledOn": "data.a == 1" 47 | }, 48 | { 49 | "label": "选项2", 50 | "value": 2, 51 | "hiddenOn": "data.a == 2" 52 | }, 53 | { 54 | "label": "选项3", 55 | "value": 3, 56 | "visibleOn": "data.a == 3" 57 | } 58 | ] 59 | } 60 | ] 61 | } 62 | } -------------------------------------------------------------------------------- /public/pages/sub-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "SubForm 示例", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 7 | "title": "Form elements", 8 | "mode": "horizontal", 9 | "body": [ 10 | { 11 | "type": "input-sub-form", 12 | "label": "子表单单条", 13 | "name": "subForm1", 14 | "btnLabel": "点击设置${a}", 15 | "form": { 16 | "title": "子表单", 17 | "body": [ 18 | { 19 | "name": "a", 20 | "type": "input-text", 21 | "label": "Foo" 22 | }, 23 | { 24 | "name": "b", 25 | "type": "switch", 26 | "label": "Boo" 27 | } 28 | ] 29 | } 30 | }, 31 | { 32 | "type": "input-sub-form", 33 | "label": "子表单多条", 34 | "name": "subForm2", 35 | "labelField": "a", 36 | "btnLabel": "点击设置", 37 | "multiple": true, 38 | "form": { 39 | "title": "子表单", 40 | "body": [ 41 | { 42 | "name": "a", 43 | "type": "input-text", 44 | "label": "Foo" 45 | }, 46 | { 47 | "name": "b", 48 | "type": "switch", 49 | "label": "Boo" 50 | } 51 | ] 52 | } 53 | } 54 | ] 55 | } 56 | ] 57 | } -------------------------------------------------------------------------------- /src/components/Editor/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 78 | 79 | 94 | -------------------------------------------------------------------------------- /public/pages/custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "自定义组件示例", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "mode": "horizontal", 7 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 8 | "debug": true, 9 | "actions": [ 10 | { 11 | "type": "submit", 12 | "label": "提交", 13 | "primary": true 14 | } 15 | ], 16 | "body": [ 17 | { 18 | "label": "姓名", 19 | "type": "text", 20 | "name": "name" 21 | }, 22 | { 23 | "type": "divider" 24 | }, 25 | { 26 | "label": "使用 custom 组件", 27 | "name": "name", 28 | "type": "custom" 29 | }, 30 | { 31 | "type": "divider" 32 | }, 33 | { 34 | "name": "a", 35 | "asFormItem": true 36 | }, 37 | { 38 | "type": "divider" 39 | }, 40 | { 41 | "name": "b", 42 | "type": "my-custom", 43 | "label": "自定义FormItem" 44 | }, 45 | { 46 | "type": "divider" 47 | }, 48 | { 49 | "type": "control", 50 | "body": { 51 | "type": "my-renderer", 52 | "source": "${x}" 53 | } 54 | }, 55 | { 56 | "type": "divider" 57 | }, 58 | { 59 | "label": "", 60 | "asFormItem": true 61 | }, 62 | { 63 | "name": "c", 64 | "label": "", 65 | "asFormItem": true 66 | } 67 | ] 68 | }, 69 | { 70 | "type": "my-renderer", 71 | "tip": "放表单外的情况" 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /src/views/amis/Editor.vue: -------------------------------------------------------------------------------- 1 | 2 | 54 | 55 | 76 | 83 | -------------------------------------------------------------------------------- /public/pages/crud-item-action.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "点击左侧 crud 会触发右侧 crud 刷新", 3 | "subTitle": "需要配置 syncLocation: false 避免左侧也刷新", 4 | "body": { 5 | "type": "grid", 6 | "columns": [ 7 | { 8 | "body": [ 9 | { 10 | "type": "crud", 11 | "api": "/amis/api/sample", 12 | "headerToolbar": [], 13 | "perPage": 10, 14 | "syncLocation": false, 15 | "itemAction": { 16 | "actionType": "reload", 17 | "target": "detailCRUD?id=${id}" 18 | }, 19 | "columns": [ 20 | { 21 | "name": "id", 22 | "label": "ID", 23 | "width": 20, 24 | "type": "text" 25 | }, 26 | { 27 | "name": "platform", 28 | "label": "Platform(s)", 29 | "type": "text" 30 | } 31 | ] 32 | } 33 | ] 34 | }, 35 | { 36 | "body": [ 37 | { 38 | "type": "crud", 39 | "name": "detailCRUD", 40 | "headerToolbar": [], 41 | "syncLocation": false, 42 | "api": "/amis/api/sample?perPage=10&id=${id}&waitSeconds=1", 43 | "columns": [ 44 | { 45 | "name": "engine", 46 | "label": "Rendering engine", 47 | "type": "text" 48 | }, 49 | { 50 | "name": "version", 51 | "label": "Engine version", 52 | "type": "text" 53 | } 54 | ] 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | } -------------------------------------------------------------------------------- /public/pages/services-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "动态加载表单中的部分", 4 | "body": [ 5 | "同样通过 serviceschemaApi 来加载部分内容,当然也可以全部由它来加载", 6 | { 7 | "type": "form", 8 | "panelClassName": "Panel--info m-t", 9 | "target": "service1", 10 | "mode": "horizontal", 11 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=1", 12 | "body": [ 13 | { 14 | "type": "fieldset", 15 | "title": "基本信息", 16 | "body": [ 17 | { 18 | "type": "input-text", 19 | "label": "字段一", 20 | "name": "filed1" 21 | }, 22 | { 23 | "type": "input-text", 24 | "label": "字段二", 25 | "name": "filed2" 26 | } 27 | ] 28 | }, 29 | { 30 | "title": "其他信息", 31 | "type": "fieldset", 32 | "body": [ 33 | { 34 | "name": "tpl", 35 | "type": "select", 36 | "label": "模板", 37 | "inline": true, 38 | "required": true, 39 | "value": "tpl1", 40 | "options": [ 41 | { 42 | "label": "模板1", 43 | "value": "tpl1" 44 | }, 45 | { 46 | "label": "模板2", 47 | "value": "tpl2" 48 | }, 49 | { 50 | "label": "模板3", 51 | "value": "tpl3" 52 | } 53 | ] 54 | }, 55 | { 56 | "type": "service", 57 | "className": "m-t", 58 | "initFetchSchemaOn": "data.tpl", 59 | "schemaApi": "/amis/api/mock2/service/form?tpl=$tpl" 60 | } 61 | ] 62 | } 63 | ] 64 | } 65 | ] 66 | } -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ['plugin:vue/recommended', 'eslint:recommended', '@vue/prettier'], 7 | parser: 'vue-eslint-parser', 8 | parserOptions: { 9 | sourceType: 'module', 10 | ecmaVersion: 10, 11 | ecmaFeatures: { 12 | jsx: true 13 | } 14 | }, 15 | rules: { 16 | // 'no-undef': 2, 17 | 'no-console': 'off', 18 | 'no-debugger': 'off', 19 | 'vue/no-v-html': 'off', 20 | 'vue/html-self-closing': [ 21 | 'error', 22 | { 23 | html: { 24 | void: 'any', 25 | normal: 'any', 26 | component: 'always' 27 | }, 28 | svg: 'always', 29 | math: 'always' 30 | } 31 | ], 32 | // Vue.js风格指南(https://cn.vuejs.org/v2/style-guide/) 33 | // Vue组件排序 34 | 'vue/order-in-components': [ 35 | 'warn', 36 | { 37 | order: [ 38 | 'el', 39 | 'name', 40 | 'key', 41 | 'parent', 42 | 'functional', 43 | ['delimiters', 'comments'], 44 | ['components', 'directives', 'filters'], 45 | 'extends', 46 | 'mixins', 47 | ['provide', 'inject'], 48 | 'ROUTER_GUARDS', 49 | 'layout', 50 | 'middleware', 51 | 'validate', 52 | 'scrollToTop', 53 | 'transition', 54 | 'loading', 55 | 'inheritAttrs', 56 | 'model', 57 | ['props', 'propsData'], 58 | 'emits', 59 | 'setup', 60 | 'fetch', 61 | 'asyncData', 62 | 'data', 63 | 'head', 64 | 'computed', 65 | 'watch', 66 | 'watchQuery', 67 | 'LIFECYCLE_HOOKS', 68 | 'methods', 69 | ['template', 'render'], 70 | 'renderError' 71 | ] 72 | } 73 | ], 74 | // Vue属性排序 75 | 'vue/attributes-order': [ 76 | 'warn', 77 | { 78 | order: [ 79 | 'DEFINITION', 80 | 'LIST_RENDERING', 81 | 'CONDITIONALS', 82 | 'RENDER_MODIFIERS', 83 | 'GLOBAL', 84 | 'UNIQUE', 85 | 'TWO_WAY_BINDING', 86 | 'OTHER_DIRECTIVES', 87 | 'OTHER_ATTR', 88 | 'EVENTS', 89 | 'CONTENT' 90 | ], 91 | alphabetical: true 92 | } 93 | ] 94 | }, 95 | overrides: [ 96 | { 97 | files: [ 98 | '**/__tests__/*.{j,t}s?(x)', 99 | '**/tests/unit/**/*.spec.{j,t}s?(x)' 100 | ], 101 | env: { 102 | jest: true 103 | } 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /public/pages/crud-columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "增删改查列类型汇总", 3 | "body": { 4 | "type": "crud", 5 | "api": "/amis/api/mock2/crud/list", 6 | "columns": [ 7 | { 8 | "name": "id", 9 | "label": "ID", 10 | "type": "text" 11 | }, 12 | { 13 | "name": "audio", 14 | "label": "音频", 15 | "type": "audio" 16 | }, 17 | { 18 | "name": "carousel", 19 | "label": "轮播图", 20 | "type": "carousel", 21 | "width": "300" 22 | }, 23 | { 24 | "name": "text", 25 | "label": "文本", 26 | "type": "text" 27 | }, 28 | { 29 | "type": "image", 30 | "label": "图片", 31 | "name": "image", 32 | "enlargeAble": true, 33 | "title": "233", 34 | "thumbMode": "cover" 35 | }, 36 | { 37 | "name": "date", 38 | "type": "date", 39 | "label": "日期" 40 | }, 41 | { 42 | "name": "progress", 43 | "label": "进度", 44 | "type": "progress" 45 | }, 46 | { 47 | "name": "boolean", 48 | "label": "状态", 49 | "type": "status" 50 | }, 51 | { 52 | "name": "boolean", 53 | "label": "开关", 54 | "type": "switch" 55 | }, 56 | { 57 | "name": "type", 58 | "label": "映射", 59 | "type": "mapping", 60 | "map": { 61 | "1": "漂亮", 62 | "2": "开心", 63 | "3": "惊吓", 64 | "4": "紧张", 65 | "*": "其他:${type}" 66 | } 67 | }, 68 | { 69 | "name": "list", 70 | "type": "list", 71 | "label": "List", 72 | "placeholder": "-", 73 | "size": "sm", 74 | "listItem": { 75 | "title": "${title}", 76 | "subTitle": "${description}" 77 | } 78 | }, 79 | { 80 | "name": "json", 81 | "type": "json", 82 | "label": "Json" 83 | } 84 | ] 85 | } 86 | } -------------------------------------------------------------------------------- /public/pages/hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "其他类型演示", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 7 | "title": "Hint demo", 8 | "mode": "horizontal", 9 | "horizontal": { 10 | "leftFixed": true 11 | }, 12 | "body": [ 13 | { 14 | "type": "input-group", 15 | "size": "md", 16 | "label": "Icon 组合", 17 | "body": [ 18 | { 19 | "type": "icon", 20 | "addOnclassName": "no-bg", 21 | "className": "text-sm", 22 | "icon": "search", 23 | "vendor": "iconfont" 24 | }, 25 | { 26 | "type": "input-text", 27 | "placeholder": "搜索作业ID/名称", 28 | "inputClassName": "b-l-none p-l-none", 29 | "name": "jobName" 30 | } 31 | ] 32 | }, 33 | { 34 | "name": "a", 35 | "type": "input-text", 36 | "label": "ID", 37 | "value": "", 38 | "size": "xs", 39 | "hint": "比如输入 a-xxxx-xxx" 40 | }, 41 | { 42 | "name": "b", 43 | "type": "input-text", 44 | "label": "ID", 45 | "value": "", 46 | "size": "sm", 47 | "hint": "比如输入 a-xxxx-xxx" 48 | }, 49 | { 50 | "name": "c", 51 | "type": "input-text", 52 | "label": "ID", 53 | "value": "", 54 | "size": "md", 55 | "hint": "比如输入 a-xxxx-xxx" 56 | }, 57 | { 58 | "name": "d", 59 | "type": "input-text", 60 | "label": "ID", 61 | "value": "", 62 | "size": "lg", 63 | "hint": "比如输入 a-xxxx-xxx" 64 | }, 65 | { 66 | "name": "tag", 67 | "type": "input-tag", 68 | "label": "Tag", 69 | "size": "md", 70 | "clearable": true, 71 | "placeholder": "多个标签以逗号分隔", 72 | "options": [ 73 | "周小度", 74 | "杜小度" 75 | ] 76 | } 77 | ] 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /public/pages/crud-keyboards.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Table 全键盘操作示例", 3 | "remark": "bla bla bla", 4 | "body": [ 5 | { 6 | "type": "plain", 7 | "className": "text-danger", 8 | "text": "请通过上下左右键切换单元格,按 `Space` 键进入编辑模式,按 `Enter` 提交编辑,并最后点左上角的全部保存完成操作。" 9 | }, 10 | { 11 | "type": "crud", 12 | "className": "m-t", 13 | "api": "/amis/api/sample", 14 | "quickSaveApi": "/amis/api/sample/bulkUpdate", 15 | "quickSaveItemApi": "/amis/api/sample/$id", 16 | "columns": [ 17 | { 18 | "name": "id", 19 | "label": "ID", 20 | "width": 20, 21 | "sortable": true, 22 | "type": "text", 23 | "toggled": true 24 | }, 25 | { 26 | "name": "engine", 27 | "label": "Rendering engine", 28 | "sortable": true, 29 | "quickEdit": { 30 | "type": "input-text", 31 | "required": true, 32 | "mode": "inline" 33 | }, 34 | "type": "text", 35 | "toggled": true 36 | }, 37 | { 38 | "name": "browser", 39 | "label": "Browser", 40 | "sortable": true, 41 | "quickEdit": { 42 | "type": "input-text", 43 | "required": true 44 | }, 45 | "type": "text", 46 | "toggled": true 47 | }, 48 | { 49 | "name": "platform", 50 | "label": "Platform(s)", 51 | "sortable": true, 52 | "quickEdit": true, 53 | "type": "text", 54 | "toggled": true 55 | }, 56 | { 57 | "name": "version", 58 | "label": "Engine version", 59 | "quickEdit": true, 60 | "type": "text", 61 | "toggled": true 62 | }, 63 | { 64 | "name": "grade", 65 | "label": "CSS grade", 66 | "quickEdit": { 67 | "type": "select", 68 | "options": [ 69 | "A", 70 | "B", 71 | "C", 72 | "D", 73 | "X" 74 | ] 75 | }, 76 | "type": "text", 77 | "toggled": true 78 | } 79 | ] 80 | } 81 | ] 82 | } -------------------------------------------------------------------------------- /public/pages/wizard.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "表单向导", 4 | "subTitle": "可以通过表单向导,将一个超长的表单页面拆分成多个步骤,一步一步指引用户完成。", 5 | "body": [ 6 | { 7 | "type": "wizard", 8 | "actionFinishLabel": "确认", 9 | "api": "/api/saveWizard", 10 | "steps": [ 11 | { 12 | "title": "填写活动信息", 13 | "controls": [ 14 | { 15 | "type": "text", 16 | "name": "title", 17 | "label": "活动标题", 18 | "required": true, 19 | "size": "md" 20 | }, 21 | 22 | { 23 | "type": "date", 24 | "name": "date", 25 | "label": "举办时间", 26 | "size": "md" 27 | }, 28 | 29 | { 30 | "type": "number", 31 | "name": "num", 32 | "label": "参与人数", 33 | "value": 10, 34 | "size": "md" 35 | } 36 | ] 37 | }, 38 | 39 | { 40 | "title": "填写赞助商信息", 41 | "controls": [ 42 | { 43 | "type": "text", 44 | "name": "company", 45 | "label": "公司名称", 46 | "required": true, 47 | "size": "md" 48 | }, 49 | 50 | { 51 | "type": "text", 52 | "name": "money", 53 | "label": "赞助金额", 54 | "addOn": { 55 | "type": "text", 56 | "label": "¥" 57 | }, 58 | "size": "md" 59 | } 60 | ] 61 | }, 62 | 63 | { 64 | "title": "确认", 65 | "mode": "horizontal", 66 | "horizontal": { 67 | "leftFixed": "sm" 68 | }, 69 | "controls": [ 70 | { 71 | "type": "static", 72 | "name": "company", 73 | "label": "活动标题", 74 | "labelClassName": "text-muted" 75 | }, 76 | { 77 | "type": "static-date", 78 | "name": "date", 79 | "label": "举办时间", 80 | "labelClassName": "text-muted" 81 | }, 82 | { 83 | "type": "static", 84 | "name": "num", 85 | "label": "参与人数", 86 | "labelClassName": "text-muted" 87 | }, 88 | { 89 | "type": "static", 90 | "name": "company", 91 | "label": "公司名称", 92 | "labelClassName": "text-muted" 93 | }, 94 | { 95 | "type": "static", 96 | "name": "money", 97 | "label": "赞助金额", 98 | "labelClassName": "text-muted" 99 | } 100 | ] 101 | } 102 | ] 103 | } 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /public/pages/event-tabs.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "标签页组件事件", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "name": "trigger1", 12 | "id": "trigger1", 13 | "type": "action", 14 | "label": "选项卡1", 15 | "level": "primary", 16 | "className": "mr-3 mb-3", 17 | "onEvent": { 18 | "click": { 19 | "actions": [ 20 | { 21 | "actionType": "changeActiveKey", 22 | "componentId": "tabs-change-receiver", 23 | "activeKey": 0 24 | } 25 | ] 26 | } 27 | } 28 | }, 29 | { 30 | "name": "trigger2", 31 | "id": "trigger2", 32 | "type": "action", 33 | "label": "选项卡2", 34 | "level": "primary", 35 | "className": "mr-3 mb-3", 36 | "onEvent": { 37 | "click": { 38 | "actions": [ 39 | { 40 | "actionType": "changeActiveKey", 41 | "componentId": "tabs-change-receiver", 42 | "activeKey": 1 43 | } 44 | ] 45 | } 46 | } 47 | }, 48 | { 49 | "name": "trigger3", 50 | "id": "trigger3", 51 | "type": "action", 52 | "label": "选项卡3", 53 | "level": "primary", 54 | "className": "mr-3 mb-3", 55 | "onEvent": { 56 | "click": { 57 | "actions": [ 58 | { 59 | "actionType": "changeActiveKey", 60 | "componentId": "tabs-change-receiver", 61 | "activeKey": 2 62 | } 63 | ] 64 | } 65 | } 66 | }, 67 | { 68 | "name": "tabs-change-receiver", 69 | "id": "tabs-change-receiver", 70 | "type": "tabs", 71 | "mode": "line", 72 | "tabs": [ 73 | { 74 | "title": "选项卡1", 75 | "body": "选项卡内容1" 76 | }, 77 | { 78 | "title": "选项卡2", 79 | "body": "选项卡内容2" 80 | }, 81 | { 82 | "title": "选项卡3", 83 | "body": "选项卡内容3" 84 | } 85 | ], 86 | "onEvent": { 87 | "change": { 88 | "actions": [ 89 | { 90 | "actionType": "toast", 91 | "msgType": "info", 92 | "msg": "派发change事件" 93 | } 94 | ] 95 | } 96 | } 97 | } 98 | ] 99 | } -------------------------------------------------------------------------------- /public/pages/event-input-excel.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "excel事件", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "tpl", 12 | "tpl": "InputExcel", 13 | "inline": false, 14 | "wrapperComponent": "h2" 15 | }, 16 | { 17 | "type": "form", 18 | "debug": true, 19 | "api": "/amis/api/mock2/form/saveForm", 20 | "body": [ 21 | { 22 | "type": "group", 23 | "body": [ 24 | { 25 | "name": "trigger1", 26 | "id": "trigger1", 27 | "type": "action", 28 | "label": "clear触发器", 29 | "level": "primary", 30 | "onEvent": { 31 | "click": { 32 | "actions": [ 33 | { 34 | "actionType": "clear", 35 | "componentId": "clear-input-excel", 36 | "description": "点击清除数据" 37 | } 38 | ] 39 | } 40 | } 41 | }, 42 | { 43 | "type": "input-excel", 44 | "id": "clear-input-excel", 45 | "name": "file", 46 | "multiple": true, 47 | "onEvent": { 48 | "change": { 49 | "actions": [ 50 | { 51 | "actionType": "dialog", 52 | "args": { 53 | "val": "${event.data.value}" 54 | }, 55 | "dialog": { 56 | "title": "派发change事件", 57 | "data": { 58 | "val": "${val}" 59 | }, 60 | "body": [ 61 | { 62 | "type": "tpl", 63 | "tpl": "${val|json}" 64 | } 65 | ] 66 | } 67 | } 68 | ] 69 | } 70 | } 71 | } 72 | ] 73 | } 74 | ] 75 | } 76 | ] 77 | } -------------------------------------------------------------------------------- /src/views/Login/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /public/pages/carousel-carousel.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "轮播图", 4 | "data": { 5 | "carousel0": [ 6 | "/amis/static/photo/bd3eb13533fa828b13b24500f31f4134960a5a44_81bbc2d.jpg", 7 | "/amis/static/photo/da6376bf988c_3360340.jpg", 8 | "/amis/static/photo/3893101144_bff2dc9.jpg" 9 | ], 10 | "carousel1": [ 11 | { 12 | "html": "
carousel data in form
" 13 | }, 14 | { 15 | "image": "/amis/static/photo/bd3eb13533fa828b13b24500f31f4134960a5a44_81bbc2d.jpg" 16 | }, 17 | { 18 | "image": "/amis/static/photo/3893101144_bff2dc9.jpg" 19 | } 20 | ] 21 | }, 22 | "body": [ 23 | { 24 | "type": "grid", 25 | "columns": [ 26 | { 27 | "type": "panel", 28 | "title": "直接页面配置", 29 | "body": { 30 | "type": "carousel", 31 | "controlsTheme": "light", 32 | "height": "300", 33 | "options": [ 34 | { 35 | "image": "/amis/static/photo/da6376bf988c_3360340.jpg" 36 | }, 37 | { 38 | "html": "
carousel data
" 39 | }, 40 | { 41 | "image": "/amis/static/photo/3893101144_bff2dc9.jpg" 42 | } 43 | ] 44 | } 45 | }, 46 | { 47 | "type": "panel", 48 | "title": "使用itemSchema配置", 49 | "body": { 50 | "type": "carousel", 51 | "name": "carousel0", 52 | "controlsTheme": "dark", 53 | "height": "300", 54 | "itemSchema": { 55 | "type": "tpl", 56 | "tpl": "
); background-position: center center; background-size: cover;\">
" 57 | } 58 | } 59 | } 60 | ] 61 | }, 62 | { 63 | "type": "grid", 64 | "columns": [ 65 | { 66 | "type": "form", 67 | "title": "表单内展示", 68 | "sm": 6, 69 | "body": [ 70 | { 71 | "type": "carousel", 72 | "controlsTheme": "dark", 73 | "name": "carousel1", 74 | "label": "carousel", 75 | "animation": "slide", 76 | "height": "300" 77 | } 78 | ] 79 | } 80 | ] 81 | } 82 | ] 83 | } -------------------------------------------------------------------------------- /public/pages/event-input-rating.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "评分组件事件", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "tpl", 12 | "tpl": "InputRating组件", 13 | "inline": false, 14 | "wrapperComponent": "h2" 15 | }, 16 | { 17 | "type": "form", 18 | "debug": true, 19 | "body": [ 20 | { 21 | "name": "input-rating-clear", 22 | "type": "action", 23 | "label": "clear触发器", 24 | "level": "primary", 25 | "onEvent": { 26 | "click": { 27 | "actions": [ 28 | { 29 | "actionType": "clear", 30 | "componentId": "clear-input-rating-clear-receiver", 31 | "description": "点击清空内容" 32 | } 33 | ] 34 | } 35 | } 36 | }, 37 | { 38 | "name": "rate-clear", 39 | "id": "clear-input-rating-clear-receiver", 40 | "type": "input-rating", 41 | "value": 3, 42 | "onEvent": { 43 | "change": { 44 | "actions": [ 45 | { 46 | "actionType": "toast", 47 | "msgType": "info", 48 | "msg": "派发change事件" 49 | } 50 | ] 51 | } 52 | } 53 | }, 54 | { 55 | "name": "input-rating-reset", 56 | "type": "action", 57 | "label": "reset触发器", 58 | "level": "primary", 59 | "onEvent": { 60 | "click": { 61 | "actions": [ 62 | { 63 | "actionType": "clear", 64 | "componentId": "clear-input-rating-reset-receiver", 65 | "description": "点击清空内容" 66 | } 67 | ] 68 | } 69 | } 70 | }, 71 | { 72 | "name": "rate-reset", 73 | "id": "clear-input-rating-reset-receiver", 74 | "type": "input-rating", 75 | "value": 3, 76 | "resetValue": 3, 77 | "onEvent": { 78 | "change": { 79 | "actions": [ 80 | { 81 | "actionType": "toast", 82 | "msgType": "info", 83 | "msg": "派发change事件" 84 | } 85 | ] 86 | } 87 | } 88 | } 89 | ] 90 | } 91 | ] 92 | } -------------------------------------------------------------------------------- /public/pages/reaction.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "显隐切换示例", 3 | "body": [ 4 | { 5 | "name": "hiddenOn", 6 | "type": "form", 7 | "mode": "horizontal", 8 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 9 | "title": "Hide On 和 disabledOn 示例", 10 | "body": [ 11 | { 12 | "type": "radios", 13 | "name": "type", 14 | "label": "类型选择", 15 | "inline": true, 16 | "value": "1", 17 | "options": [ 18 | { 19 | "label": "类型 1", 20 | "value": "1" 21 | }, 22 | { 23 | "label": "类型 2", 24 | "value": "2" 25 | }, 26 | { 27 | "label": "类型 3", 28 | "value": "3" 29 | } 30 | ], 31 | "description": "请切换类型来看效果" 32 | }, 33 | { 34 | "type": "input-text", 35 | "label": "所有可见", 36 | "name": "text1" 37 | }, 38 | { 39 | "type": "input-text", 40 | "label": "类型2 可见", 41 | "hiddenOn": "data.type != 2", 42 | "name": "text2" 43 | }, 44 | { 45 | "type": "input-text", 46 | "label": "类型3 不可点", 47 | "disabledOn": "data.type == 3", 48 | "name": "text3" 49 | }, 50 | { 51 | "type": "input-text", 52 | "required": true, 53 | "label": "必填字段", 54 | "name": "test4" 55 | }, 56 | { 57 | "type": "button-toolbar", 58 | "buttons": [ 59 | { 60 | "type": "submit", 61 | "disabledOn": "data.type == 1", 62 | "label": "类型1不可点" 63 | }, 64 | { 65 | "type": "reset", 66 | "label": "类型3出现且不可点", 67 | "visibleOn": "data.type == 3", 68 | "disabledOn": "data.type == 3" 69 | }, 70 | { 71 | "type": "button", 72 | "label": "Baidu", 73 | "actionType": "url", 74 | "url": "http://www.baidu.com?a=1&b=$test4" 75 | }, 76 | { 77 | "type": "button", 78 | "actionType": "ajax", 79 | "label": "No Submit", 80 | "api": "/amis/api/mock2/saveForm?waitSeconds=5" 81 | }, 82 | { 83 | "type": "submit", 84 | "actionType": "ajax", 85 | "label": "Submit", 86 | "api": "/amis/api/mock2/saveForm?waitSeconds=5" 87 | } 88 | ] 89 | } 90 | ] 91 | } 92 | ] 93 | } -------------------------------------------------------------------------------- /public/pages/crud-merge-cell.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "支持自动合并单元格,从左到右,可配置从左侧起多少列内启动自动合并单元格,当前配置 3", 3 | "body": { 4 | "type": "table", 5 | "data": { 6 | "items": [ 7 | { 8 | "engine": "Trident", 9 | "browser": "Internet Explorer 4.2", 10 | "platform": "Win 95+", 11 | "version": "4", 12 | "grade": "A" 13 | }, 14 | { 15 | "engine": "Trident", 16 | "browser": "Internet Explorer 4.2", 17 | "platform": "Win 95+", 18 | "version": "4", 19 | "grade": "B" 20 | }, 21 | { 22 | "engine": "Trident", 23 | "browser": "AOL browser (AOL desktop)", 24 | "platform": "Win 95+", 25 | "version": "4", 26 | "grade": "C" 27 | }, 28 | { 29 | "engine": "Trident", 30 | "browser": "AOL browser (AOL desktop)", 31 | "platform": "Win 98", 32 | "version": "3", 33 | "grade": "A" 34 | }, 35 | { 36 | "engine": "Trident", 37 | "browser": "AOL browser (AOL desktop)", 38 | "platform": "Win 98", 39 | "version": "4", 40 | "grade": "A" 41 | }, 42 | { 43 | "engine": "Gecko", 44 | "browser": "Firefox 1.0", 45 | "platform": "Win 98+ / OSX.2+", 46 | "version": "4", 47 | "grade": "A" 48 | }, 49 | { 50 | "engine": "Gecko", 51 | "browser": "Firefox 1.0", 52 | "platform": "Win 98+ / OSX.2+", 53 | "version": "5", 54 | "grade": "A" 55 | }, 56 | { 57 | "engine": "Gecko", 58 | "browser": "Firefox 2.0", 59 | "platform": "Win 98+ / OSX.2+", 60 | "version": "5", 61 | "grade": "B" 62 | }, 63 | { 64 | "engine": "Gecko", 65 | "browser": "Firefox 2.0", 66 | "platform": "Win 98+ / OSX.2+", 67 | "version": "5", 68 | "grade": "C" 69 | }, 70 | { 71 | "engine": "Gecko", 72 | "browser": "Firefox 2.0", 73 | "platform": "Win 98+ / OSX.2+", 74 | "version": "5", 75 | "grade": "D" 76 | } 77 | ] 78 | }, 79 | "combineNum": 3, 80 | "columns": [ 81 | { 82 | "name": "engine", 83 | "label": "Rendering engine" 84 | }, 85 | { 86 | "name": "browser", 87 | "label": "Browser" 88 | }, 89 | { 90 | "name": "platform", 91 | "label": "Platform(s)" 92 | }, 93 | { 94 | "name": "version", 95 | "label": "Engine version" 96 | }, 97 | { 98 | "name": "grade", 99 | "label": "CSS grade" 100 | } 101 | ] 102 | } 103 | } -------------------------------------------------------------------------------- /public/pages/crud-header-group.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "支持表头分组,通过在 cloumn 上设置 groupName 实现。", 3 | "body": { 4 | "type": "table", 5 | "data": { 6 | "items": [ 7 | { 8 | "engine": "Trident", 9 | "browser": "Internet Explorer 4.2", 10 | "platform": "Win 95+", 11 | "version": "4", 12 | "grade": "A" 13 | }, 14 | { 15 | "engine": "Trident", 16 | "browser": "Internet Explorer 4.2", 17 | "platform": "Win 95+", 18 | "version": "4", 19 | "grade": "B" 20 | }, 21 | { 22 | "engine": "Trident", 23 | "browser": "AOL browser (AOL desktop)", 24 | "platform": "Win 95+", 25 | "version": "4", 26 | "grade": "C" 27 | }, 28 | { 29 | "engine": "Trident", 30 | "browser": "AOL browser (AOL desktop)", 31 | "platform": "Win 98", 32 | "version": "3", 33 | "grade": "A" 34 | }, 35 | { 36 | "engine": "Trident", 37 | "browser": "AOL browser (AOL desktop)", 38 | "platform": "Win 98", 39 | "version": "4", 40 | "grade": "A" 41 | }, 42 | { 43 | "engine": "Gecko", 44 | "browser": "Firefox 1.0", 45 | "platform": "Win 98+ / OSX.2+", 46 | "version": "4", 47 | "grade": "A" 48 | }, 49 | { 50 | "engine": "Gecko", 51 | "browser": "Firefox 1.0", 52 | "platform": "Win 98+ / OSX.2+", 53 | "version": "5", 54 | "grade": "A" 55 | }, 56 | { 57 | "engine": "Gecko", 58 | "browser": "Firefox 2.0", 59 | "platform": "Win 98+ / OSX.2+", 60 | "version": "5", 61 | "grade": "B" 62 | }, 63 | { 64 | "engine": "Gecko", 65 | "browser": "Firefox 2.0", 66 | "platform": "Win 98+ / OSX.2+", 67 | "version": "5", 68 | "grade": "C" 69 | }, 70 | { 71 | "engine": "Gecko", 72 | "browser": "Firefox 2.0", 73 | "platform": "Win 98+ / OSX.2+", 74 | "version": "5", 75 | "grade": "D" 76 | } 77 | ] 78 | }, 79 | "columns": [ 80 | { 81 | "name": "engine", 82 | "label": "Rendering engine", 83 | "groupName": "A" 84 | }, 85 | { 86 | "name": "browser", 87 | "label": "Browser", 88 | "groupName": "A" 89 | }, 90 | { 91 | "name": "platform", 92 | "label": "Platform(s)", 93 | "groupName": "B" 94 | }, 95 | { 96 | "name": "version", 97 | "label": "Engine version", 98 | "groupName": "B" 99 | }, 100 | { 101 | "name": "grade", 102 | "label": "CSS grade" 103 | } 104 | ] 105 | } 106 | } -------------------------------------------------------------------------------- /public/pages/validation.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "表单验证示例", 3 | "toolbar": "文档", 4 | "body": [ 5 | { 6 | "type": "form", 7 | "autoFocus": false, 8 | "messages": { 9 | "validateFailed": "请仔细检查表单规则,部分表单项没通过验证" 10 | }, 11 | "title": "表单", 12 | "actions": [ 13 | { 14 | "type": "submit", 15 | "label": "提交" 16 | } 17 | ], 18 | "api": "/amis/api/mock2/form/saveFormFailed?waitSeconds=2", 19 | "mode": "horizontal", 20 | "body": [ 21 | { 22 | "type": "input-text", 23 | "name": "test", 24 | "label": "必填", 25 | "required": true 26 | }, 27 | { 28 | "type": "divider" 29 | }, 30 | { 31 | "name": "test1", 32 | "type": "input-email", 33 | "label": "Email" 34 | }, 35 | { 36 | "type": "divider" 37 | }, 38 | { 39 | "name": "url", 40 | "type": "input-url", 41 | "label": "URL" 42 | }, 43 | { 44 | "type": "divider" 45 | }, 46 | { 47 | "name": "num", 48 | "type": "input-text", 49 | "label": "数字", 50 | "validations": "isNumeric" 51 | }, 52 | { 53 | "type": "divider" 54 | }, 55 | { 56 | "name": "alpha", 57 | "type": "input-text", 58 | "label": "字母或数字", 59 | "validations": "isAlphanumeric" 60 | }, 61 | { 62 | "type": "divider" 63 | }, 64 | { 65 | "name": "int", 66 | "type": "input-text", 67 | "label": "整形", 68 | "validations": "isInt" 69 | }, 70 | { 71 | "type": "divider" 72 | }, 73 | { 74 | "name": "minLength", 75 | "type": "input-text", 76 | "label": "长度限制", 77 | "validations": "minLength:2,maxLength:10" 78 | }, 79 | { 80 | "type": "divider" 81 | }, 82 | { 83 | "name": "min", 84 | "type": "input-text", 85 | "label": "数值限制", 86 | "validations": "maximum:10,minimum:2" 87 | }, 88 | { 89 | "type": "divider" 90 | }, 91 | { 92 | "name": "reg", 93 | "type": "input-text", 94 | "label": "正则", 95 | "validations": "matchRegexp:/^abc/", 96 | "validationErrors": { 97 | "matchRegexp": "请输入abc开头的好么?" 98 | } 99 | }, 100 | { 101 | "type": "divider" 102 | }, 103 | { 104 | "name": "test2", 105 | "type": "input-text", 106 | "label": "服务端验证" 107 | } 108 | ] 109 | } 110 | ] 111 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amis-admin-vue", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "eslint --ext .js --fix&&vue-cli-service lint", 9 | "proxy": "node api/proxy.js", 10 | "prepare": "husky install", 11 | "lint:style": "stylelint **/*.{vue,scss} --fix", 12 | "commit": "git-cz" 13 | }, 14 | "author": "h7ml ", 15 | "keywords": [ 16 | "vue", 17 | "amis", 18 | "amis-admin-vue", 19 | "renderer", 20 | "json", 21 | "schema" 22 | ], 23 | "license": "Apache-2.0", 24 | "licenses": [ 25 | { 26 | "type": "Apache-2.0", 27 | "url": "http://www.apache.org/licenses/LICENSE-2.0" 28 | } 29 | ], 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/h7ml/amis-admin-vue.git" 33 | }, 34 | "dependencies": { 35 | "@fortawesome/fontawesome-free": "^6.1.1", 36 | "axios": "^0.27.2", 37 | "bootstrap": "^5.1.3", 38 | "copy-to-clipboard": "3.3.1", 39 | "core-js": "^3.22.4", 40 | "font-awesome": "^4.7.0", 41 | "qs": "6.10.3", 42 | "react": "^16.0.0", 43 | "react-dom": "^16.0.0", 44 | "vue": "^2.6.14", 45 | "vue-amis-sdk": "^1.10.2", 46 | "vue-router": "2.6.0", 47 | "vuera": "^0.2.7", 48 | "vuex": "3.6.2", 49 | "vuex-persistedstate": "^2.4.2" 50 | }, 51 | "devDependencies": { 52 | "@commitlint/config-conventional": "^15.0.0", 53 | "@popperjs/core": "^2.10.2", 54 | "@typescript-eslint/eslint-plugin": "^5.5.0", 55 | "@typescript-eslint/parser": "^5.5.0", 56 | "@vue/cli-plugin-babel": "^4.5.13", 57 | "@vue/cli-plugin-eslint": "^4.5.13", 58 | "@vue/cli-plugin-pwa": "^4.5.13", 59 | "@vue/cli-service": "^4.5.13", 60 | "@vue/eslint-config-prettier": "^6.0.0", 61 | "babel-eslint": "^10.1.0", 62 | "commitizen": "^4.2.4", 63 | "commitlint": "^15.0.0", 64 | "commitlint-config-cz": "^0.13.2", 65 | "compression-webpack-plugin": "^6.1.1", 66 | "cz-conventional-changelog": "^3.3.0", 67 | "element-ui": "^2.15.8", 68 | "esbuild-loader": "^2.18.0", 69 | "eslint": "^7.32.0", 70 | "eslint-config-prettier": "^8.3.0", 71 | "eslint-config-standard": "^16.0.3", 72 | "eslint-plugin-import": "^2.25.3", 73 | "eslint-plugin-node": "^11.1.0", 74 | "eslint-plugin-prettier": "^4.0.0", 75 | "eslint-plugin-promise": "^5.2.0", 76 | "eslint-plugin-vue": "^7.17.0", 77 | "http-proxy-middleware": "^2.0.6", 78 | "husky": "^7.0.4", 79 | "less": "^3.0.4", 80 | "less-loader": "^4.1.0", 81 | "lint-staged": "^12.1.2", 82 | "prettier": "^2.5.1", 83 | "rc-input-number": "7.3.11", 84 | "register-service-worker": "^1.7.2", 85 | "stylelint": "^13.13.1", 86 | "stylelint-config-prettier": "^8.0.2", 87 | "stylelint-config-recess-order": "^2.5.0", 88 | "typescript": "^4.5.2", 89 | "vue-eslint-parser": "^6.0.0", 90 | "vue-template-compiler": "^2.6.11", 91 | "webpack": "4.46.0", 92 | "webpackbar": "^5.0.0-3" 93 | }, 94 | "homepage": "https://amis-admin-vue.vercel.app", 95 | "eslintConfig": { 96 | "root": true, 97 | "env": { 98 | "node": true 99 | }, 100 | "engines": { 101 | "node": ">= 12.0.0", 102 | "npm": ">= 3.0.0" 103 | }, 104 | "extends": [ 105 | "plugin:vue/essential", 106 | "eslint:recommended" 107 | ], 108 | "parserOptions": { 109 | "parser": "babel-eslint" 110 | }, 111 | "rules": {} 112 | }, 113 | "gitHooks": { 114 | "pre-commit": "lint-staged" 115 | }, 116 | "lint-staged": { 117 | "*.{js,jsx,vue}": [ 118 | "vue-cli-service lint" 119 | ] 120 | }, 121 | "config": { 122 | "commitizen": { 123 | "path": "cz-conventional-changelog" 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /public/pages/formula.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "公式示例", 3 | "body": [ 4 | "

通过公式,可以动态的设置目标值。

", 5 | { 6 | "type": "form", 7 | "title": "自动应用", 8 | "api": "/amis/api/mock2/form/saveForm", 9 | "body": [ 10 | { 11 | "type": "input-number", 12 | "name": "a", 13 | "label": "A" 14 | }, 15 | { 16 | "type": "input-number", 17 | "name": "b", 18 | "label": "B" 19 | }, 20 | { 21 | "type": "input-number", 22 | "name": "sum", 23 | "label": "和", 24 | "disabled": true, 25 | "description": "自动计算 A + B" 26 | }, 27 | { 28 | "type": "formula", 29 | "name": "sum", 30 | "value": 0, 31 | "formula": "a + b" 32 | } 33 | ] 34 | }, 35 | { 36 | "type": "form", 37 | "title": "手动应用", 38 | "api": "/amis/api/mock2/form/saveForm", 39 | "body": [ 40 | { 41 | "type": "input-number", 42 | "name": "a", 43 | "label": "A" 44 | }, 45 | { 46 | "type": "input-number", 47 | "name": "b", 48 | "label": "B" 49 | }, 50 | { 51 | "type": "group", 52 | "body": [ 53 | { 54 | "type": "input-number", 55 | "name": "sum", 56 | "label": "和", 57 | "disabled": true, 58 | "columnClassName": "col-sm-11" 59 | }, 60 | { 61 | "type": "button", 62 | "label": "计算", 63 | "columnClassName": "col-sm-1 v-bottom", 64 | "target": "theFormula" 65 | } 66 | ] 67 | }, 68 | { 69 | "type": "formula", 70 | "name": "sum", 71 | "id": "theFormula", 72 | "value": 0, 73 | "formula": "a + b", 74 | "initSet": false, 75 | "autoSet": false 76 | } 77 | ] 78 | }, 79 | { 80 | "type": "form", 81 | "title": "条件应用", 82 | "api": "/amis/api/mock2/form/saveForm", 83 | "body": [ 84 | { 85 | "type": "radios", 86 | "name": "radios", 87 | "inline": true, 88 | "label": "radios", 89 | "options": [ 90 | { 91 | "label": "a", 92 | "value": "a" 93 | }, 94 | { 95 | "label": "b", 96 | "value": "b" 97 | } 98 | ], 99 | "description": "radios 变化会自动清空 B" 100 | }, 101 | { 102 | "type": "input-text", 103 | "name": "b", 104 | "label": "B" 105 | }, 106 | { 107 | "type": "formula", 108 | "name": "b", 109 | "value": "some string", 110 | "formula": "''", 111 | "condition": "${radios}", 112 | "initSet": false 113 | } 114 | ] 115 | } 116 | ] 117 | } -------------------------------------------------------------------------------- /public/pages/crud-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "列表", 4 | "remark": null, 5 | "name": "page-demo", 6 | "toolbar": [ 7 | { 8 | "type": "button", 9 | "actionType": "link", 10 | "link": "/crud/new", 11 | "label": "新增", 12 | "primary": true 13 | } 14 | ], 15 | "body": [ 16 | { 17 | "type": "crud", 18 | "name": "sample", 19 | "api": "/api/sample", 20 | "filter": { 21 | "title": "", 22 | "mode": "inline", 23 | "wrapWithPanel": false, 24 | "submitText": "", 25 | "controls": [ 26 | { 27 | "type": "text", 28 | "name": "keywords", 29 | "placeholder": "通过关键字搜索", 30 | "addOn": { 31 | "label": "搜索", 32 | "type": "submit", 33 | "className": "btn-success" 34 | }, 35 | "clearable": true 36 | } 37 | ], 38 | "className": "m-b-sm" 39 | }, 40 | "bulkActions": [ 41 | { 42 | "label": "批量修改", 43 | "type": "button", 44 | "actionType": "dialog", 45 | "level": "primary", 46 | "dialog": { 47 | "title": "批量编辑", 48 | "name": "sample-bulk-edit", 49 | "body": { 50 | "type": "form", 51 | "api": "/api/sample/bulkUpdate2", 52 | "controls": [ 53 | { 54 | "type": "text", 55 | "name": "engine", 56 | "label": "Engine" 57 | } 58 | ] 59 | } 60 | } 61 | }, 62 | { 63 | "label": "批量删除", 64 | "type": "button", 65 | "level": "danger", 66 | "actionType": "ajax", 67 | "api": "delete:/api/sample/$ids", 68 | "confirmText": "确定要批量删除?" 69 | } 70 | ], 71 | "columns": [ 72 | { 73 | "name": "engine", 74 | "label": "Rendering engine", 75 | "sortable": true 76 | }, 77 | { 78 | "name": "id", 79 | "label": "ID", 80 | "width": 20, 81 | "sortable": true 82 | }, 83 | { 84 | "name": "browser", 85 | "label": "Browser", 86 | "sortable": true 87 | }, 88 | { 89 | "name": "platform", 90 | "label": "Platform(s)", 91 | "sortable": true 92 | }, 93 | { 94 | "name": "version", 95 | "label": "Engine version" 96 | }, 97 | { 98 | "name": "grade", 99 | "label": "CSS grade" 100 | }, 101 | { 102 | "type": "operation", 103 | "label": "操作", 104 | "width": "", 105 | "buttons": [ 106 | { 107 | "type": "button-group", 108 | "buttons": [ 109 | { 110 | "type": "button", 111 | "label": "查看", 112 | "level": "primary", 113 | "actionType": "link", 114 | "link": "/crud/${id}" 115 | }, 116 | { 117 | "type": "button", 118 | "label": "修改", 119 | "level": "info", 120 | "actionType": "link", 121 | "link": "/crud/${id}/edit" 122 | }, 123 | { 124 | "type": "button", 125 | "label": "删除", 126 | "level": "danger", 127 | "actionType": "ajax", 128 | "confirmText": "您确认要删除?", 129 | "api": "delete:/api/sample/$id" 130 | } 131 | ] 132 | } 133 | ], 134 | "placeholder": "-", 135 | "fixed": "right" 136 | } 137 | ], 138 | "affixHeader": true, 139 | "columnsTogglable": "auto", 140 | "placeholder": "暂无数据", 141 | "tableClassName": "table-db table-striped", 142 | "headerClassName": "crud-table-header", 143 | "footerClassName": "crud-table-footer", 144 | "toolbarClassName": "crud-table-toolbar", 145 | "combineNum": 0, 146 | "bodyClassName": "panel-default" 147 | } 148 | ] 149 | } 150 | -------------------------------------------------------------------------------- /public/pages/horizontal-horizontal.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "HBox & Grid", 3 | "type": "page", 4 | "body": [ 5 | { 6 | "type": "plain", 7 | "tpl": "Grid 请参考 bootstrap 的 grid 布局", 8 | "inline": false, 9 | "className": "h3 m-b-xs" 10 | }, 11 | { 12 | "type": "grid", 13 | "columns": [ 14 | { 15 | "type": "tpl", 16 | "tpl": "sm-2", 17 | "sm": 2, 18 | "className": "bg-info", 19 | "inline": false 20 | }, 21 | { 22 | "type": "tpl", 23 | "tpl": "sm-4", 24 | "sm": 4, 25 | "className": "bg-success", 26 | "inline": false 27 | }, 28 | { 29 | "type": "tpl", 30 | "tpl": "sm-6", 31 | "sm": 6, 32 | "className": "bg-primary", 33 | "inline": false 34 | } 35 | ] 36 | }, 37 | { 38 | "type": "plain", 39 | "tpl": "Hbox", 40 | "inline": false, 41 | "className": "h3 m-t m-b-xs" 42 | }, 43 | { 44 | "type": "hbox", 45 | "columns": [ 46 | { 47 | "type": "tpl", 48 | "tpl": "平均分配", 49 | "className": "bg-info", 50 | "inline": false 51 | }, 52 | { 53 | "type": "tpl", 54 | "tpl": "平均分配", 55 | "className": "bg-success", 56 | "inline": false 57 | }, 58 | { 59 | "type": "tpl", 60 | "tpl": "平均分配", 61 | "className": "bg-primary", 62 | "inline": false 63 | } 64 | ] 65 | }, 66 | { 67 | "type": "plain", 68 | "tpl": "Hbox 部分定宽", 69 | "inline": false, 70 | "className": "h3 m-t m-b-xs" 71 | }, 72 | { 73 | "type": "hbox", 74 | "columns": [ 75 | { 76 | "type": "tpl", 77 | "tpl": "w-xs", 78 | "className": "bg-info", 79 | "inline": false, 80 | "columnClassName": "w-xs" 81 | }, 82 | { 83 | "type": "tpl", 84 | "tpl": "w-sm", 85 | "className": "bg-info lter", 86 | "inline": false, 87 | "columnClassName": "w-sm" 88 | }, 89 | { 90 | "type": "tpl", 91 | "tpl": "w", 92 | "className": "bg-info dk", 93 | "inline": false, 94 | "columnClassName": "w" 95 | }, 96 | { 97 | "type": "tpl", 98 | "tpl": "平均分配", 99 | "className": "bg-success", 100 | "inline": false 101 | }, 102 | { 103 | "type": "tpl", 104 | "tpl": "平均分配", 105 | "className": "bg-primary", 106 | "inline": false 107 | } 108 | ] 109 | }, 110 | { 111 | "type": "plain", 112 | "tpl": "示例", 113 | "inline": false, 114 | "className": "h3 m-t m-b-xs" 115 | }, 116 | { 117 | "type": "grid", 118 | "columns": [ 119 | { 120 | "type": "panel", 121 | "title": "面板1", 122 | "className": "Panel--danger", 123 | "body": "内容", 124 | "sm": 4 125 | }, 126 | { 127 | "type": "panel", 128 | "title": "面板2", 129 | "className": "Panel--primary", 130 | "body": "内容", 131 | "sm": 8 132 | } 133 | ] 134 | } 135 | ] 136 | } -------------------------------------------------------------------------------- /public/pages/event-action-dataflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "数据传递", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "tpl", 12 | "tpl": "

从事件触发开始,整个数据流包含事件本身产生的事件数据和动作产生的动作数据,事件源头产生的数据在AMIS事件动作机制底层已经自动加入渲染器数据域,可以通过\"event.data.xxx\"直接获取,而部分动作产生的数据如何流动需要交互设计者进行介入,对于数据流动可以通过数据映射,将上一个动作产生的数据作为动作参数写入下一个动作。通过outputVar指定输出的变量名,通过args指定输入的参数数据

" 13 | }, 14 | { 15 | "type": "button", 16 | "id": "b_001", 17 | "label": "发一个广播,携带args参数", 18 | "onEvent": { 19 | "click": { 20 | "actions": [ 21 | { 22 | "actionType": "broadcast", 23 | "eventName": "broadcast_1", 24 | "args": { 25 | "name": "lvxj", 26 | "age": 18 27 | }, 28 | "description": "一个按钮的点击事件" 29 | } 30 | ] 31 | } 32 | } 33 | }, 34 | { 35 | "type": "button", 36 | "id": "b_001", 37 | "label": "发送Ajax请求,并把返回数据传给弹窗", 38 | "className": "ml-2", 39 | "onEvent": { 40 | "click": { 41 | "actions": [ 42 | { 43 | "actionType": "ajax", 44 | "api": "/amis/api/mock2/form/saveForm", 45 | "messages": { 46 | "success": "成功了!欧耶", 47 | "failed": "失败了呢。。" 48 | }, 49 | "outputVar": "ajax1" 50 | }, 51 | { 52 | "actionType": "dialog", 53 | "args": { 54 | "id": "${event.data.ajax1.id}" 55 | }, 56 | "dialog": { 57 | "type": "dialog", 58 | "id": "dialog_1", 59 | "title": "弹框标题1", 60 | "data": { 61 | "id": "${id}" 62 | }, 63 | "body": [ 64 | { 65 | "type": "form", 66 | "debug": true, 67 | "body": [ 68 | { 69 | "type": "tpl", 70 | "tpl": "

Ajax请求返回的id=${id}

", 71 | "inline": false 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | } 78 | ] 79 | } 80 | } 81 | }, 82 | { 83 | "type": "form", 84 | "name": "form1", 85 | "id": "form_001", 86 | "title": "表单1-监听广播并获取携带的参数", 87 | "debug": true, 88 | "body": [ 89 | { 90 | "type": "input-text", 91 | "id": "form_001_text_01", 92 | "label": "年龄", 93 | "name": "age", 94 | "disabled": false, 95 | "mode": "horizontal" 96 | } 97 | ], 98 | "data": { 99 | "name": "amis" 100 | }, 101 | "onEvent": { 102 | "broadcast_1": { 103 | "actions": [ 104 | { 105 | "actionType": "reload", 106 | "args": { 107 | "age": "${event.data.age}" 108 | } 109 | } 110 | ] 111 | } 112 | } 113 | } 114 | ] 115 | } -------------------------------------------------------------------------------- /public/pages/tabs-tab3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "选项卡3页面", 4 | "body": [ 5 | "

也可以多个页面,利用导航nav渲染期模拟 tabs 的效果。

", 6 | { 7 | "type": "nav", 8 | "links": [ 9 | { 10 | "label": "选项卡1", 11 | "icon": "fa fa-cloud", 12 | "to": "./tab1" 13 | }, 14 | { 15 | "label": "选项卡2", 16 | "to": "./tab2" 17 | }, 18 | { 19 | "label": "选项卡3", 20 | "icon": "fa fa-youtube", 21 | "to": "./tab3" 22 | } 23 | ] 24 | }, 25 | { 26 | "type": "wrapper", 27 | "className": "wrapper bg-white b-l b-b b-r", 28 | "body": { 29 | "type": "chart", 30 | "config": { 31 | "title": { 32 | "text": "极坐标双数值轴" 33 | }, 34 | "legend": { 35 | "data": [ 36 | "line" 37 | ] 38 | }, 39 | "polar": { 40 | "center": [ 41 | "50%", 42 | "54%" 43 | ] 44 | }, 45 | "tooltip": { 46 | "trigger": "axis", 47 | "axisPointer": { 48 | "type": "cross" 49 | } 50 | }, 51 | "angleAxis": { 52 | "type": "value", 53 | "startAngle": 0 54 | }, 55 | "radiusAxis": { 56 | "min": 0 57 | }, 58 | "series": [ 59 | { 60 | "coordinateSystem": "polar", 61 | "name": "line", 62 | "type": "line", 63 | "showSymbol": false, 64 | "data": [ 65 | [ 66 | 0, 67 | 0 68 | ], 69 | [ 70 | 0.03487823687206265, 71 | 1 72 | ], 73 | [ 74 | 0.06958655048003272, 75 | 2 76 | ], 77 | [ 78 | 0.10395584540887964, 79 | 3 80 | ], 81 | [ 82 | 0.13781867790849958, 83 | 4 84 | ], 85 | [ 86 | 0.17101007166283433, 87 | 5 88 | ], 89 | [ 90 | 0.2033683215379001, 91 | 6 92 | ], 93 | [ 94 | 0.2347357813929454, 95 | 7 96 | ], 97 | [ 98 | 0.26495963211660245, 99 | 8 100 | ], 101 | [ 102 | 0.2938926261462365, 103 | 9 104 | ], 105 | [ 106 | 0.3213938048432697, 107 | 10 108 | ] 109 | ] 110 | } 111 | ], 112 | "animationDuration": 2000 113 | } 114 | } 115 | } 116 | ] 117 | } -------------------------------------------------------------------------------- /src/components/View/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 49 | 106 | -------------------------------------------------------------------------------- /public/pages/services-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "动态加载数据", 4 | "body": [ 5 | "除了用 Page、CRUD、Form 或者 Wizard 能拉取数据外,还可以通过 Service 专门拉取数据,然后丢给其他类型的渲染器渲染。", 6 | { 7 | "type": "form", 8 | "title": "条件输入", 9 | "className": "m-t", 10 | "wrapWithPanel": false, 11 | "target": "service1", 12 | "mode": "inline", 13 | "body": [ 14 | { 15 | "type": "input-text", 16 | "name": "keywords", 17 | "placeholder": "关键字", 18 | "addOn": { 19 | "type": "button", 20 | "icon": "fa fa-search", 21 | "actionType": "submit", 22 | "level": "primary" 23 | } 24 | } 25 | ] 26 | }, 27 | { 28 | "name": "service1", 29 | "type": "service", 30 | "className": "m-t", 31 | "api": "/amis/api/mock2/service/data?keywords=${keywords}", 32 | "body": [ 33 | "当前关键字是 ${keywords},当前时间是: ${date|date:YYYY-MM-DD HH\\:mm}", 34 | { 35 | "type": "table", 36 | "className": "m-t", 37 | "source": "${table1}", 38 | "columns": [ 39 | { 40 | "name": "id", 41 | "label": "ID", 42 | "type": "text" 43 | }, 44 | { 45 | "name": "text", 46 | "label": "文本", 47 | "type": "text" 48 | }, 49 | { 50 | "type": "image", 51 | "label": "图片", 52 | "name": "image", 53 | "popOver": { 54 | "title": "查看大图", 55 | "body": "
" 56 | } 57 | }, 58 | { 59 | "name": "date", 60 | "type": "date", 61 | "label": "日期" 62 | } 63 | ] 64 | }, 65 | { 66 | "type": "table", 67 | "source": "${table2}", 68 | "columns": [ 69 | { 70 | "name": "progress", 71 | "label": "进度", 72 | "type": "progress" 73 | }, 74 | { 75 | "name": "boolean", 76 | "label": "状态", 77 | "type": "status" 78 | }, 79 | { 80 | "name": "boolean", 81 | "label": "开关", 82 | "type": "switch" 83 | }, 84 | { 85 | "name": "type", 86 | "label": "映射", 87 | "type": "mapping", 88 | "map": { 89 | "1": "漂亮", 90 | "2": "开心", 91 | "3": "惊吓", 92 | "4": "紧张", 93 | "*": "其他:${type}" 94 | } 95 | }, 96 | { 97 | "name": "list", 98 | "type": "list", 99 | "label": "List", 100 | "placeholder": "-", 101 | "listItem": { 102 | "title": "${title}", 103 | "subTitle": "${description}" 104 | } 105 | } 106 | ] 107 | } 108 | ] 109 | } 110 | ] 111 | } -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | webpackBarName: 'amis-admin-vue', 3 | webpackBanner: ' build: amis-admin-vue \n copyright: h7ml (h7ml@qq.com)' 4 | } 5 | const productionGzipExtensions = [ 6 | 'html', 7 | 'js', 8 | 'css', 9 | 'svg', 10 | 'ttf', 11 | 'woff', 12 | 'woff2', 13 | 'eot', 14 | 'png', 15 | 'jpg', 16 | 'jpeg', 17 | 'gif', 18 | 'ico', 19 | 'webp', 20 | 'json' 21 | ] 22 | const path = require('path') 23 | const WebpackBar = require('webpackbar') 24 | const resolve = dir => { 25 | return path.join(__dirname, dir) 26 | } 27 | 28 | const { ESBuildMinifyPlugin } = require('esbuild-loader') 29 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 30 | const Webpack = require('webpack') 31 | module.exports = { 32 | devServer: { 33 | proxy: { 34 | '/amis': { 35 | target: 'https://aisuda.bce.baidu.com/', 36 | changeOrigin: true 37 | } 38 | } 39 | }, 40 | configureWebpack() { 41 | return { 42 | resolve: { 43 | alias: { 44 | '~': resolve('.'), 45 | '@': resolve('src') 46 | } 47 | }, 48 | plugins: [ 49 | new Webpack.ProvidePlugin({}), 50 | new WebpackBar({ 51 | name: config.webpackBarName 52 | }) 53 | ], 54 | output: { 55 | filename: `output/assets/js/amis.[name].js`, 56 | chunkFilename: `output/assets/js/amis.[name].js` 57 | } 58 | } 59 | }, 60 | pwa: { 61 | workboxOptions: { 62 | skipWaiting: true, 63 | clientsClaim: true 64 | }, 65 | themeColor: '#ffffff', 66 | msTileColor: '#ffffff', 67 | appleMobileWebAppCapable: 'yes', 68 | appleMobileWebAppStatusBarStyle: 'black', 69 | manifestOptions: { 70 | name: 'amis-admin-vue', 71 | short_name: 'amis-admin-vue', 72 | background_color: '#ffffff' 73 | } 74 | }, 75 | chainWebpack(config) { 76 | const rule = config.module.rule('js') 77 | 78 | // 清理自带的 babel-loader 79 | rule.uses.clear() 80 | 81 | // 添加 esbuild-loader 82 | rule 83 | .use('esbuild-loader') 84 | .loader('esbuild-loader') 85 | .options({ 86 | loader: 'ts', // 如果使用了 ts, 或者 vue 的 class 装饰器,则需要加上这个 option 配置, 否则会报错:ERROR: Unexpected "@" 87 | target: 'es2015', 88 | tsconfigRaw: require('./tsconfig.json') 89 | }) 90 | // 删除底层 terser, 换用 esbuild-minimize-plugin 91 | config.optimization.minimizers.delete('terser') 92 | 93 | // 使用 esbuild 优化 css 压缩 94 | config.optimization 95 | .minimizer('esbuild') 96 | .use(ESBuildMinifyPlugin, [{ minify: true, css: true }]) 97 | 98 | config.resolve.symlinks(true) 99 | config.when(process.env.NODE_ENV === 'development', config => { 100 | config.devtool('source-map') 101 | }) 102 | config.when(process.env.NODE_ENV === 'production', config => { 103 | config.performance.set('hints', false) 104 | config.devtool('none') 105 | config.optimization.splitChunks({ 106 | automaticNameDelimiter: '-', 107 | chunks: 'all', 108 | cacheGroups: { 109 | chunk: { 110 | name: 'amis-chunk', 111 | test: /[\\/]node_modules[\\/]/, 112 | minSize: 131072, 113 | maxSize: 524288, 114 | chunks: 'async', 115 | minChunks: 2, 116 | priority: 10 117 | }, 118 | vue: { 119 | name: 'vue', 120 | test: /[\\/]node_modules[\\/](vue(.*)|core-js)[\\/]/, 121 | chunks: 'initial', 122 | priority: 20 123 | }, 124 | elementUI: { 125 | name: 'element-ui', 126 | test: /[\\/]node_modules[\\/]element-ui(.*)[\\/]/, 127 | priority: 30 128 | } 129 | } 130 | }) 131 | config 132 | .plugin('banner') 133 | .use(Webpack.BannerPlugin, [`${config.webpackBanner}`]) 134 | config.plugin('compression').use(CompressionWebpackPlugin, [ 135 | { 136 | filename: '[path][base].gz[query]', 137 | algorithm: 'gzip', 138 | test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), 139 | threshold: 8192, 140 | minRatio: 0.8 141 | } 142 | ]) 143 | }) 144 | }, 145 | runtimeCompiler: true, 146 | productionSourceMap: false, 147 | css: { 148 | requireModuleExtension: true, 149 | sourceMap: true, 150 | extract: { 151 | filename: `output/assets/css/amis.[name].css`, 152 | chunkFilename: `output/assets/css/amis.[name].css` 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /public/pages/event-action-stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "title": "事件/动作干预", 4 | "regions": [ 5 | "body", 6 | "toolbar", 7 | "header" 8 | ], 9 | "body": [ 10 | { 11 | "type": "button", 12 | "id": "b_001", 13 | "label": "联动表单1(事件干预)", 14 | "onEvent": { 15 | "click": { 16 | "actions": [ 17 | { 18 | "actionType": "broadcast", 19 | "eventName": "broadcast_1", 20 | "args": { 21 | "name": "lvxj", 22 | "age": 18 23 | }, 24 | "description": "一个按钮的点击事件" 25 | } 26 | ] 27 | } 28 | } 29 | }, 30 | { 31 | "type": "button", 32 | "id": "b_002", 33 | "label": "联动表单2(动作干预)", 34 | "className": "ml-2", 35 | "onEvent": { 36 | "click": { 37 | "actions": [ 38 | { 39 | "actionType": "broadcast", 40 | "eventName": "broadcast_1", 41 | "args": { 42 | "name": "lvxj", 43 | "age": 18 44 | }, 45 | "description": "一个按钮的点击事件" 46 | } 47 | ] 48 | } 49 | } 50 | }, 51 | { 52 | "type": "form", 53 | "name": "form1", 54 | "id": "form_001", 55 | "title": "表单1-刷新(刷新后,按钮的弹窗动作因为被干预,不会执行)", 56 | "debug": true, 57 | "body": [ 58 | { 59 | "type": "input-text", 60 | "id": "form_001_text_01", 61 | "label": "年龄", 62 | "name": "age", 63 | "disabled": false, 64 | "mode": "horizontal" 65 | } 66 | ], 67 | "data": { 68 | "expression": "kkk", 69 | "param": "1" 70 | }, 71 | "onEvent": { 72 | "broadcast_1": { 73 | "actions": [ 74 | { 75 | "actionType": "reload", 76 | "args": { 77 | "age": "${event.data.age}" 78 | }, 79 | "preventDefault": true, 80 | "expression": "expression === \"kkk\"" 81 | } 82 | ] 83 | } 84 | } 85 | }, 86 | { 87 | "type": "form", 88 | "name": "form2", 89 | "id": "form_002", 90 | "title": "表单2-刷新+发Ajax(只执行刷新,Ajax请求被干预,不会执行)", 91 | "debug": true, 92 | "body": [ 93 | { 94 | "type": "input-text", 95 | "id": "form_001_text_01", 96 | "label": "年龄", 97 | "name": "age", 98 | "disabled": false, 99 | "mode": "horizontal" 100 | } 101 | ], 102 | "data": { 103 | "expression": "kkk", 104 | "param": "1" 105 | }, 106 | "onEvent": { 107 | "broadcast_1": { 108 | "actions": [ 109 | { 110 | "actionType": "reload", 111 | "args": { 112 | "age": "${event.data.age}" 113 | }, 114 | "preventDefault": false, 115 | "stopPropagation": true, 116 | "expression": "expression === \"kkk\"" 117 | }, 118 | { 119 | "actionType": "ajax", 120 | "args": { 121 | "param": "2" 122 | }, 123 | "api": "https://api/form/ajax?param=${param}", 124 | "expression": "expression === \"kkk\"", 125 | "preventDefault": false, 126 | "stopPropagation": false 127 | } 128 | ] 129 | } 130 | } 131 | } 132 | ] 133 | } -------------------------------------------------------------------------------- /public/pages/echarts-echarts.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "cssVars": { 4 | "--Form-input-paddingY": "0.25rem" 5 | }, 6 | "title": "ECharts 图表可视化编辑,用于演示如何基于 amis 将任意 json 配置改造成可视化编辑,这个例子无法复制配置,实现方式请在源码中寻找", 7 | "data": { 8 | "config": { 9 | "title": { 10 | "text": "未来一周气温变化", 11 | "subtext": "纯属虚构" 12 | }, 13 | "tooltip": { 14 | "trigger": "axis" 15 | }, 16 | "legend": { 17 | "data": [ 18 | "最高气温", 19 | "最低气温" 20 | ] 21 | }, 22 | "toolbox": { 23 | "show": true, 24 | "feature": { 25 | "mark": { 26 | "show": true 27 | }, 28 | "dataView": { 29 | "show": true, 30 | "readOnly": true 31 | }, 32 | "magicType": { 33 | "show": false, 34 | "type": [ 35 | "line", 36 | "bar" 37 | ] 38 | }, 39 | "restore": { 40 | "show": true 41 | }, 42 | "saveAsImage": { 43 | "show": true 44 | } 45 | } 46 | }, 47 | "calculable": true, 48 | "xAxis": [ 49 | { 50 | "type": "category", 51 | "boundaryGap": false, 52 | "data": [ 53 | "周一", 54 | "周二", 55 | "周三", 56 | "周四", 57 | "周五", 58 | "周六", 59 | "周日" 60 | ] 61 | } 62 | ], 63 | "yAxis": [ 64 | { 65 | "type": "value", 66 | "name": "°C" 67 | } 68 | ], 69 | "series": [ 70 | { 71 | "name": "最高气温", 72 | "type": "line", 73 | "data": [ 74 | 11, 75 | 11, 76 | 15, 77 | 13, 78 | 12, 79 | 13, 80 | 10 81 | ] 82 | }, 83 | { 84 | "name": "最低气温", 85 | "type": "line", 86 | "data": [ 87 | 1, 88 | -2, 89 | 2, 90 | 5, 91 | 3, 92 | 2, 93 | 0 94 | ] 95 | } 96 | ] 97 | } 98 | }, 99 | "body": [ 100 | { 101 | "type": "form", 102 | "title": "", 103 | "controls": [ 104 | { 105 | "type": "grid", 106 | "columns": [ 107 | { 108 | "sm": 12, 109 | "md": 5, 110 | "columnClassName": "pl-1 pr-0.5", 111 | "controls": [ 112 | { 113 | "type": "chart", 114 | "source": "${config}", 115 | "replaceChartOption": true, 116 | "unMountOnHidden": false 117 | }, 118 | { 119 | "type": "editor", 120 | "name": "config", 121 | "language": "json", 122 | "disabled": true, 123 | "options": { 124 | "lineNumbers": "off" 125 | }, 126 | "source": "${config}" 127 | } 128 | ] 129 | }, 130 | { 131 | "sm": 12, 132 | "md": 7, 133 | "columnClassName": "pl-0.5 pr-1", 134 | "controls": [ 135 | {} 136 | ] 137 | } 138 | ] 139 | } 140 | ] 141 | } 142 | ] 143 | } -------------------------------------------------------------------------------- /public/pages/table.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "表格编辑", 3 | "body": { 4 | "type": "form", 5 | "mode": "horizontal", 6 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 7 | "actions": [ 8 | { 9 | "type": "submit", 10 | "label": "提交", 11 | "primary": true 12 | } 13 | ], 14 | "body": [ 15 | { 16 | "type": "combo", 17 | "name": "colors", 18 | "label": "Combo", 19 | "multiple": true, 20 | "draggable": true, 21 | "multiLine": true, 22 | "value": [ 23 | { 24 | "color": "green", 25 | "name": "颜色" 26 | } 27 | ], 28 | "items": [ 29 | { 30 | "type": "input-color", 31 | "name": "color", 32 | "clearable": false 33 | }, 34 | { 35 | "type": "input-text", 36 | "name": "name", 37 | "placeholder": "说明文字" 38 | } 39 | ] 40 | }, 41 | { 42 | "type": "static", 43 | "label": "当前值", 44 | "tpl": "
${colors|json}
" 45 | }, 46 | { 47 | "type": "input-table", 48 | "name": "colors", 49 | "label": "Table", 50 | "draggable": true, 51 | "addable": true, 52 | "removable": true, 53 | "needConfirm": false, 54 | "columns": [ 55 | { 56 | "label": "Color", 57 | "name": "color", 58 | "type": "input-color", 59 | "quickEdit": false 60 | }, 61 | { 62 | "label": "说明文字", 63 | "name": "name" 64 | } 65 | ] 66 | }, 67 | { 68 | "type": "control", 69 | "body": { 70 | "type": "button", 71 | "label": "Table2新增一行", 72 | "target": "table2", 73 | "actionType": "add" 74 | } 75 | }, 76 | { 77 | "type": "input-table", 78 | "name": "table2", 79 | "label": "Table2", 80 | "editable": true, 81 | "addable": true, 82 | "removable": true, 83 | "draggable": true, 84 | "columns": [ 85 | { 86 | "name": "a", 87 | "label": "A" 88 | }, 89 | { 90 | "name": "b", 91 | "label": "B", 92 | "quickEdit": { 93 | "type": "select", 94 | "options": [ 95 | { 96 | "label": "A", 97 | "value": "a" 98 | }, 99 | { 100 | "label": "B", 101 | "value": "b" 102 | } 103 | ] 104 | } 105 | } 106 | ] 107 | }, 108 | { 109 | "type": "input-table", 110 | "name": "table3", 111 | "label": "Table3(指定第2列只有update时能编辑)", 112 | "editable": true, 113 | "addable": true, 114 | "removable": true, 115 | "draggable": true, 116 | "columns": [ 117 | { 118 | "name": "a", 119 | "label": "A", 120 | "quickEdit": true 121 | }, 122 | { 123 | "name": "b", 124 | "label": "B", 125 | "quickEdit": false, 126 | "quickEditOnUpdate": { 127 | "type": "select", 128 | "options": [ 129 | { 130 | "label": "A", 131 | "value": "a" 132 | }, 133 | { 134 | "label": "B", 135 | "value": "b" 136 | } 137 | ] 138 | } 139 | } 140 | ] 141 | } 142 | ] 143 | } 144 | } -------------------------------------------------------------------------------- /public/pages/remote.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "动态拉取选项", 3 | "name": "page-form-remote", 4 | "body": [ 5 | { 6 | "type": "form", 7 | "title": "动态表单元素示例", 8 | "name": "demo-form", 9 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 10 | "mode": "horizontal", 11 | "actions": [ 12 | { 13 | "type": "submit", 14 | "label": "提交" 15 | } 16 | ], 17 | "body": [ 18 | { 19 | "name": "select", 20 | "type": "select", 21 | "label": "动态选项", 22 | "source": "/amis/api/mock2/form/getOptions?waitSeconds=1", 23 | "description": "通过接口一口气拉取选项", 24 | "clearable": true, 25 | "searchable": true 26 | }, 27 | { 28 | "type": "divider" 29 | }, 30 | { 31 | "name": "select2", 32 | "type": "select", 33 | "label": "选项自动补全", 34 | "autoComplete": "/amis/api/mock2/options/autoComplete?term=$term", 35 | "placeholder": "请输入", 36 | "description": "通过接口自动补全" 37 | }, 38 | { 39 | "type": "divider" 40 | }, 41 | { 42 | "type": "input-text", 43 | "name": "text", 44 | "label": "文本提示", 45 | "source": "/amis/api/mock2/form/getOptions?waitSeconds=1", 46 | "placeholder": "请选择", 47 | "creatable": true 48 | }, 49 | { 50 | "type": "divider" 51 | }, 52 | { 53 | "name": "text2", 54 | "type": "input-text", 55 | "label": "文本自动补全", 56 | "clearable": true, 57 | "autoComplete": "/amis/api/mock2/options/autoComplete2?term=$term", 58 | "description": "通过接口自动补全" 59 | }, 60 | { 61 | "name": "chained", 62 | "type": "chained-select", 63 | "label": "级联选项", 64 | "source": "/amis/api/mock2/options/chainedOptions?waitSeconds=1&parentId=$parentId&level=$level&maxLevel=4&waiSeconds=1", 65 | "desc": "无限级别, 只要 api 返回数据就能继续往下选择. 当没有下级时请返回 null.", 66 | "value": "a,b" 67 | }, 68 | { 69 | "type": "divider" 70 | }, 71 | { 72 | "name": "tree", 73 | "showOutline": true, 74 | "type": "input-tree", 75 | "label": "动态树", 76 | "source": "/amis/api/mock2/options/tree?waitSeconds=1" 77 | }, 78 | { 79 | "type": "divider" 80 | }, 81 | { 82 | "name": "tree", 83 | "type": "input-tree", 84 | "label": "树懒加载", 85 | "multiple": true, 86 | "deferApi": "/amis/api/mock2/form/deferOptions?label=${label}&waitSeconds=2", 87 | "options": [ 88 | { 89 | "label": "法师", 90 | "children": [ 91 | { 92 | "label": "诸葛亮", 93 | "value": "zhugeliang" 94 | } 95 | ] 96 | }, 97 | { 98 | "label": "战士", 99 | "defer": true 100 | }, 101 | { 102 | "label": "打野", 103 | "children": [ 104 | { 105 | "label": "李白", 106 | "value": "libai" 107 | }, 108 | { 109 | "label": "韩信", 110 | "value": "hanxin" 111 | }, 112 | { 113 | "label": "云中君", 114 | "value": "yunzhongjun" 115 | } 116 | ] 117 | } 118 | ] 119 | }, 120 | { 121 | "type": "divider" 122 | }, 123 | { 124 | "name": "matrix", 125 | "type": "matrix-checkboxes", 126 | "label": "动态矩阵开关", 127 | "source": "/amis/api/mock2/options/matrix?waitSeconds=1" 128 | } 129 | ] 130 | } 131 | ] 132 | } -------------------------------------------------------------------------------- /public/pages/anchor-nav.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "表单内锚点导航示例", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "mode": "horizontal", 7 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 8 | "title": "", 9 | "body": [ 10 | { 11 | "type": "anchor-nav", 12 | "links": [ 13 | { 14 | "title": "员工基本信息", 15 | "body": [ 16 | { 17 | "type": "fieldSet", 18 | "title": "员工基本信息", 19 | "body": [ 20 | { 21 | "name": "name", 22 | "type": "input-text", 23 | "label": "用户名" 24 | }, 25 | { 26 | "name": "age", 27 | "type": "input-text", 28 | "label": "年龄" 29 | } 30 | ] 31 | } 32 | ] 33 | }, 34 | { 35 | "title": "在职信息", 36 | "body": [ 37 | { 38 | "type": "fieldSet", 39 | "title": "地址信息", 40 | "body": [ 41 | { 42 | "name": "home", 43 | "type": "input-text", 44 | "label": "居住地址" 45 | }, 46 | { 47 | "name": "address", 48 | "type": "input-text", 49 | "label": "工作地址" 50 | } 51 | ] 52 | } 53 | ] 54 | }, 55 | { 56 | "title": "教育经历", 57 | "body": [ 58 | { 59 | "type": "fieldSet", 60 | "title": "教育经历", 61 | "body": [ 62 | { 63 | "name": "school1", 64 | "type": "input-text", 65 | "label": "经历1" 66 | }, 67 | { 68 | "name": "school2", 69 | "type": "input-text", 70 | "label": "经历2" 71 | }, 72 | { 73 | "name": "school2", 74 | "type": "input-text", 75 | "label": "经历2" 76 | } 77 | ] 78 | } 79 | ] 80 | }, 81 | { 82 | "title": "紧急联系人信息", 83 | "body": [ 84 | { 85 | "type": "fieldSet", 86 | "title": "紧急联系人信息", 87 | "body": [ 88 | { 89 | "name": "contact1", 90 | "type": "input-text", 91 | "label": "联系人1" 92 | }, 93 | { 94 | "name": "contact2", 95 | "type": "input-text", 96 | "label": "联系人2" 97 | }, 98 | { 99 | "name": "contact3", 100 | "type": "input-text", 101 | "label": "联系人3" 102 | } 103 | ] 104 | } 105 | ] 106 | } 107 | ] 108 | } 109 | ] 110 | } 111 | ] 112 | } -------------------------------------------------------------------------------- /public/pages/wizard-wizard.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "表单向导", 3 | "body": [ 4 | { 5 | "type": "wizard", 6 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 7 | "initApi": "/amis/api/mock2/form/initData?waitSeconds=2", 8 | "steps": [ 9 | { 10 | "title": "第一步", 11 | "body": [ 12 | { 13 | "name": "website", 14 | "label": "网址", 15 | "type": "input-url", 16 | "required": true 17 | }, 18 | { 19 | "name": "name", 20 | "label": "名称", 21 | "type": "input-text", 22 | "required": true 23 | } 24 | ] 25 | }, 26 | { 27 | "title": "Step 2", 28 | "body": [ 29 | { 30 | "name": "email2", 31 | "label": "邮箱", 32 | "type": "input-email", 33 | "required": true 34 | } 35 | ] 36 | }, 37 | { 38 | "title": "Step 3", 39 | "body": [ 40 | "这是最后一步了" 41 | ] 42 | } 43 | ] 44 | }, 45 | { 46 | "type": "wizard", 47 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2", 48 | "mode": "vertical", 49 | "steps": [ 50 | { 51 | "title": "第一步", 52 | "body": [ 53 | { 54 | "name": "website", 55 | "label": "网址", 56 | "type": "input-url", 57 | "required": true 58 | }, 59 | { 60 | "name": "email", 61 | "label": "邮箱", 62 | "type": "input-email", 63 | "required": true 64 | } 65 | ] 66 | }, 67 | { 68 | "title": "Step 2", 69 | "body": [ 70 | { 71 | "name": "email2", 72 | "label": "邮箱", 73 | "type": "input-email", 74 | "required": true 75 | } 76 | ] 77 | }, 78 | { 79 | "title": "Step 3", 80 | "body": [ 81 | "这是最后一步了" 82 | ] 83 | } 84 | ] 85 | }, 86 | { 87 | "type": "wizard", 88 | "steps": [ 89 | { 90 | "title": "第一步", 91 | "body": [ 92 | { 93 | "name": "website", 94 | "label": "网址", 95 | "type": "input-url", 96 | "required": true 97 | }, 98 | { 99 | "name": "email", 100 | "label": "邮箱", 101 | "type": "input-email", 102 | "required": true 103 | } 104 | ], 105 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2" 106 | }, 107 | { 108 | "title": "第二步", 109 | "body": [ 110 | { 111 | "name": "test1", 112 | "type": "input-email", 113 | "label": "Email", 114 | "value": "test@test.com" 115 | }, 116 | { 117 | "type": "divider" 118 | }, 119 | { 120 | "type": "input-text", 121 | "name": "test2", 122 | "label": "必填示例", 123 | "required": true 124 | }, 125 | { 126 | "type": "divider" 127 | }, 128 | { 129 | "type": "input-text", 130 | "name": "test3", 131 | "placeholder": "可选" 132 | } 133 | ], 134 | "initApi": "/amis/api/mock2/form/initForm", 135 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2" 136 | }, 137 | { 138 | "title": "确定", 139 | "body": [ 140 | "最后一步了,确认要提交吗?" 141 | ], 142 | "api": "/amis/api/mock2/form/saveForm?waitSeconds=2" 143 | } 144 | ] 145 | } 146 | ] 147 | } -------------------------------------------------------------------------------- /public/pages/fieldset.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "FieldSet 示例", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "mode": "horizontal", 7 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 8 | "actions": [ 9 | { 10 | "type": "submit", 11 | "label": "提交", 12 | "primary": true 13 | } 14 | ], 15 | "collapsable": true, 16 | "title": "fieldSet 可以对表单元素做个分组", 17 | "body": [ 18 | { 19 | "type": "fieldSet", 20 | "title": "基本信息", 21 | "collapsable": true, 22 | "body": [ 23 | { 24 | "type": "group", 25 | "body": [ 26 | { 27 | "type": "input-email", 28 | "name": "email", 29 | "placeholder": "请输入邮箱地址", 30 | "label": "邮箱" 31 | }, 32 | { 33 | "type": "input-password", 34 | "name": "password", 35 | "label": false, 36 | "placeholder": "Password" 37 | } 38 | ] 39 | }, 40 | { 41 | "type": "divider" 42 | }, 43 | { 44 | "type": "group", 45 | "body": [ 46 | { 47 | "type": "input-email", 48 | "name": "email", 49 | "placeholder": "请输入邮箱地址", 50 | "label": "邮箱" 51 | }, 52 | { 53 | "type": "checkbox", 54 | "name": "rememberMe", 55 | "label": false, 56 | "option": "Remember me" 57 | } 58 | ] 59 | } 60 | ] 61 | }, 62 | { 63 | "title": "其他信息", 64 | "type": "fieldSet", 65 | "body": [ 66 | { 67 | "type": "input-email", 68 | "name": "email", 69 | "placeholder": "请输入邮箱地址", 70 | "label": "邮箱" 71 | }, 72 | { 73 | "type": "divider" 74 | }, 75 | { 76 | "type": "checkbox", 77 | "name": "rememberMe", 78 | "option": "记住我" 79 | } 80 | ] 81 | } 82 | ] 83 | }, 84 | { 85 | "title": "FieldSet 样式集", 86 | "type": "form", 87 | "body": [ 88 | { 89 | "title": "超级小", 90 | "type": "fieldSet", 91 | "className": "fieldset-xs", 92 | "body": [ 93 | { 94 | "type": "plain", 95 | "text": "文本 ..." 96 | } 97 | ] 98 | }, 99 | { 100 | "title": "小尺寸", 101 | "type": "fieldSet", 102 | "className": "fieldset-sm", 103 | "body": [ 104 | { 105 | "type": "plain", 106 | "text": "文本 ..." 107 | } 108 | ] 109 | }, 110 | { 111 | "title": "正常尺寸", 112 | "type": "fieldSet", 113 | "className": "fieldset", 114 | "body": [ 115 | { 116 | "type": "plain", 117 | "text": "文本 ..." 118 | } 119 | ] 120 | }, 121 | { 122 | "title": "中大尺寸", 123 | "type": "fieldSet", 124 | "className": "fieldset-md", 125 | "body": [ 126 | { 127 | "type": "plain", 128 | "text": "文本 ..." 129 | } 130 | ] 131 | }, 132 | { 133 | "title": "超大尺寸", 134 | "type": "fieldSet", 135 | "className": "fieldset-lg", 136 | "body": [ 137 | { 138 | "type": "plain", 139 | "text": "文本 ..." 140 | } 141 | ] 142 | } 143 | ] 144 | } 145 | ] 146 | } -------------------------------------------------------------------------------- /public/pages/fields-tabs.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "FieldSet In Tabs", 3 | "remark": "", 4 | "body": { 5 | "type": "form", 6 | "body": [ 7 | { 8 | "type": "tabs", 9 | "collapsable": true, 10 | "tabs": [ 11 | { 12 | "title": "Tab A", 13 | "body": [ 14 | { 15 | "type": "fieldset", 16 | "body": [ 17 | { 18 | "type": "tabs", 19 | "title": "Group A", 20 | "tabs": [ 21 | { 22 | "title": "SubTab A", 23 | "body": [ 24 | { 25 | "name": "a", 26 | "type": "input-text", 27 | "label": "Text" 28 | }, 29 | { 30 | "name": "a", 31 | "type": "input-text", 32 | "label": "Text" 33 | } 34 | ] 35 | }, 36 | { 37 | "title": "SubTab B", 38 | "body": [ 39 | { 40 | "name": "a", 41 | "type": "input-text", 42 | "label": "Text" 43 | }, 44 | { 45 | "name": "a", 46 | "type": "input-text", 47 | "label": "Text" 48 | } 49 | ] 50 | } 51 | ] 52 | }, 53 | { 54 | "type": "tabs", 55 | "title": "Group B", 56 | "body": [ 57 | { 58 | "name": "a", 59 | "type": "input-text", 60 | "label": "Text" 61 | }, 62 | { 63 | "name": "a", 64 | "type": "input-text", 65 | "label": "Text" 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | ] 72 | }, 73 | { 74 | "title": "Tab B", 75 | "body": [ 76 | { 77 | "type": "fieldset", 78 | "title": "Group A", 79 | "body": [ 80 | { 81 | "name": "a", 82 | "type": "input-text", 83 | "label": "Text" 84 | }, 85 | { 86 | "name": "a", 87 | "type": "input-text", 88 | "label": "Text" 89 | } 90 | ] 91 | }, 92 | { 93 | "type": "fieldset", 94 | "title": "Group B", 95 | "body": [ 96 | { 97 | "name": "a", 98 | "type": "input-text", 99 | "label": "Text" 100 | }, 101 | { 102 | "name": "a", 103 | "type": "input-text", 104 | "label": "Text" 105 | } 106 | ] 107 | } 108 | ] 109 | } 110 | ] 111 | } 112 | ] 113 | } 114 | } -------------------------------------------------------------------------------- /public/pages/crud-jump-next.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "操作并下一个", 3 | "remark": "当存在下一条时,支持直接打开下一条操作。", 4 | "body": { 5 | "type": "crud", 6 | "title": "", 7 | "api": "/amis/api/sample/list", 8 | "columnsTogglable": false, 9 | "columns": [ 10 | { 11 | "name": "id", 12 | "label": "ID", 13 | "width": 20, 14 | "type": "text", 15 | "toggled": true 16 | }, 17 | { 18 | "name": "engine", 19 | "label": "Rendering engine", 20 | "type": "text", 21 | "toggled": true 22 | }, 23 | { 24 | "name": "browser", 25 | "label": "Browser", 26 | "type": "text", 27 | "toggled": true 28 | }, 29 | { 30 | "type": "operation", 31 | "label": "操作", 32 | "width": 130, 33 | "buttons": [ 34 | { 35 | "type": "button", 36 | "icon": "fa fa-pencil", 37 | "actionType": "dialog", 38 | "nextCondition": "true", 39 | "_nextCondition": "可以设置条件比如: data.grade == \"B\"", 40 | "dialog": { 41 | "title": "编辑", 42 | "actions": [ 43 | { 44 | "type": "button", 45 | "actionType": "prev", 46 | "level": "info", 47 | "visibleOn": "data.hasPrev", 48 | "label": "上一个" 49 | }, 50 | { 51 | "type": "button", 52 | "actionType": "cancel", 53 | "label": "关闭" 54 | }, 55 | { 56 | "type": "submit", 57 | "actionType": "next", 58 | "visibleOn": "data.hasNext", 59 | "label": "保存并下一个", 60 | "level": "primary" 61 | }, 62 | { 63 | "type": "submit", 64 | "visibleOn": "!data.hasNext", 65 | "label": "保存", 66 | "level": "primary" 67 | }, 68 | { 69 | "type": "button", 70 | "actionType": "next", 71 | "level": "info", 72 | "visibleOn": "data.hasNext", 73 | "label": "下一个" 74 | } 75 | ], 76 | "body": { 77 | "type": "form", 78 | "name": "sample-edit-form", 79 | "api": "/amis/api/sample/$id", 80 | "body": [ 81 | { 82 | "type": "input-text", 83 | "name": "engine", 84 | "label": "Engine", 85 | "required": true 86 | }, 87 | { 88 | "type": "divider" 89 | }, 90 | { 91 | "type": "input-text", 92 | "name": "browser", 93 | "label": "Browser", 94 | "required": true 95 | }, 96 | { 97 | "type": "divider" 98 | }, 99 | { 100 | "type": "input-text", 101 | "name": "platform", 102 | "label": "Platform(s)", 103 | "required": true 104 | }, 105 | { 106 | "type": "divider" 107 | }, 108 | { 109 | "type": "input-text", 110 | "name": "version", 111 | "label": "Engine version" 112 | }, 113 | { 114 | "type": "divider" 115 | }, 116 | { 117 | "type": "input-text", 118 | "name": "grade", 119 | "label": "CSS grade" 120 | } 121 | ] 122 | } 123 | } 124 | } 125 | ], 126 | "toggled": true 127 | } 128 | ] 129 | } 130 | } -------------------------------------------------------------------------------- /public/pages/condition-builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "条件生成器", 3 | "body": [ 4 | { 5 | "type": "form", 6 | "api": "/amis/api/mock2/saveForm?waitSeconds=2", 7 | "title": "", 8 | "mode": "horizontal", 9 | "horizontal": { 10 | "leftFixed": true 11 | }, 12 | "actions": [ 13 | { 14 | "label": "查看数据", 15 | "type": "button", 16 | "actionType": "dialog", 17 | "dialog": { 18 | "title": "数据", 19 | "body": "
${conditions|json:2}
" 20 | } 21 | } 22 | ], 23 | "body": [ 24 | { 25 | "type": "condition-builder", 26 | "label": "条件组件", 27 | "name": "conditions", 28 | "description": "适合让用户自己拼查询条件,然后后端根据数据生成 query where", 29 | "fields": [ 30 | { 31 | "name": "switch", 32 | "type": "custom", 33 | "label": "开关", 34 | "value": { 35 | "name": "checkbox", 36 | "type": "checkbox", 37 | "label": "勾选框", 38 | "option": "选项说明" 39 | }, 40 | "operators": [ 41 | "equal", 42 | { 43 | "label": "属于", 44 | "value": "belong" 45 | }, 46 | { 47 | "label": "不属于", 48 | "value": "not_belong", 49 | "values": [ 50 | { 51 | "type": "input-date", 52 | "name": "date1", 53 | "label": "日期", 54 | "inputFormat": "YYYY年MM月DD日" 55 | }, 56 | { 57 | "type": "tpl", 58 | "tpl": "~" 59 | }, 60 | { 61 | "type": "input-date", 62 | "name": "date2", 63 | "label": "日期", 64 | "inputFormat": "YYYY年MM月DD日" 65 | } 66 | ] 67 | } 68 | ] 69 | }, 70 | { 71 | "label": "文本", 72 | "type": "text", 73 | "name": "text" 74 | }, 75 | { 76 | "label": "数字", 77 | "type": "number", 78 | "name": "number" 79 | }, 80 | { 81 | "label": "布尔", 82 | "type": "boolean", 83 | "name": "boolean" 84 | }, 85 | { 86 | "label": "选项", 87 | "type": "select", 88 | "name": "select", 89 | "options": [ 90 | { 91 | "label": "A", 92 | "value": "a" 93 | }, 94 | { 95 | "label": "B", 96 | "value": "b" 97 | }, 98 | { 99 | "label": "C", 100 | "value": "c" 101 | }, 102 | { 103 | "label": "D", 104 | "value": "d" 105 | }, 106 | { 107 | "label": "E", 108 | "value": "e" 109 | } 110 | ] 111 | }, 112 | { 113 | "label": "日期", 114 | "children": [ 115 | { 116 | "label": "日期", 117 | "type": "date", 118 | "name": "date" 119 | }, 120 | { 121 | "label": "时间", 122 | "type": "time", 123 | "name": "time" 124 | }, 125 | { 126 | "label": "日期时间", 127 | "type": "datetime", 128 | "name": "datetime" 129 | } 130 | ] 131 | } 132 | ] 133 | } 134 | ] 135 | } 136 | ] 137 | } -------------------------------------------------------------------------------- /public/pages/my-custom.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FormItem, Renderer } from "../../../src/index"; 3 | 4 | @FormItem({ 5 | type: "my-custom", 6 | }) 7 | class MyFormItem extends React.Component { 8 | render() { 9 | const { value, onChange } = this.props; 10 | 11 | return ( 12 |
13 |

这个是个自定义组件。通过注册渲染器的方式实现。

14 | 15 |

当前值:{JSON.stringify(value)}

16 | 17 | onChange(Math.round(Math.random() * 10000))} 20 | > 21 | 随机修改 22 | 23 |
24 | ); 25 | } 26 | } 27 | 28 | @Renderer({ 29 | test: /(^|\/)my\-renderer$/, 30 | autoVar: true, 31 | }) 32 | class CustomRenderer extends React.Component { 33 | render() { 34 | const { tip, source } = this.props; 35 | return source ? ( 36 |
{`非 FormItem 类型的渲染器注册,通过变量获取 x 的值为:${source}`}
37 | ) : ( 38 |
{tip}
39 | ); 40 | } 41 | } 42 | 43 | export default { 44 | title: "自定义组件示例", 45 | body: [ 46 | { 47 | type: "form", 48 | mode: "horizontal", 49 | api: "/api/mock2/form/saveForm?waitSeconds=2", 50 | debug: true, 51 | actions: [ 52 | { 53 | type: "submit", 54 | label: "提交", 55 | primary: true, 56 | }, 57 | ], 58 | body: [ 59 | { 60 | label: "姓名", 61 | type: "text", 62 | name: "name", 63 | }, 64 | 65 | { 66 | type: "divider", 67 | }, 68 | 69 | { 70 | label: "使用 custom 组件", 71 | name: "name", 72 | type: "custom", 73 | onMount: (dom, data, onChange) => { 74 | const button = document.createElement("button"); 75 | button.innerText = "点击修改姓名"; 76 | button.onclick = (event) => { 77 | onChange("new name"); 78 | event.preventDefault(); 79 | }; 80 | dom.appendChild(button); 81 | }, 82 | onUpdate: (dom, data) => { 83 | console.log("数据有变化", data); 84 | }, 85 | }, 86 | 87 | { 88 | type: "divider", 89 | }, 90 | 91 | { 92 | name: "a", 93 | asFormItem: true, 94 | children: ({ value, onChange }) => ( 95 |
96 |

这是使用 children 的方式,也无需注册。

97 | 98 |

当前值:{value}

99 | 100 | onChange(Math.round(Math.random() * 10000))} 103 | > 104 | 随机修改 105 | 106 |
107 | ), 108 | }, 109 | 110 | { 111 | type: "divider", 112 | }, 113 | 114 | { 115 | name: "b", 116 | type: "my-custom", 117 | label: "自定义FormItem", 118 | }, 119 | 120 | { 121 | type: "divider", 122 | }, 123 | 124 | { 125 | type: "control", 126 | body: { 127 | type: "my-renderer", 128 | source: "${x}", 129 | }, 130 | }, 131 | 132 | { 133 | type: "divider", 134 | }, 135 | { 136 | label: "", 137 | asFormItem: true, 138 | children: ({ render }) => ( 139 |
140 |

组合现有组件

141 | 142 | {render( 143 | "formitem", 144 | [ 145 | { 146 | type: "input-text", 147 | name: "x", 148 | label: "X", 149 | value: "1", 150 | }, 151 | { 152 | type: "input-text", 153 | name: "y", 154 | label: "Y", 155 | }, 156 | ], 157 | { 158 | formMode: "normal", 159 | } 160 | )} 161 |
162 | ), 163 | }, 164 | { 165 | name: "c", 166 | label: "", 167 | asFormItem: true, 168 | component: ({ render, value, onChange, name }) => { 169 | function handleXChange(x) { 170 | value = { 171 | ...value, 172 | x, 173 | }; 174 | onChange(value); 175 | 176 | // 一定要 return false 177 | return false; 178 | } 179 | 180 | function handleYChange(y) { 181 | value = { 182 | ...value, 183 | y, 184 | }; 185 | onChange(value); 186 | 187 | // 一定要 return false 188 | return false; 189 | } 190 | 191 | return ( 192 |
193 |

组合现有组件并控制数据

194 | 195 | {render( 196 | "item1", 197 | { 198 | type: "input-text", 199 | name: "x", 200 | label: "X", 201 | }, 202 | { 203 | value: value?.x || "", 204 | onChange: handleXChange, 205 | } 206 | )} 207 | 208 | {render( 209 | "item2", 210 | { 211 | type: "input-text", 212 | name: "y", 213 | label: "Y", 214 | }, 215 | { 216 | value: value?.y || "", 217 | onChange: handleYChange, 218 | } 219 | )} 220 |
221 | ); 222 | }, 223 | }, 224 | ], 225 | }, 226 | 227 | { 228 | type: "my-renderer", 229 | tip: "放表单外的情况", 230 | }, 231 | ], 232 | }; 233 | -------------------------------------------------------------------------------- /src/components/Amis/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 196 | 200 | --------------------------------------------------------------------------------