snippets:vue

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
snippets:vue [2025/08/07 03:49] lingaosnippets:vue [2025/11/05 12:18] (current) – [tsx slots type] lingao
Line 1: Line 1:
 ==== tsx component best practice ==== ==== tsx component best practice ====
 bare bone bare bone
 +
 +<code tsx>
 +import { computed, defineComponent, defineProps, type PropType } from 'vue'
 +
 +type ModelType = __MODEL_TYPE__;
 +
 +export default defineComponent({
 +  props: {
 +    modelValue: {
 +      type: Object as PropType<ModelType>,
 +      default: () => ({} as ModelType),
 +    },
 +    'onUpdate:modelValue': {
 +      type: Function as PropType<(val: ModelType) => void>,
 +    },
 +  },
 +  setup(props) {
 +    const modelValue = computed({
 +      get() {
 +        return props.modelValue;
 +      },
 +      set(val: ModelType) {
 +        props['onUpdate:modelValue']?.(val);
 +      },
 +    });
 +
 +    return () => <></>;
 +  },
 +});
 +
 +</code>
 +
 <code tsx> <code tsx>
 import { defineComponent } from 'vue' import { defineComponent } from 'vue'
Line 17: Line 49:
 <code tsx> <code tsx>
 import { defineComponent } from 'vue' import { defineComponent } from 'vue'
