diff --git a/packages/vue-generator/test/testcases/data-binding/advanced.test.js b/packages/vue-generator/test/testcases/data-binding/advanced.test.js new file mode 100644 index 0000000000..ce2b53eb03 --- /dev/null +++ b/packages/vue-generator/test/testcases/data-binding/advanced.test.js @@ -0,0 +1,103 @@ +import { expect, test, describe } from 'vitest' +import path from 'path' +import fs from 'fs' +import { generateApp } from '@/generator/generateApp' +import { advancedDataBindingSchema } from './mockData' + +describe('Advanced Data Binding', () => { + test('should generate v-model for nested object bindings', async () => { + const instance = generateApp() + const res = await instance.generate(advancedDataBindingSchema) + const { genResult, errors } = res + + // 检查是否有错误 + expect(errors).toHaveLength(0) + + // 找到生成的 Vue 页面文件 + const vueFile = genResult.find((file) => file.fileName === 'AdvancedFormPage.vue') + expect(vueFile).toBeDefined() + + const content = vueFile.fileContent + + // 验证包含 v-model 绑定 + expect(content).toContain('v-model') + + // 验证嵌套对象数据绑定 + expect(content).toContain('v-model="state.formData.address.detail"') + expect(content).toContain('v-model="state.formData.address.zipCode"') + + // 验证基础字段绑定 + expect(content).toContain('v-model="state.formData.username"') + expect(content).toContain('v-model="state.formData.enabled"') + expect(content).toContain('v-model="state.formData.gender"') + expect(content).toContain('v-model="state.formData.remarks"') + expect(content).toContain('v-model="state.formData.category"') + + // 写入测试结果文件 + const outputDir = path.resolve(__dirname, './result/advanced') + fs.mkdirSync(outputDir, { recursive: true }) + + for (const { fileName, fileContent } of genResult) { + if (fileName.endsWith('.vue')) { + fs.writeFileSync(path.join(outputDir, fileName), fileContent) + } + } + }) + + test('should handle multiple component types with data binding', async () => { + const instance = generateApp() + const res = await instance.generate(advancedDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'AdvancedFormPage.vue') + const content = vueFile.fileContent + + // 统计 v-model 绑定数量 + const vModelMatches = content.match(/v-model[^=]*="[^"]+"/g) || [] + + // 应该有8个 v-model 绑定 + expect(vModelMatches).toHaveLength(8) + + // 验证所有组件类型都正确生成 + expect(content).toContain(' { + const instance = generateApp() + const res = await instance.generate(advancedDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'AdvancedFormPage.vue') + const content = vueFile.fileContent + + // 验证嵌套状态对象结构 + expect(content).toContain('formData: {') + expect(content).toContain('address: {') + expect(content).toContain("detail: ''") + expect(content).toContain("zipCode: ''") + + // 验证状态是响应式的 + expect(content).toContain('vue.reactive(') + }) + + test('should handle radio button groups correctly', async () => { + const instance = generateApp() + const res = await instance.generate(advancedDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'AdvancedFormPage.vue') + const content = vueFile.fileContent + + // 验证单选框组绑定到同一个字段 + const genderBindings = content.match(/v-model="state\.formData\.gender"/g) || [] + expect(genderBindings).toHaveLength(2) // 两个单选框绑定到同一字段 + + // 验证单选框的 value 属性 + expect(content).toContain('value="male"') + expect(content).toContain('value="female"') + }) +}) diff --git a/packages/vue-generator/test/testcases/data-binding/basic.test.js b/packages/vue-generator/test/testcases/data-binding/basic.test.js new file mode 100644 index 0000000000..f0d578fba5 --- /dev/null +++ b/packages/vue-generator/test/testcases/data-binding/basic.test.js @@ -0,0 +1,70 @@ +import { expect, test, describe } from 'vitest' +import path from 'path' +import fs from 'fs' +import { generateApp } from '@/generator/generateApp' +import { basicDataBindingSchema } from './mockData' + +describe('Basic Data Binding', () => { + test('should generate v-model for basic form components', async () => { + const instance = generateApp() + const res = await instance.generate(basicDataBindingSchema) + const { genResult, errors } = res + + // 检查是否有错误 + expect(errors).toHaveLength(0) + + // 找到生成的 Vue 页面文件 + const vueFile = genResult.find((file) => file.fileName === 'BasicDataBindingPage.vue') + expect(vueFile).toBeDefined() + + const content = vueFile.fileContent + + // 验证包含 v-model 绑定 + expect(content).toContain('v-model') + + // 验证具体的数据绑定 + expect(content).toContain('v-model="state.username"') + expect(content).toContain('v-model="state.role"') + expect(content).toContain('v-model="state.agreed"') + + // 验证组件正确渲染 + expect(content).toContain(' { + const instance = generateApp() + const res = await instance.generate(basicDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'BasicDataBindingPage.vue') + const content = vueFile.fileContent + + // 验证不同组件类型的 v-model 生成 + const vModelMatches = content.match(/v-model[^=]*="[^"]+"/g) || [] + + // 应该有3个 v-model 绑定 + expect(vModelMatches).toHaveLength(3) + + // 验证每个绑定都是正确的 + expect(vModelMatches).toContain('v-model="state.username"') + expect(vModelMatches).toContain('v-model="state.role"') + expect(vModelMatches).toContain('v-model="state.agreed"') + }) +}) diff --git a/packages/vue-generator/test/testcases/data-binding/edge-case.test.js b/packages/vue-generator/test/testcases/data-binding/edge-case.test.js new file mode 100644 index 0000000000..03c60e8af4 --- /dev/null +++ b/packages/vue-generator/test/testcases/data-binding/edge-case.test.js @@ -0,0 +1,122 @@ +import { expect, test, describe } from 'vitest' +import path from 'path' +import fs from 'fs' +import { generateApp } from '@/generator/generateApp' +import { edgeCaseDataBindingSchema } from './mockData' + +describe('Edge Case Data Binding Tests', () => { + test('should handle empty field gracefully', async () => { + const instance = generateApp() + const res = await instance.generate(edgeCaseDataBindingSchema) + const { genResult, errors } = res + + // 不应该因为空字段而报错 + expect(errors).toHaveLength(0) + + const vueFile = genResult.find((file) => file.fileName === 'EdgeCaseDataBindingPage.vue') + expect(vueFile).toBeDefined() + + const content = vueFile.fileContent + + // 空字段应该不生成v-model或生成空的v-model + // 确保不会导致语法错误 + expect(content).not.toContain('v-model=""') + expect(content).not.toContain('v-model="undefined"') + }) + + test('should remove this. prefix correctly', async () => { + const instance = generateApp() + const res = await instance.generate(edgeCaseDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'EdgeCaseDataBindingPage.vue') + const content = vueFile.fileContent + + // 应该移除this.前缀 + expect(content).toContain('v-model="state.withThis"') + expect(content).not.toContain('v-model="this.state.withThis"') + }) + + test('should handle deep nested field paths', async () => { + const instance = generateApp() + const res = await instance.generate(edgeCaseDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'EdgeCaseDataBindingPage.vue') + const content = vueFile.fileContent + + // 深层嵌套路径应该正确处理 + expect(content).toContain('v-model="state.level1.level2.level3.deepField"') + + // 验证状态结构正确生成 + expect(content).toContain('level1: {') + expect(content).toContain('level2: {') + expect(content).toContain('level3: {') + expect(content).toContain("deepField: ''") + }) + + test('should maintain correct state structure for nested objects', async () => { + const instance = generateApp() + const res = await instance.generate(edgeCaseDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'EdgeCaseDataBindingPage.vue') + const content = vueFile.fileContent + + // 验证响应式状态结构 + expect(content).toContain('vue.reactive(') + expect(content).toContain("noComponentType: ''") + expect(content).toContain("withThis: ''") + + // 写入测试结果 + const outputDir = path.resolve(__dirname, './result/edge-case') + fs.mkdirSync(outputDir, { recursive: true }) + + for (const { fileName, fileContent } of genResult) { + if (fileName.endsWith('.vue')) { + fs.writeFileSync(path.join(outputDir, fileName), fileContent) + } + } + }) + + test('should handle null and undefined values in JSDataBinding', async () => { + // 创建包含null/undefined值的特殊schema + const nullValueSchema = { + ...edgeCaseDataBindingSchema, + pageSchema: [ + { + ...edgeCaseDataBindingSchema.pageSchema[0], + children: [ + { + componentName: 'TinyInput', + props: { + modelValue: { + type: 'JSDataBinding', + value: null // null值 + } + } + }, + { + componentName: 'TinyInput', + props: { + modelValue: { + type: 'JSDataBinding', + value: undefined // undefined值 + } + } + } + ] + } + ] + } + + const instance = generateApp() + const res = await instance.generate(nullValueSchema) + + // 不应该因为null/undefined而抛出异常 + expect(res.errors).toHaveLength(0) + + const vueFile = res.genResult.find((file) => file.fileName === 'EdgeCaseDataBindingPage.vue') + expect(vueFile).toBeDefined() + }) +}) diff --git a/packages/vue-generator/test/testcases/data-binding/form.test.js b/packages/vue-generator/test/testcases/data-binding/form.test.js new file mode 100644 index 0000000000..a428a180ff --- /dev/null +++ b/packages/vue-generator/test/testcases/data-binding/form.test.js @@ -0,0 +1,140 @@ +import { expect, test, describe } from 'vitest' +import path from 'path' +import fs from 'fs' +import { generateApp } from '@/generator/generateApp' +import { complexFormDataBindingSchema } from './mockData' + +describe('Complex Form Data Binding Tests', () => { + test('should handle nested form sections with data binding', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult, errors } = res + + expect(errors).toHaveLength(0) + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + expect(vueFile).toBeDefined() + + const content = vueFile.fileContent + + // 验证嵌套表单数据绑定 + expect(content).toContain('v-model="state.user.profile.name"') + expect(content).toContain('v-model="state.user.profile.email"') + expect(content).toContain('v-model="state.user.preferences.language"') + expect(content).toContain('v-model="state.user.preferences.emailNotifications"') + }) + + test('should generate correct nested state structure', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 验证复杂嵌套状态结构 + expect(content).toContain('user: {') + expect(content).toContain('profile: {') + expect(content).toContain("name: ''") + expect(content).toContain("email: ''") + expect(content).toContain('preferences: {') + expect(content).toContain("language: ''") + expect(content).toContain('emailNotifications: false') + }) + + test('should handle multiple component types in complex form', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 验证不同组件类型 + expect(content).toContain(' { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 验证HTML结构和样式类 + expect(content).toContain('
') + expect(content).toContain('class="user-section"') + expect(content).toContain('class="preferences-section"') + + // 验证嵌套div结构 + expect(content).toMatch(/]*class="user-section"[^>]*>[\s\S]*/) + }) + + test('should count correct number of v-model bindings', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 统计v-model数量 + const vModelMatches = content.match(/v-model[^=]*="[^"]+"/g) || [] + expect(vModelMatches).toHaveLength(4) // 4个表单字段 + + // 验证每个绑定都是唯一的 + const uniqueBindings = new Set(vModelMatches) + expect(uniqueBindings.size).toBe(4) + }) + + test('should handle different input types correctly', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 验证不同输入类型的处理 + expect(content).toContain('placeholder="姓名"') + expect(content).toContain('placeholder="邮箱"') + expect(content).toContain('placeholder="语言偏好"') + + // 验证email类型特殊处理 + expect(content).toContain('type="email"') + + // 写入测试结果 + const outputDir = path.resolve(__dirname, './result/complex-form') + fs.mkdirSync(outputDir, { recursive: true }) + + for (const { fileName, fileContent } of genResult) { + if (fileName.endsWith('.vue')) { + fs.writeFileSync(path.join(outputDir, fileName), fileContent) + } + } + }) + + test('should generate proper component imports', async () => { + const instance = generateApp() + const res = await instance.generate(complexFormDataBindingSchema) + const { genResult } = res + + const vueFile = genResult.find((file) => file.fileName === 'ComplexFormPage.vue') + const content = vueFile.fileContent + + // 验证组件导入 + expect(content).toContain( + "import { Input as TinyInput, Select as TinySelect, Checkbox as TinyCheckbox } from '@opentiny/vue'" + ) + + // 验证Vue导入 + expect(content).toContain("import * as vue from 'vue'") + }) +}) diff --git a/packages/vue-generator/test/testcases/data-binding/mockData.js b/packages/vue-generator/test/testcases/data-binding/mockData.js new file mode 100644 index 0000000000..c5425a1a42 --- /dev/null +++ b/packages/vue-generator/test/testcases/data-binding/mockData.js @@ -0,0 +1,451 @@ +/** + * 数据绑定功能测试的模拟数据 + */ + +// 基础数据绑定测试 Schema +export const basicDataBindingSchema = { + meta: { + name: 'BasicDataBindingTest', + description: 'Test basic data binding functionality' + }, + componentsMap: [ + { + componentName: 'TinyInput', + exportName: 'Input', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinySelect', + exportName: 'Select', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + } + ], + pageSchema: [ + { + componentName: 'div', + fileName: 'BasicDataBindingPage', + meta: { + id: 'basic-page', + isPage: true, + parentId: '0', + router: '/basic-data-binding' + }, + props: { + class: 'test-container' + }, + children: [ + { + componentName: 'TinyInput', + props: { + placeholder: '请输入用户名', + // 测试数据绑定 - 输入框绑定到用户名字段 + modelValue: { + type: 'JSExpression', + value: 'state.username', + model: true + } + } + }, + { + componentName: 'TinySelect', + props: { + placeholder: '请选择角色', + // 测试数据绑定 - 选择框绑定到角色字段 + modelValue: { + type: 'JSExpression', + value: 'state.role', + model: true + } + } + }, + { + componentName: 'input', + props: { + type: 'checkbox', + // 测试原生checkbox的数据绑定 + checked: { + type: 'JSExpression', + value: 'state.agreed', + model: true + } + } + } + ], + state: { + username: '', + role: '', + agreed: false + } + } + ], + blockSchema: [], + globalState: [], + dataSource: { list: [] }, + utils: [] +} + +// 高级数据绑定测试 Schema +export const advancedDataBindingSchema = { + meta: { + name: 'AdvancedDataBindingTest', + description: 'Test advanced data binding functionality with nested objects' + }, + componentsMap: [ + { + componentName: 'TinyInput', + exportName: 'Input', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinySelect', + exportName: 'Select', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinySwitch', + exportName: 'Switch', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinyRadio', + exportName: 'Radio', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + } + ], + pageSchema: [ + { + componentName: 'div', + fileName: 'AdvancedFormPage', + meta: { + id: 'advanced-page', + isPage: true, + parentId: '0', + router: '/advanced-form' + }, + props: { + class: 'advanced-form-container' + }, + children: [ + { + componentName: 'TinyInput', + props: { + placeholder: '请输入用户名', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.username' + } + } + }, + { + componentName: 'TinySwitch', + props: { + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.enabled' + } + } + }, + { + componentName: 'TinyRadio', + props: { + value: 'male', + checked: { + type: 'JSExpression', + model: true, + value: 'state.formData.gender' + } + } + }, + { + componentName: 'TinyRadio', + props: { + value: 'female', + checked: { + type: 'JSExpression', + model: true, + value: 'state.formData.gender' + } + } + }, + { + componentName: 'textarea', + props: { + placeholder: '请输入备注', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.remarks' + } + } + }, + { + componentName: 'select', + props: { + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.category' + } + } + }, + { + componentName: 'TinyInput', + props: { + placeholder: '详细地址', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.address.detail' + } + } + }, + { + componentName: 'TinyInput', + props: { + placeholder: '邮政编码', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.formData.address.zipCode' + } + } + } + ], + state: { + formData: { + username: '', + enabled: false, + gender: '', + remarks: '', + category: '', + address: { + detail: '', + zipCode: '' + } + } + } + } + ], + blockSchema: [], + globalState: [], + dataSource: { list: [] }, + utils: [] +} + +// 边界条件测试 Schema +export const edgeCaseDataBindingSchema = { + meta: { + name: 'EdgeCaseDataBindingTest', + description: 'Test edge cases and error handling for data binding' + }, + componentsMap: [ + { + componentName: 'TinyInput', + exportName: 'Input', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + } + ], + pageSchema: [ + { + componentName: 'div', + fileName: 'EdgeCaseDataBindingPage', + meta: { + id: 'edge-case-page', + isPage: true, + parentId: '0', + router: '/edge-case-data-binding' + }, + props: { + class: 'edge-case-container' + }, + children: [ + { + componentName: 'TinyInput', + props: { + placeholder: '空字段测试', + modelValue: { + type: 'JSExpression', + value: '' // 空字段 + } + } + }, + { + componentName: 'TinyInput', + props: { + placeholder: 'this前缀清理', + modelValue: { + type: 'JSExpression', + model: true, + value: 'this.state.withThis' + } + } + }, + { + componentName: 'TinyInput', + props: { + placeholder: '深层嵌套', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.level1.level2.level3.deepField' + } + } + } + ], + state: { + noComponentType: '', + withThis: '', + level1: { + level2: { + level3: { + deepField: '' + } + } + } + } + } + ], + blockSchema: [], + globalState: [], + dataSource: { list: [] }, + utils: [] +} + +// 复杂表单测试 Schema +export const complexFormDataBindingSchema = { + meta: { + name: 'ComplexFormDataBindingTest', + description: 'Test complex form with multiple data binding scenarios' + }, + componentsMap: [ + { + componentName: 'TinyInput', + exportName: 'Input', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinySelect', + exportName: 'Select', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + }, + { + componentName: 'TinyCheckbox', + exportName: 'Checkbox', + package: '@opentiny/vue', + version: '^3.10.0', + destructuring: true + } + ], + pageSchema: [ + { + componentName: 'form', + fileName: 'ComplexFormPage', + meta: { + id: 'complex-form-page', + isPage: true, + parentId: '0', + router: '/complex-form' + }, + props: { + class: 'complex-form' + }, + children: [ + // 用户信息部分 + { + componentName: 'div', + props: { class: 'user-section' }, + children: [ + { + componentName: 'TinyInput', + props: { + placeholder: '姓名', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.user.profile.name' + } + } + }, + { + componentName: 'TinyInput', + props: { + type: 'email', + placeholder: '邮箱', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.user.profile.email' + } + } + } + ] + }, + // 偏好设置部分 + { + componentName: 'div', + props: { class: 'preferences-section' }, + children: [ + { + componentName: 'TinySelect', + props: { + placeholder: '语言偏好', + modelValue: { + type: 'JSExpression', + model: true, + value: 'state.user.preferences.language' + } + } + }, + { + componentName: 'TinyCheckbox', + props: { + label: '接收邮件通知', + checked: { + type: 'JSExpression', + model: true, + value: 'state.user.preferences.emailNotifications' + } + } + } + ] + } + ], + state: { + user: { + profile: { + name: '', + email: '' + }, + preferences: { + language: '', + emailNotifications: false + } + } + } + } + ], + blockSchema: [], + globalState: [], + dataSource: { list: [] }, + utils: [] +} diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/package.json b/packages/vue-generator/test/testcases/generator/expected/appdemo01/package.json index a404389d7b..6f3161e7ca 100644 --- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/package.json +++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/package.json @@ -11,8 +11,8 @@ "module": "dist/index.js", "dependencies": { "@opentiny/tiny-engine-i18n-host": "^1.0.0", - "@opentiny/vue": "0.1.16", - "@opentiny/vue-icon": "0.1.16", + "@opentiny/vue": "3.24.0", + "@opentiny/vue-icon": "3.24.0", "axios": "latest", "axios-mock-adapter": "^1.19.0", "vue": "^3.3.9", diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/router/index.js b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/router/index.js index 53ad88c6ec..70c3c74f30 100644 --- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/router/index.js +++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/router/index.js @@ -28,6 +28,12 @@ const routes = [ name: '3sV9KkvL3SuQIufS' } }, + { + name: 'lifecycle-page', + path: 'lifecycle', + component: () => import('@/views/LifeCyclePage.vue'), + children: [] + }, { name: '1737797330916', path: 'testCanvasRowCol', diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/LifeCyclePage.vue b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/LifeCyclePage.vue new file mode 100644 index 0000000000..fddf898275 --- /dev/null +++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/LifeCyclePage.vue @@ -0,0 +1,100 @@ + + + + diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/createVm.vue b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/createVm.vue index 57881bbb7a..7fae2266cb 100644 --- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/createVm.vue +++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/views/createVm.vue @@ -55,7 +55,7 @@ > vCPUs 内存 - 规格名称 - + 规格名称 +
@@ -212,18 +212,18 @@ >
- + GiB IOPS上限240,IOPS突发上限5,000
- + GiB IOPS上限600,IOPS突发上限5,000 - +
@@ -340,7 +348,11 @@ 购买量 - + @@ -384,7 +396,8 @@ import { Form as TinyForm, Grid as TinyGrid, Select as TinySelect, - ButtonGroup as TinyButtonGroup + ButtonGroup as TinyButtonGroup, + Button as TinyButton } from '@opentiny/vue' import { IconPanelMini, IconPlus } from '@opentiny/vue-icon' import * as vue from 'vue' @@ -400,7 +413,24 @@ const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode() const wrap = lowcodeWrap(props, { emit }) wrap({ stores }) -const state = vue.reactive({ dataDisk: [1, 2, 3] }) +const state = vue.reactive({ + dataDisk: [1, 2, 3], + formData: { + zone: '1', + cpu: '1', + memory: '1', + storageType: '1', + storageSize: '40', + diskType: '1', + diskSize: '100', + networkType: '1', + bandwidth: '1', + instanceType: '1', + instanceCount: '1' + }, + inputValues: { diskLabel: '', systemDisk: '', dataDiskSize: '', networkConfig: '' }, + selectValues: { availableZone: '1', cpuArch: '1', memorySize: '1', storageOption: '1', networkOption: '1' } +}) wrap({ state })