浏览代码

data props

Alsmile 2 年之前
父节点
当前提交
9cc66d8e82
共有 6 个文件被更改,包括 293 次插入36 次删除
  1. 1 1
      src/services/defaults.ts
  2. 39 6
      src/styles/props.css
  3. 11 7
      src/styles/tdesign.css
  4. 2 1
      src/styles/var.css
  5. 236 17
      src/views/components/PenDatas.vue
  6. 4 4
      src/views/components/PenProps.vue

+ 1 - 1
src/services/defaults.ts

@@ -242,7 +242,7 @@ export const shapeLib = [
             {
               key: 'text',
               type: 'text',
-              name: '文',
+              name: '文',
             },
           ] as FormItemType[],
         },

+ 39 - 6
src/styles/props.css

@@ -54,13 +54,21 @@
       .t-input__inner {
         text-overflow: unset;
         &::placeholder {
-          color: var(--color-desc);
+          color: var(--color-gray);
         }
       }
       &:hover,
       &.t-is-focused {
         border-color: var(--color-border-input);
       }
+
+      &.t-is-disabled {
+        border-color: var(--color-border-input) !important;
+
+        .t-input__inner {
+          color: var(--color-desc);
+        }
+      }
     }
 
     & > input {
@@ -70,7 +78,7 @@
       color: var(--color-desc);
 
       &::placeholder {
-        color: var(--color-desc);
+        color: var(--color-gray);
       }
     }
 
@@ -89,6 +97,17 @@
     }
   }
 
+  .t-dialog {
+    .form-item {
+      .t-input {
+        border-color: var(--color-border-input);
+        &:hover {
+          border-color: var(--color-primary);
+        }
+      }
+    }
+  }
+
   .t-collapse.t--border-less {
     .t-collapse-panel__header {
       font-size: 13px;
@@ -139,15 +158,29 @@
     height: 24px;
     border-color: var(--color-desc);
 
-    &.t-button--theme-primary {
-      border-color: var(--color-primary);
-    }
-
     &:hover {
       border-color: var(--color-primary);
       color: var(--color-primary);
     }
 
+    &.t-button--variant-base {
+      border-color: var(--td-bg-color-component);
+      &:hover {
+        color: var(--color);
+        border-color: var(--color-border-input-hover);
+        background-color: var(--color-border-input-hover);
+      }
+
+      &.t-button--theme-primary {
+        border-color: var(--color-primary);
+        &:hover {
+          color: var(--color);
+          border-color: var(--color-primary-hover);
+          background-color: var(--color-primary-hover);
+        }
+      }
+    }
+
     &.icon {
       border-color: transparent;
       padding: 0;

+ 11 - 7
src/styles/tdesign.css

@@ -123,6 +123,13 @@
         }
       }
     }
