Vue3+TS combinado con diseño de hormigas para realizar una página de lista simple y una página de detalles

Cuando estaba trabajando en un proyecto recientemente, debido a que tenía más contacto con la página de lista y la página de detalles, la página de lista es principalmente similar a una tabla para mostrar todos los datos, y la página de detalles se refiere principalmente a la información detallada de un ciertos datos, incluida la modificación, la creación de un nuevo dato, la visualización, etc., corresponden a la página de detalles, por lo que esta vez principalmente quiero compartir un poco sobre la implementación de la página de lista y la página de detalles. La pila de tecnología utilizada es Vue3+Ts, y la biblioteca de componentes utilizada es ant design y tailwindcss. La página de implementación específica se puede ver en la siguiente figura.

Esta página es una página de lista, que muestra principalmente los datos básicos del usuario. Después de verificar un dato, puede hacer clic para verlo y hacer clic en Eliminar para eliminar los datos actuales.

 Después de hacer clic en el botón de nuevos datos, ingresará a la página de detalles de nuevos datos, que es un formulario. Después de que el usuario ingrese la información y envíe la verificación, se agregarán nuevos datos en la página de lista.

Después de seleccionar un dato en la página de lista, haga clic en Ver para ir a la página de detalles del dato, que muestra toda la información del dato.

 

 

 Haga clic en el botón Modificar en la página de detalles para modificar los datos actuales. Una vez completada la modificación, haga clic en Enviar para cambiar la información de los datos actuales.

En general, es muy simple, solo dos páginas, una página de lista y una página de detalles. Hablemos de las ideas de implementación específicas:

        En un proyecto real, todos los datos se obtienen del backend, por lo que todos los cambios realizados se enviarán al backend a través de la solicitud de la interfaz y luego se solicitarán los datos nuevamente para actualizar la página. Aquí hice algunos datos falsos y los asigné cuando se inicializó la página. Al cambiar entre la página de lista y la página de detalles, enruté todos los datos como parámetros, por lo que no tengo que preocuparme por la pérdida de datos causada por la actualización de la página. . .

Dado que la página nueva, la página de detalles de visualización y la página de edición corresponden a la misma página, teniendo en cuenta la reutilización de los componentes, el formulario se combina con v-if para el control.

const routes = [
  {
    path: "/",
    component: () => import("../ant-table/Table.vue"),
  },
  {
    path: "/details",
    name: "details",
    component: () => import("../view/Detail.vue"),
  },
]

 La configuración de enrutamiento es como se muestra en la figura, y la página de lista se ingresa de forma predeterminada.

Empecemos oficialmente a escribir la página:

<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<script setup lang="ts"></script>

Aquí está el componente raíz de la aplicación, que se usa para representar el contenido cuando se cambia la ruta.

interface DataType {
  name: string;
  age: string;
  address: any;
  sex: string;
  school: string;
  hobby: any;
  birthday: any;
  phone: string;
  description: string;
  position: {
    isShow: boolean;
    place: string;
  };
}

Defina tipos de datos para facilitar la detección de tipos y escribir especificaciones.

    <a-table
      :row-selection="{
        type: 'radio',
        selectedRowKeys: rowSelection.selectedRowKeys,
        onChange: onSelectChange,
      }"
      rowKey="name"
      :columns="columns"
      :data-source="data"
    >
      <template #bodyCell="{ column, record, text, index }">
        <template v-if="column.dataIndex === 'operation'">
          <span class="text-yn-400">
            <delete-two-tone @click="deleteData(record, index)" />
          </span>
        </template>
        <template v-if="column.dataIndex === 'index'">
          <span>
            {
   
   { index }}
          </span>
        </template>
        <template v-if="column.dataIndex === 'address'">
          <span v-for="city in record.address">
            {
   
   { city }}
          </span>
        </template>
        <template v-if="column.dataIndex === 'hobby'">
          <span
            v-for="hobby in record.hobby"
            class="bg-green-200 rounded-lg py-1 px-1.5 mx-1.5"
          >
            {
   
   { hobby }}
          </span>
        </template>
      </template>
    </a-table>

Esta parte del código es principalmente para definir algunos datos, incluido el encabezado de la tabla, inicializar los datos de la tabla, etc.

// 跳转详情页
const toDetails = () => {
  if (rowSelection.selectedRowKeys.length !== 1) {
    message.error("请选择一条数据!");
  } else {
    let selectName = rowSelection.selectedRowKeys[0];
    let usedata: any = toRaw(data.value);
    router.push({
      path: "/details",
      query: { selectName, useData: JSON.stringify(usedata) },
    });
  }
};

 Vaya al código para ver la página de detalles como se muestra en la figura: el parámetro de consulta aquí pasa el nombre de los datos seleccionados actualmente (como un identificador único), y también pasa todos los datos en la página de lista, preste atención a la parámetro de enrutamiento aquí, si se pasa Son datos de tipo no cadena, que deben envolverse con JSON.stringify y analizarse con JSON.parse al recibir.