-export interface Expose {} 
  
 export default defineComponent({ export default defineComponent({
Line 74: Line 105:
 import { ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElButton } from 'element-plus' import { ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElButton } from 'element-plus'
 import { defineComponent, onMounted, ref } from 'vue' import { defineComponent, onMounted, ref } from 'vue'
-import { useRoute } from 'vue-router'+import {ItemType} from './types'
  
-/******************** +type PaginationConfiguration = Pick<IResponsePage, 'total' | 'pageNum' | 'pageSize'> 
- * 类型定义 +type QueryParams = Partial<Pick<Item, never>> 
- ********************/ +type Item = ItemType
-interface QueryParams { +
-  personId: string +
-+
- +
-interface Item +
-  personId: string +
-  personName: string +
-  personPhone: string +
-  personAddress: string +
-}+
  
 export default defineComponent({ export default defineComponent({
-  name: 'DifficultHouseholdList', 
- 
   setup() {   setup() {
-    /******************** 
-     * 公共变量定义 
-     ********************/ 
     const loading = ref(false)     const loading = ref(false)
     const tableData = ref<Item[]>([])     const tableData = ref<Item[]>([])
-    const queryParams = ref<QueryParams>({ +    const queryParams = ref<QueryParams>({})
-      personId: '' +
-    })+
     const paginationConfig = ref<PaginationConfiguration>({     const paginationConfig = ref<PaginationConfiguration>({
       total: 0,       total: 0,
Line 107: Line 121:
       pageSize: 10       pageSize: 10
     })     })
-    const route = useRoute() 
-    const projectId = route.query.parentId as string 
- 
-    /******************** 
-     * 业务逻辑 
-     ********************/ 
- 
-    /** 
-     * 搜索表单初始化 
-     */ 
- 
-    /** 
-     * 表格初始化 
-     */ 
  
-    const handleQuerySearch () => {+    function handleQuerySearch() {
       getTableData()       getTableData()
     }     }
-    const handleQueryReset () => +    function handleQueryReset() { 
-      queryParams.value.personId ''+      queryParams.value = {}
       getTableData()       getTableData()
     }     }
-    const handleAdd () => {} +    function handleAdd() {} 
-    const handleEdit (row: Item) => {} +    // @ts-expect-error 
-    const handleDelete (row: Item) => {} +    function handleEdit(row: Item) {} 
-    const getTableData = async () => +    // @ts-expect-error 
-      const res = {} as any+    function handleDelete(row: Item) {} 
 + 
 +    async function getTableData() { 
 +      // @ts-expect-error 
 +      const res = { data: [{}] }
       loading.value = true       loading.value = true
       // paginationConfig.value.total =       // paginationConfig.value.total =
Line 139: Line 143:
     }     }
  
-    /******************** +    function handleKeydown(e: KeyboardEvent) { 
-     * 初始化 +      if (e.key === 'Enter') handleQuerySearch() 
-     ********************/+    }
  
     onMounted(() => {     onMounted(() => {
Line 158: Line 162:
                   clearable                   clearable
                   style="width: 200px"                   style="width: 200px"
-                  onKeydown={(e: KeyboardEvent) => { +                  onKeydown={handleKeydown}
-                    if (e.key === 'Enter') handleQuerySearch() +
-                  }}+
                 />                 />
               </ElFormItem>               </ElFormItem>
Line 179: Line 181:
               </div>               </div>
             </div>             </div>
-            <ElTable class="flex-1" v-loading={loading.value} data={tableData.value}>+            <ElTable class="flex-[1-1-0]" v-loading={loading.value} data={tableData.value}>
               <ElTableColumn width="60" type="selection" align="center" />               <ElTableColumn width="60" type="selection" align="center" />
               <ElTableColumn label="序号" width="60" type="index" align="center">               <ElTableColumn label="序号" width="60" type="index" align="center">
Line 198: Line 200:
               <ElTableColumn label="操作" align="center" width="100">               <ElTableColumn label="操作" align="center" width="100">
                 {(scope) => (                 {(scope) => (
-                  <div class="flex align-center justify-center">+                  <div class="flex align-center justify-center flex-wrap">
                     <ElButton                     <ElButton
                       link                       link
                       type="primary"                       type="primary"
-                      icon="ElIconEdit" 
                       onClick={() => handleEdit(scope.row)}                       onClick={() => handleEdit(scope.row)}
                     >                     >
Line 210: Line 211:
                       link                       link
                       type="danger"                       type="danger"
-                      icon="ElIconDelete" 
                       onClick={() => handleDelete(scope.row)}                       onClick={() => handleDelete(scope.row)}
                     >                     >
Line 235: Line 235:
 }) })
 </code> </code>
 +++++
  
 +==== tsx _form ====
 +
 +++++ tsx _form |
 +<code tsx>
 +import { computed, defineComponent, PropType } from 'vue'
 +import BaseCard from '@/components/BaseCard/Index'
 +import type { AssessmentObjective } from './types'
 +import { ElForm, ElFormItem } from 'element-plus'
 +
 +const rules = {}
 +
 +export default defineComponent({
 +  props: {
 +    modelValue: {
 +      type: Object as PropType<AssessmentObjective>,
 +      default: () => ({})
 +    }
 +  },
 +  emits: ['update:modelValue'],
 +  setup(props, { emit }) {
 +    const modelValue = computed({
 +      get() {
 +        return props.modelValue
 +      },
 +      set(val) {
 +        emit('update:modelValue', val)
 +      }
 +    })
 +
 +    return () => (
 +      <ElForm model={modelValue.value} rules={rules} class="flex flex-col gap-3">
 +        <BaseCard title="基础信息">
 +          <div class="grid grid-cols-2 gap-4">
 +            <ElFormItem label="企业名称" prop="companyName">
 +              <span>name</span>
 +            </ElFormItem>
 +          </div>
 +        </BaseCard>
 +      </ElForm>
 +    )
 +  }
 +})
 +</code>
 +++++
 +
 +==== tsx add ====
 +
 +++++ tsx add |
 +<code tsx>
 +import { defineComponent, ref } from 'vue'
 +import BaseContainer from '@/components/BaseContainer/BaseContainer.vue'
 +import Form from './_Form'
 +import { AssessmentObjective } from './types'
 +import { ElButton } from 'element-plus'
 +
 +export default defineComponent({
 +  setup() {
 +    const form = ref<AssessmentObjective>({})
 +
 +    function handleSubmit() {}
 +
 +    return () => (
 +      <BaseContainer fill back>
 +        {{
 +          default: () => <Form v-model={form.value} />,
 +          'header-options': () => (
 +            <ElButton type="primary" onClick={handleSubmit} icon="ElIconDocument">
 +              提交
 +            </ElButton>
 +          )
 +        }}
 +      </BaseContainer>
 +    )
 +  }
 +})
 +
 +</code>
 +++++
 +
 +==== tsx slots type ====
 +
 +++++ tsx slots type |
 +<codeprism tsx>
 +const Component = defineComponent({
 +  props: {
 +    config: {
 +      type: Array as PropType<EntityInfo[]>
 +    }
 +  },
 +  slots: Object as SlotsType<{
 +    default: ({ foo: string; bar: number }) => JSX.Element
 +  }>,
 +  setup: (props, { slots }) => {
 +    if (props.config == null) throw Error('Config can not be null')
 +    const context = createReferenceInstance(props.config)
 +    provide(refInjectionKey, context)
 +    return () => <>{slots.default && slots.default()}</>
 +  }
 +})
 +
 +const s = new Component().$slots
 +
 +const a = (
 +  <Component>
 +    {
 +      {
 +        default: (scope) => {
 +          scope
 +        }
 +      } as typeof s
 +    }
 +  </Component>
 +)
 +</codeprism>
 ++++ ++++
  • snippets/vue.1754538568.txt.gz
  • Last modified: 2025/08/07 03:49
  • by lingao