+
+    &.t-dropdown__item--disabled {
+      .t-dropdown__item-text {
+        background-color: var(--color-background-popup) !important;
+        color: var(--color-desc);
+      }
+    }
   }
 
   .t-divider {
@@ -454,12 +461,9 @@
 }
 
 .t-dialog {
-  label {
-    font-size: 10px;
-    background-color: #ff400030;
-    color: var(--color-bland);
-    padding: 0 6px;
-    margin-left: 4px;
-    border-radius: 2px;
+  padding: 16px 20px;
+
+  .t-dialog__header {
+    font-size: 14px;
   }
 }

+ 2 - 1
src/styles/var.css

@@ -13,7 +13,7 @@
   --color-bland-hover: #fa541c;
 
   --color-primary: #4583ff;
-  --color-primary-hover: #1677ff;
+  --color-primary-hover: #0c56eb;
   --color-primary-disabled: #bae7ff;
   --color-success: #52c41a;
   --color-success-hover: #3fad09;
@@ -36,6 +36,7 @@
   --color-border: #000000;
   --color-sub-border: #f7f7f7;
   --color-border-input: #535f79;
+  --color-border-input-hover: #454f64;
 
   --color-scrollbar: #dad7d7;
   --color-scrollbar-hover: #e5e5e5;

+ 236 - 17
src/views/components/PenDatas.vue

@@ -1,18 +1,44 @@
 <template>
   <div class="props">
-    <div class="grid px-16 py-12" v-if="pen.realTimes">
-      <div class="title">数据名称</div>
-      <div class="title">值</div>
-      <div>
+    <div class="px-16 py-16" v-if="pen.realTimes && pen.realTimes.length">
+      <div class="grid" style="line-height: 30px">
+        <div class="title">数据名</div>
+        <div class="title ml-8">值</div>
+        <div>
+          <div style="text-align: right; padding-right: 2px">
+            <t-icon name="more" />
+          </div>
+        </div>
+      </div>
+      <div class="grid" v-for="(item, i) in pen.realTimes">
+        <t-tooltip :content="item.key" placement="top">
+          <label class="label">{{ item.label }}</label>
+        </t-tooltip>
+        <div class="value">
+          <t-input v-model="item.value" />
+        </div>
+        <div class="actions">
+          <t-tooltip content="数据绑定" placement="top">
+            <t-icon name="link" class="hover" style="visibility: visible" />
+          </t-tooltip>
+          <t-dropdown
+            :options="moreOptions"
+            @click="onMenuMore($event, item, i)"
+            :minColumnWidth="80"
+          >
+            <t-icon name="more" class="more hover" />
+          </t-dropdown>
+        </div>
+      </div>
+      <div class="mt-8">
         <t-dropdown
           :options="options"
-          @click="addRealTime(i, $event)"
+          @click="addRealTime"
           :minColumnWidth="150"
         >
-          <t-icon name="add-circle" class="hover ml-4" />
+          <a> <t-icon name="add-rectangle" /> 添加动态数据 </a>
         </t-dropdown>
       </div>
-      <template v-for="item in pen.realTimes"> </template>
     </div>
     <div class="flex column center blank" v-else>
       <img src="/img/blank.png" />
@@ -20,84 +46,252 @@
       <div class="mt-8">
         <t-dropdown
           :options="options"
-          @click="addRealTime(i, $event)"
+          @click="addRealTime"
           :minColumnWidth="150"
-          trigger="click"
         >
           <t-button style="height: 30px"> 添加动态数据 </t-button>
         </t-dropdown>
       </div>
     </div>
   </div>
+
+  <t-dialog
+    v-if="addDataDialog.show"
+    :visible="true"
+    class="data-dialog"
+    :header="addDataDialog.header"
+    @close="addDataDialog.show = false"
+    @confirm="onConfirmData"
+  >
+    <div class="form-item mt-16">
+      <label>数据名</label>
+      <t-input
+        v-model="addDataDialog.data.label"
+        placeholder="简短描述"
+        :disabled="!!addDataDialog.data.keywords"
+        @blur="onChangeLabel"
+      />
+    </div>
+    <div class="form-item mt-16">
+      <label>属性名</label>
+      <t-input
+        v-model="addDataDialog.data.key"
+        placeholder="关键字"
+        :disabled="!!addDataDialog.data.keywords"
+      />
+    </div>
+    <div class="form-item mt-16">
+      <label>类型</label>
+      <t-select
+        class="w-full"
+        :options="typeOptions"
+        v-model="addDataDialog.data.type"
+        placeholder="字符串"
+        :disabled="!!addDataDialog.data.keywords"
+        @change="addDataDialog.data.value = null"
+      />
+    </div>
+    <div class="form-item mt-16">
+      <label>值</label>
+      <div class="flex-grow" v-if="addDataDialog.data.type === 'number'">
+        <t-input
+          class="w-full"
+          v-model="addDataDialog.data.value"
+          placeholder="数字"
+        />
+        <div class="desc mt-8">
+          固定数字:直接输入数字。例如:5<br />
+          随机范围数字:最小值-最大值。例如:0-1 或 0-100<br />
+          随机指定数字:数字1,数字2,数字3... 。 例如:1,5,10,20<br />
+        </div>
+      </div>
+      <t-select
+        v-else-if="addDataDialog.data.type === 'bool'"
+        v-model="addDataDialog.data.value"
+      >
+        <t-option :key="true" :value="true" label="true"></t-option>
+        <t-option :key="false" :value="false" label="false"></t-option>
+        <t-option key="随机" label="随机"></t-option>
+      </t-select>
+      <div class="flex-grow" v-else>
+        <t-input
+          class="w-full"
+          v-model="addDataDialog.data.value"
+          placeholder="字符串"
+        />
+        <div class="desc mt-8">
+          固定文字:直接输入。例如:大屏可视化<br />
+          随机文本:[文本长度]。例如:[8] 或 [16]<br />
+          随机指定文本:{文本1,文本2,文本3...} 。 例如:{大屏,可视化}
+          <br />
+        </div>
+      </div>
+    </div>
+  </t-dialog>
 </template>
 
 <script lang="ts" setup>
 import { onBeforeMount, reactive, ref } from 'vue';
 
+import { MessagePlugin } from 'tdesign-vue-next';
+
 const { pen } = defineProps<{
   pen: any;
 }>();
 
 const options: any[] = ref([
+  {
+    value: '',
+    content: '自定义',
+    divider: true,
+  },
   {
     value: 'x',
-    content: 'X坐标',
+    content: 'X',
     type: 'number',
+    keywords: true,
   },
   {
     value: 'y',
-    content: 'Y坐标',
+    content: 'Y',
     type: 'number',
+    keywords: true,
   },
   {
     value: 'width',
     content: '宽',
     type: 'number',
+    keywords: true,
   },
   {
     value: 'height',
     content: '高',
     type: 'number',
+    keywords: true,
   },
   {
     value: 'visible',
     content: '显示',
     type: 'bool',
+    keywords: true,
   },
   {
     value: 'text',
     content: '文字',
+    keywords: true,
   },
   {
     value: 'progress',
     content: '进度',
+    keywords: true,
   },
   {
     value: 'showChild',
     content: '状态',
+    keywords: true,
   },
   {
     value: 'rotate',
     content: '旋转',
     type: 'number',
-    divider: true,
+    keywords: true,
+  },
+]);
+
+const moreOptions: any[] = ref([
+  {
+    value: 'edit',
+    content: '编辑',
+  },
+  {
+    value: 'delete',
+    content: '移除',
   },
 ]);
 
+const typeOptions = [
+  {
+    label: '字符串',
+  },
+  {
+    label: '数字',
+    value: 'number',
+  },
+  {
+    label: '布尔',
+    value: 'bool',
+  },
+];
+
+const addDataDialog = reactive({
+  show: false,
+  data: undefined,
+});
+
 onBeforeMount(() => {
   if (pen.realTimesOptions) {
+    options.value[options.value.length - 1].divider = true;
     options.value.push(...pen.realTimesOptions);
   }
-  options.value[options.value.length - 1].divider = true;
-  options.value.push({ content: '自定义', value: '' });
 });
 
-const addRealTime = () => {
+const addRealTime = (e: any) => {
+  addDataDialog.header = '添加动态数据';
+
+  addDataDialog.data = {
+    label: e.content,
+    key: e.value,
+    type: e.type,
+    keywords: e.keywords,
+  };
+  if (!e.keywords) {
+    addDataDialog.data.label = '';
+  }
+  addDataDialog.show = true;
+};
+
+const onChangeLabel = () => {
+  if (!addDataDialog.data.key) {
+    addDataDialog.data.key = addDataDialog.data.label;
+  }
+};
+
+const onConfirmData = () => {
   if (!pen.realTimes) {
     pen.realTimes = [];
   }
+  if (!addDataDialog.data.label || !addDataDialog.data.key) {
+    MessagePlugin.error('数据名或属性名不能为空!');
+    return;
+  }
+
+  if (addDataDialog.header === '添加动态数据') {
+    const found = pen.realTimes.findIndex((item) => {
+      return item.key === addDataDialog.data.key;
+    });
+    if (found > -1) {
+      MessagePlugin.error('已经存在相同属性数据!');
+      return;
+    }
+    pen.realTimes.push(addDataDialog.data);
+  }
+
+  addDataDialog.show = false;
+};
 
-  pen.realTimes.push({});
+const onMenuMore = (e: any, item: any, i: number) => {
+  switch (e.value) {
+    case 'edit':
+      addDataDialog.header = '编辑动态数据';
+      addDataDialog.data = item;
+      addDataDialog.show = true;
+      break;
+    case 'delete':
+      pen.realTimes.splice(i, 1);
+      break;
+    default:
+      break;
+  }
 };
 </script>
 <style lang="postcss" scoped>
@@ -105,7 +299,7 @@ const addRealTime = () => {
   height: 100%;
 
   .grid {
-    grid-template-columns: 1fr 1fr 30px;
+    grid-template-columns: 80px 154px 40px;
   }
 
   .blank {
@@ -115,5 +309,30 @@ const addRealTime = () => {
       opacity: 0.9;
     }
   }
+
+  .label {
+    width: fit-content;
+    font-size: 10px;
+    line-height: 28px;
+    color: var(--color-desc);
+  }
+
+  .value {
+    padding-right: 8px;
+
+    :deep(.t-input) {
+      height: 26px;
+      border-color: transparent;
+      &:hover {
+        border-color: var(--color-primary);
+      }
+    }
+  }
+
+  .actions {
+    svg {
+      margin-left: 6px;
+    }
+  }
 }
 </style>

+ 4 - 4
src/views/components/PenProps.vue

@@ -44,7 +44,7 @@
             <t-input
               class="ml-4"
               label="X"
-              placeholder="x坐标"
+              placeholder="X"
               v-model.number="data.rect.x"
               style="width: 80px"
               :format="decimalPlaces"
@@ -54,7 +54,7 @@
             <t-input
               class="ml-4"
               label="Y"
-              placeholder="y坐标"
+              placeholder="Y"
               v-model.number="data.rect.y"
               style="width: 80px"
               :format="decimalPlaces"
@@ -1040,7 +1040,7 @@ onBeforeMount(() => {
   // 测试代码
   data.pen.props.custom = [
     { label: '数字', key: 'a', type: 'number', placeholder: '输入提示' },
-    { label: '文', key: 'b' },
+    { label: '文', key: 'b' },
     { label: '布尔', key: 'c', type: 'bool', placeholder: '输入提示' },
     { label: '颜色', key: 'd', type: 'color', placeholder: '输入提示' },
     {
@@ -1171,7 +1171,7 @@ const titleOptions: monacoOption[] = [
   {
     key: 'title',
     value: 0,
-    name: '文',
+    name: '文',
     tip: '支持markdown',
     code: '',
     language: 'markdown',