@grid-form/render-naive
Advanced tools
| <template> | ||
| <n-grid :x-gap="gridGap" :y-gap="gridGap" :cols="form.grid" :style="{width: form.width, margin:'0px auto' }"> | ||
| <template v-for="(item, index) in form.items" :key="index"> | ||
| <n-form-item-gi v-if="item._hide!=true" :span="item._col" :show-feedback="false" :show-label="!(item._hideLabel === true || !form.labelShow)" | ||
| :label-placement="labelPlacement" :label-align="labelAlign"> | ||
| <template #label> | ||
| {{item._text}}<span v-if="item._required" style="color: red;"> *</span> | ||
| </template> | ||
| <component v-if="item._container && item.items" :is="buildComponent(item, renders, false)"> | ||
| <render-container :gridGap="gridGap" :renders="renders" :form="item" :formData="formData" :labelPlacement="item.labelPlacement" :labelAlign="item.labelAlign" /> | ||
| </component> | ||
| <component v-else-if="item._widget=='DATE'" v-model:formatted-value="formData[item._uuid]" :is="buildComponent(item, renders, false)" /> | ||
| <component v-else v-model:value="formData[item._uuid]" :is="buildComponent(item, renders, false)" /> | ||
| </n-form-item-gi> | ||
| </template> | ||
| </n-grid> | ||
| </template> | ||
| <script> | ||
| export default { name:"render-container" } | ||
| </script> | ||
| <script setup> | ||
| import { ref } from 'vue' | ||
| import { RenderProps } from '@grid-form/common/render.mixin' | ||
| import { buildComponent } from '@grid-form/common' | ||
| const props = defineProps({ | ||
| renders:{type:Object}, | ||
| form: {type:Object}, | ||
| labelPlacement: {type:String, default:"left"}, | ||
| labelAlign:{type:String, default:"left"}, | ||
| gridGap: {type:Number, default: 10}, | ||
| formData: {type:Object} | ||
| }) | ||
| </script> |
+18
-5
| import { h } from 'vue' | ||
| import { NInput, NTag, NInputNumber, NDatePicker, NSwitch, NSelect, NText, NRadioGroup, NRadio, NRadioButton, NAlert, NDivider, NRate, NCheckboxGroup, NCheckbox, NColorPicker, NDynamicTags } from 'naive-ui' | ||
| import { | ||
| NInput, NTag, NInputNumber, NDatePicker, NSwitch, NSelect, NText, NRadioGroup, NRadio, | ||
| NRadioButton, NAlert, NDivider, NRate, NCheckboxGroup, NCheckbox, NColorPicker, NDynamicTags, | ||
| NCard, NButton | ||
| } from 'naive-ui' | ||
@@ -38,5 +42,10 @@ import { buildOptions } from '@grid-form/common' | ||
| }, | ||
| "BUTTON" : props=>{ | ||
| buildWidthFull(props) | ||
| if(props.tip) props.title = props.tip | ||
| return h(NButton, props, ()=> props.label) | ||
| }, | ||
| "SWITCH" : NSwitch, | ||
| "SELECT" : (props, attrs)=>{ | ||
| "SELECT" : (props)=>{ | ||
| props.options = buildOptions(props.options) | ||
@@ -51,3 +60,3 @@ return h(NSelect, props) | ||
| }, | ||
| "CHECKBOX" : (props, attrs)=>{ | ||
| "CHECKBOX" : (props)=>{ | ||
| let options = buildOptions(props.options) | ||
@@ -58,6 +67,7 @@ let ps = {} | ||
| return h(NCheckboxGroup, ps, ()=> options.map(o=> h(NCheckbox, {value: o.value, label:o.label}))) | ||
| return h(NCheckboxGroup, ps, ()=> options.map(o=> h(NCheckbox, o))) | ||
| }, | ||
| "DATE" : props=> { | ||
| buildWidthFull(props) | ||
| props['value-format'] = props.format | ||
| return h(NDatePicker, props) | ||
@@ -82,5 +92,8 @@ }, | ||
| "RATE" : NRate, | ||
| "COLOR" : (props, attrs)=>{ | ||
| "COLOR" : (props)=>{ | ||
| if(!!props.swatches) props.swatches = props.swatches.trim().split("\n") | ||
| return h(NColorPicker, props) | ||
| }, | ||
| "CARD" : (props)=>{ | ||
| return h(NCard, props) | ||
| } | ||
@@ -87,0 +100,0 @@ } |
+2
-2
| { | ||
| "name": "@grid-form/render-naive", | ||
| "version": "0.0.8", | ||
| "version": "0.1.0", | ||
| "description": "基于 naive-ui 的渲染器", | ||
@@ -15,3 +15,3 @@ "homepage": "https://github.com/0604hx/grid-form", | ||
| "dependencies": { | ||
| "@grid-form/common": "0.0.8" | ||
| "@grid-form/common": "0.1.0" | ||
| }, | ||
@@ -18,0 +18,0 @@ "devDependencies": { |
+10
-19
@@ -5,3 +5,3 @@ <template> | ||
| <slot name="tip"> | ||
| <div class="text-center"> | ||
| <div style="text-align: center;"> | ||
| <n-spin><template #description>表单渲染中...</template></n-spin> | ||
@@ -11,20 +11,10 @@ </div> | ||
| </template> | ||
| <n-form v-else :size="form.size||'medium'" :label-width="form.labelWidth" :label-placement="form.labelPlacement" :label-align="form.labelAlign" :show-label="form.labelShow"> | ||
| <n-form v-else :size="form.size||'medium'" :label-width="form.labelWidth" :show-label="form.labelShow"> | ||
| <n-message-provider> | ||
| <n-grid :x-gap="gridGap" :y-gap="gridGap" :cols="form.grid" :style="{width: form.width, margin:'0px auto' }"> | ||
| <template v-for="(item, index) in form.items" :key="index"> | ||
| <n-form-item-gi v-if="item._hide!=true" :span="item._col" :show-feedback="false"> | ||
| <template #label> | ||
| {{item._text}}<span v-if="item._required" style="color: red;"> *</span> | ||
| </template> | ||
| <component v-model:value="formData[item._uuid]" :is="buildComponent(item, renders[item._widget], false)" /> | ||
| </n-form-item-gi> | ||
| </template> | ||
| </n-grid> | ||
| <div class="text-center mt-4"> | ||
| <n-space justify="center"> | ||
| <n-button v-if="form.submitText" :disabled="formData._disabled" size="large" type="primary" @click="toSubmit">{{form.submitText}}</n-button> | ||
| <n-button v-for="btn in form.buttons" :type="btn.theme" size="large" @click="onExtraBtn(btn)">{{btn.text}} </n-button> | ||
| </n-space> | ||
| </div> | ||
| <Container :gridGap="gridGap" :renders="renders" :form="form" :formData="formData" :labelPlacement="form.labelPlacement" :labelAlign="form.labelAlign"/> | ||
| <n-space justify="center" style="margin-top: 12px;"> | ||
| <n-button v-if="form.submitText" :disabled="formData._disabled" size="large" type="primary" @click="toSubmit">{{form.submitText}}</n-button> | ||
| <n-button v-for="btn in form.buttons" :type="btn.theme" size="large" @click="onExtraBtn(btn)">{{btn.text}} </n-button> | ||
| </n-space> | ||
| </n-message-provider> | ||
@@ -38,5 +28,6 @@ </n-form> | ||
| import { buildComponent } from '@grid-form/common' | ||
| import { default as RenderMixin, RenderEvent, RenderProps } from '@grid-form/common/render.mixin' | ||
| import Container from './container.vue' | ||
| const emits = defineEmits(RenderEvent) | ||
@@ -43,0 +34,0 @@ const props = defineProps(RenderProps) |
@@ -10,2 +10,6 @@ <!--文件选择框--> | ||
| <script> | ||
| export default { inheritAttrs: false } | ||
| </script> | ||
| <script setup> | ||
@@ -15,2 +19,4 @@ import { ref } from 'vue' | ||
| import { selectFile } from '@grid-form/common' | ||
| const message = useMessage() | ||
@@ -29,4 +35,2 @@ | ||
| let maxFileSize = props.maxSize * 1024 * 1024 | ||
| let path = ref(props.value) | ||
@@ -42,30 +46,3 @@ | ||
| //使用原生 JS 选择文件 | ||
| let input = document.createElement("input") | ||
| input.type = 'file' | ||
| input.accept = props.accept | ||
| input.click() | ||
| input.onchange = e=>{ | ||
| let file = e.target.files[0] | ||
| if(!!file){ | ||
| if(file.size >= maxFileSize) return message.warning(`${file.name}超出大小限制(${props.maxSize} MB)`) | ||
| if(props.dataType!=""){ | ||
| let reader = new FileReader() | ||
| reader.onload = ee=>{ | ||
| let { readyState, result } = ee.target | ||
| selectDo(file.name, result) | ||
| } | ||
| if(props.dataType == 'base64') | ||
| reader.readAsDataURL(file) | ||
| else if(props.dataType === 'text') | ||
| reader.readAsText(file) | ||
| else | ||
| reader.readAsBinaryString(file) | ||
| } | ||
| else | ||
| selectDo(file.name, file) | ||
| } | ||
| } | ||
| selectFile(props).then(({name, result})=> selectDo(name, result)).catch(msg=> message.warning(msg)) | ||
| } | ||
@@ -72,0 +49,0 @@ |
8912
7.88%7
16.67%88
17.33%+ Added
- Removed
Updated