console
Vue.createApp({
setup() {
return {
model: {},
fields: [{
component: 'van-nav-bar',
props: { title: '标题' }
}, {
component: 'van-cell-group',
props: {
title: '基本用法'
},
children: [{
component: 'van-form',
children: [{
component: 'van-field',
model: 'model.name',
props: {
label: "用户名"
}
}, {
component: 'van-field',
model: 'model.pwd',
props: {
label: "密码",
type: "password"
}
}]
}]
}, {
component: 'van-cell-group',
props: {
title: '表单项类型'
},
children: [{
component: 'van-form',
children: [{
component: 'van-checkbox',
model: 'model.checked',
fieldProps: {
label: 'check'
},
props: {
shape: 'square'
}
}, {
component: 'van-switch',
model: 'model.opened',
fieldProps: {
label: 'switch'
},
props: { size: '20' }
}, {
component: 'van-checkbox-group',
condition: '$:!!model.opened',
model: 'model.checks',
fieldProps: {
label: '复选框组'
},
props: {
direction: 'horizontal'
},
checkItems: [
{ value: 1, label: '选项1' },
{ value: 2, label: '选项2' }
]
}]
}]
}]
}
},
methods: {
// prerender 自定义渲染钩子
onSetup({ prerender }) {
// 组件外加上一层 van-field
prerender(({ proxy, context }) => (field, next) => {
if (!field.fieldProps) {
next(field)
return
}
const fieldProps = field.fieldProps
field.slot = 'input'
delete field.fieldProps
next(proxy.inject({
component: 'van-field',
// 因为 field 是代理对象,所以要获取代理对象定义之后获取属性值表达式
condition: JRenderCore.getProxyDefine(field).condition,
props: fieldProps,
children: [field]
}, context))
})
// 根据 checkItems 属性生成选项
prerender(({ context }) => (field, next) => {
if (!field.checkItems) {
next(field)
return
}
field.children = field.checkItems.map(item => ({
component: 'van-checkbox',
props: {
shape: 'square',
name: item.value
},
children: [{
component: 'span',
text: item.label
}]
}))
next(field)
})
}
}
})
.use(vant)
.use(JRenderFull)
.mount('#app')
<html>
<head>
<meta name="viewport" content="width=device-width,intial-scale=1,user-scalable=no">
<title>Json to render</title>
<script src="https://cdn.jsdelivr.net/npm/vue@next/dist/vue.global.prod.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/vant@next/lib/vant.min.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/@json2render/vue-full">
</script>
<script src="https://cdn.jsdelivr.net/npm/@json2render/core">
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@next/lib/index.css" />
</head>
<body>
<div id="app">
<v-jrender class="container" v-model="model" :fields="fields" @setup="onSetup"></v-jrender>
</div>
</body>
</html>
#app {
display: flex;
justify-content: center;
}
#app>.container {
width: 100%
}
@media screen and (min-width: 520px) {
#app>.container {
width: 360px;
border-radius: 20px;
background: #fafafa;
box-shadow: rgb(235, 237, 240) 0px 8px;
padding-top: 20px;
padding-bottom: 20px;
}
}