// 新建记录
const addNewData = () => {
  let usedata: any = toRaw(data.value);
  router.push({
    path: "/details",
    query: {
      useData: JSON.stringify(usedata),
    },
  });
};

Aquí está el código correspondiente al hacer clic para crear nuevos datos.

 Esta parte del código es el código correspondiente a la operación de inicializar la página y borrar los datos de la lista. Hice un juicio sobre la inicialización de los datos aquí, es decir, si hay algún dato cuando se carga la página. Si no hay datos, usaré los pocos datos definidos al principio. Si hay datos (de la página de detalles), use los datos en la página de detalles. La belleza aquí es que, de hecho, solo cuando se carga la página, no hay datos, y se usarán los datos predeterminados, y habrá datos cada vez que se cambie la ruta de la página después.

      <a-form
        :model="baseForm"
        name="basic"
        class="grid grid-cols-3"
        ref="formRef"
        :rules="baseInfoEules"
        layout="vertical"
      >
        <!-- 姓名 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="name" label="姓名">
            <span v-if="!isEdit">{
   
   { baseForm.name }}</span>
            <a-input
              :disabled="disableName"
              v-else
              v-model:value="baseForm.name"
            />
          </a-form-item>
        </div>
        <!-- 年龄 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="age" label="年龄">
            <span v-if="!isEdit">{
   
   { baseForm.age }}</span>
            <a-input-number
              class="w-full"
              id="inputNumber"
              v-else
              v-model:value="baseForm.age"
              :min="1"
              :max="99"
            />
          </a-form-item>
        </div>
        <!-- 性别 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="sex" label="性别">
            <span v-if="!isEdit">{
   
   { baseForm.sex }}</span>
            <a-select
              v-else
              v-model:value="baseForm.sex"
              placeholder="Please select sex"
            >
              <a-select-option value="男">男</a-select-option>
              <a-select-option value="女">女</a-select-option>
            </a-select>
          </a-form-item>
        </div>
        <!-- 地址 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="address" label="地址">
            <span v-if="!isEdit" v-for="city in baseForm.address">{
   
   {
              city
            }}</span>
            <a-cascader
              v-else
              v-model:value="baseForm.address"
              :options="cityOptions"
              placeholder="Please select address"
            />
          </a-form-item>
        </div>
        <!-- 学校 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="school" label="学校">
            <span v-if="!isEdit">{
   
   { baseForm.school }}</span>
            <a-select
              v-else
              v-model:value="baseForm.school"
              placeholder="Please select a university"
            >
              <a-select-option value="西南大学">西南大学</a-select-option>
              <a-select-option value="中南大学">中南大学</a-select-option>
              <a-select-option value="武汉大学">武汉大学</a-select-option>
              <a-select-option value="浙江大学">浙江大学</a-select-option>
            </a-select>
          </a-form-item>
        </div>
        <!-- 爱好 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="hobby" label="爱好">
            <span
              v-if="!isEdit"
              v-for="hobby in baseForm.hobby"
              class="mr-1.5 bg-green-200 py-1 px-1.5 pb-1.5 rounded-lg"
              >{
   
   { hobby }}</span
            >
            <a-select
              :options="options"
              :fieldNames="{ label: 'label', value: 'value' }"
              v-else
              v-model:value="baseForm.hobby"
              mode="multiple"
              placeholder="Please select hobby"
            >
            </a-select>
          </a-form-item>
        </div>
        <!-- 出生日期 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="birthday" label="出生日期">
            <span v-if="!isEdit">{
   
   { baseForm.birthday }}</span>
            <a-date-picker
              placeholder="请选择时间"
              style="width: 100%"
              v-else
              v-model:value="baseForm.birthday"
              value-format="YYYY-MM-DD"
            />
          </a-form-item>
        </div>
        <!-- 手机号 -->
        <div class="col-span-1 mx-3">
          <a-form-item name="phone" label="手机号码">
            <span v-if="!isEdit">{
   
   { baseForm.phone }}</span>
            <a-input
              v-else
              v-model:value="baseForm.phone"
              placeholder="请输入手机号码"
            />
          </a-form-item>
        </div>
        <!-- 位置信息 -->
        <a-form-item name="position" label="">
          <div class="col-span-1 mx-3 pt-8">
            <span class="mx-3">是否显示位置信息</span>
            <a-switch v-model:checked="baseForm.position!.isShow" />
            <span
              class="mx-3 bg-blue-200 px-1.5 py-1 rounded-md"
              v-if="baseForm.position!.isShow"
              >{
   
   { baseForm.position?.place }}
            </span>
          </div>
        </a-form-item>
        <!-- 说明 -->
        <div class="col-span-3 mx-3">
          <a-form-item name="description" label="情况说明">
            <span v-if="!isEdit">{
   
   { baseForm.description }}</span>
            <a-textarea
              v-else
              :rows="4"
              v-model:value="baseForm.description"
              placeholder="请输入说明"
            >
            </a-textarea>
          </a-form-item>
        </div>
      </a-form>

El contenido del formulario de la página de detalles es el siguiente: utilice v-if para juzgar si se encuentra actualmente en un formulario editable o en un estado de visualización de información.

// 获取列表页数据
if (route.query.useData as any) {
  useData.value = JSON.parse(route.query.useData as any) || [];
  dataSource.value = useData.value;
}

 Obtener los datos pasados ​​por la página de lista

 Esta parte del código no se mostrará, y debería poder saber lo que estoy haciendo mirando los comentarios en la imagen.

// 初始化数据
const initData = () => {
  dataSource.value = useData.value;
  // 表单置空
  getEmptydata();
  // 是否查看详情页
  if (receiveName) {
    dataSource.value.map((item) => {
      if (item.name === receiveName) {
        editData = item;
        baseForm.value.name = item.name;
        baseForm.value.age = item.age;
        baseForm.value.sex = item.sex;
        baseForm.value.school = item.school;
        baseForm.value.address = item.address;
        baseForm.value.hobby = item.hobby;
        baseForm.value.phone = item.phone;
        baseForm.value.birthday = item.birthday;
        baseForm.value.description = item.description;
        baseForm.value.position = item.position || {
          isShow: false,
          place: "湖北  武汉",
        };
      }
    });
  } else {
    // 新增数据页面
    isEdit.value = true;
    disableName.value = false;
  }
};
onMounted(() => {
  initData();
});

Esta parte del código es más crítica, es decir, al inicializar la página de detalles, primero juzgue si es una página nueva o una página de visualización pasando parámetros.En la página de lista, si hace clic para ver los detalles, el valor del nombre de los datos seleccionados se pasa, y No hay transmisión cuando hace clic en Crear, aquí es para determinar si se deben crear nuevos datos o ver los detalles al juzgar si se ha recibido el valor del nombre del parámetro de enrutamiento.

// 提交
const submit = () => {
  // 修改后提交
  if (receiveName) {
    formRef.value?.validateFields().then(
      (res) => {
        isEdit.value = !isEdit.value;
        let newData: any = res;
        dataSource.value.map((item) => {
          // 把修改的数据替换掉原来的数据
          if (item.name == receiveName) {
            item.name = newData?.name;
            item.age = newData?.age;
            item.sex = newData?.sex;
            item.school = newData?.school;
            item.address = newData?.address;
            item.hobby = toRaw(newData?.hobby);
            item.birthday = newData?.birthday;
            item.phone = newData?.phone;
            item.position = newData.position;
            item.description = newData?.description;
          }
        });
        router.push({
          path: "/",
          query: { obj: JSON.stringify(dataSource.value) },
        });
      },
      (error) => {
        console.log(error);
      }
    );
  } else {
    // 新增后提交
    formRef.value?.validateFields().then(
      (res) => {
        console.log(res);
        if (res) {
          isEdit.value = !isEdit.value;
          let newData: any = res;
          dataSource.value.push(newData);
          router.push({
            path: "/",
            query: { obj: JSON.stringify(dataSource.value) },
          });
        }
      },
      (error) => {
        console.log(error);
      }
    );
  }
};

Esta parte del código también es muy importante, ya que es el método que se activa al hacer clic en enviar después de la modificación o adición.

Primero juzgue si modificar o crear nuevos datos, y luego envíe el formulario para obtener el proceso. Si es un envío modificado, reemplace los datos originales con los datos modificados. Si son datos nuevos, insértelos directamente en los datos. Finalmente, una vez completada la modificación, la ruta salta a la página de lista y todos los datos se pasan como referencia.

Hasta ahora, se han realizado una página de lista simple y una página de detalles. Algunas partes tienen una redundancia relativamente alta y se pueden optimizar y mejorar aún más, y algunos detalles también se pueden optimizar, como la coincidencia regular de números de teléfonos móviles.

Efectivamente, aún es más fácil ajustar la interfaz y solicitar datos directamente desde el backend jaja, de lo contrario sería demasiado problemático obtener tantos datos cada vez.

¡Hay otras preguntas bienvenidas para criticar y corregir!

Pondré el código fuente en el almacén de código en la nube más tarde.

Supongo que te gusta

Origin blog.csdn.net/weixin_48914380/article/details/128904901
Recomendado
Clasificación