El diseño Ant de la tabla Vue utiliza el resumen del problema del encabezado del paquete vue-draggable-resizeable

fondo

El proyecto necesita que la tabla admita el estiramiento del ancho de cada columna.Después de revisar el documento, la sugerencia oficial es usar el complemento vue-draggable-resizeable combinado con el atributo components para agregar una función arrastrable al encabezado. De hecho, los primeros tres problemas a continuación son fáciles de resolver y hay muchas soluciones en Internet, pero debido a que hay muchas tablas en el proyecto y cada tabla debe admitir el ancho de columna extendido, es imposible seguir el documento oficial. Todos los componentes vue de Vue escriben códigos repetitivos, por lo que se encapsula un método para obtener los componentes del encabezado arrastrable.

pregunta

1. Al usar ResizeableTitle, puede haber un conflicto de nombres.
Error: el análisis del módulo falló: el nombre del argumento choca
inserte la descripción de la imagen aquí
Solución:
simplemente cambie ResizeableTitle a resizeableTitle. A veces ocurre este problema y otras veces no.

2. Después de agregar el cuadro de selección de tabla, se informa un error.
De hecho, es principalmente un problema con el código en el documento oficial (como se muestra en la figura a continuación).
inserte la descripción de la imagen aquí
Esto se debe a que en el documento antd, las columnas no tienen un cuadro de selección Cuando la función atraviesa y ejecuta cada columna, encuentra una selección No hay una columna correspondiente en la columna del cuadro, y la columna no estará definida, por lo que se debe hacer un juicio sobre el cuadro de selección, y se puede devuelto directamente sin realizar operaciones posteriores.
Solución:
inserte la descripción de la imagen aquí
3. Desaparecen algunos estilos de botón del encabezado de la tabla, como el estilo deslizable y el estilo de clic en la figura a continuación, porque el nuevo th no hereda el nombre de clase del th original.
inserte la descripción de la imagen aquí
Como se muestra en el código del documento oficial como se muestra en la figura a continuación, podemos ver que el th devuelto no tiene nombre de clase o solo cambia el tamaño de la tabla-th, que es muy superficial.
inserte la descripción de la imagen aquí
Solución:
De hecho, podemos obtener el nombre de clase del elemento original del parámetro devuelto por la función. El
inserte la descripción de la imagen aquí
parámetro formal impreso es como se muestra en la siguiente figura:
inserte la descripción de la imagen aquí
4. La función de clasificación en el encabezado de la tabla no es válida y la clasificación no se puede hacer clic en la función
inserte la descripción de la imagen aquí

Como se mencionó en el fondo de la apelación, he encapsulado este método de arrastrar y soltar en un método global. Y la razón directa de este problema es que encapsulo resizeableTitle en un método global getTableDragHeader y lo coloco en un archivo js, ​​en lugar de escribirlo en la página vue que llama al componente de tabla como el documento oficial. Porque si no está encapsulado, todas las tablas que deben arrastrarse tendrán que reescribir estos códigos, lo cual es muy inconveniente, así que lo escribí como un método global para todas las páginas con tablas.

Además, también encontré un problema. En el método de arrastre global que encapsulé, si cambio el resizeableTitle a otro nombre, el método de llamada será diferente. La función original llamada resizeableTitle
inserte la descripción de la imagen aquí
imprima un parámetro formal:
inserte la descripción de la imagen aquí
simplemente escriba un parámetro formal para obtener accesorios, niños y datos.

Pero para cambiar el nombre de la función a cualquier otro nombre, simplemente pase tres parámetros, y el documento oficial se escribe para pasar tres parámetros.
Imprima la siguiente imagen, el primer parámetro es una función, el segundo parámetro es accesorios y el tercer parámetro es niños:
inserte la descripción de la imagen aquí
Esto es muy inexplicable, pero hay una gran diferencia si el nombre de la función es diferente.
Originalmente, usar resizeableTitle empaquetado como un método global para llamar para obtener las columnas de los encabezados que se pueden arrastrar no informará un error, pero no se puede hacer clic en la función de clasificación. Pero cuando cambio el nombre de resizeableTitle a resizeable , se da el caso de que hay tres parámetros con el documento oficial, y la consola informa un error: Error en render: "ReferenceError: h is notdefined" , como se muestra en la figura
inserte la descripción de la imagen aquí
a continuación: Baidu tiene este error, cuando otras personas encuentran este problema, su explicación es que las columnas de la tabla no se colocan en la función de datos y no se puede obtener el contexto. ¿Qué tipo de explicación vaga es esta? . .
Esto está relacionado con mi situación actual, y de hecho está relacionado con el contexto.Después de todo, lo encapsulo como un método js global, es decir, el método no es específico de una determinada instancia de vue, sino un método js global.

Entonces, todavía cambio el método a local primero, y luego comparo y veo cuál es el llamado contexto.
De acuerdo con la forma del documento antd, vuelvo a escribir el método en la página vue. getTableDragHeader es un método que encapsulo en un método que puede devolver el encabezado de arrastre de acuerdo con las columnas. El código es el siguiente:
inserte la descripción de la imagen aquí

Luego mírelo, el resultado es que no habrá ningún problema con la función de clasificación que falla. Es decir, el evento no es inválido porque el encabezado es reemplazado por la plantilla devuelta por los componentes.El método de arrastre de vue-draggable-resizable + components no es problema.

Entonces, el problema puede estar en la llamada y declaración del método.

Después de muchos intentos, he considerado el apuntamiento de this y la forma de introducir el objeto de instancia de vue, pero no parece importar, el punto parece ser que el método debe declararse en el componente, y debe estar bajo la instancia del componente llamado. Entonces, ¿cómo se puede encapsular en un método global para que lo usen todos los componentes? ¿No es posible escribir sólo en un componente?

Me di la vuelta, hice clic en el lugar donde se informó el error y verifiqué directamente su código fuente:
inserte la descripción de la imagen aquí
parece que TableHeaderRow es una forma de proporcionar renderizar a vue para representar la plantilla de retorno de la función, y h es el método para crear elementos.
Para resumir, según tengo entendido, en realidad es la plantilla devuelta por devolución, como se muestra en la figura a continuación:
inserte la descripción de la imagen aquí
debe escribirse en la instancia de vue, no simplemente escribirse en un archivo js, ​​y luego llamarse en vue. En Baidu, los internautas dijeron que la solución a este tipo de informe de errores es que las columnas están escritas en los datos, y no es más que sus columnas tienen customRender, una opción que requiere plantillas de renderizado. De manera similar al método getTableDragHeader que encapsulé , este método con devolución de plantilla de plantilla no se puede declarar fuera de la instancia de vue, debe declararse en una determinada instancia de vue. Por lo tanto, también es problemático declarar fuera de la instancia de vue en el documento oficial, como se muestra en la figura a continuación.
inserte la descripción de la imagen aquí
La consola oficial no informa un error porque el nombre de la función es ResizeableTitle , cambiarlo a otro nombre de función informará inmediatamente un error, y el error h no está definido mencionado anteriormente seguirá apareciendo, porque el método para devolver la plantilla no es escrito en la instancia de vue.
Solución:
ahora que sé que el método debe escribirse en cualquier instancia de vue, pero no quiero declararlo uno por uno, por lo que debo tener una instancia de vue global a la que puedan llamar todas las páginas de vue. Esto trae a la mente el componente raíz $root y $Bus. Debido a que no quiero que $root se vuelva complicado y desordenado, creé una instancia de vue pública de $Bus para todas las llamadas y comunicaciones de los componentes.
el código se muestra a continuación:

import Vue from 'vue';
import VueDraggableResizable from 'vue-draggable-resizable';
Vue.component('vue-draggable-resizable', VueDraggableResizable);
const Bus = new Vue({
    
    
    methods:{
    
    
        getTableDragHeader(columns) {
    
    
            const draggingMap = {
    
    };
            columns.forEach((col) => {
    
    
              draggingMap[col.key] = col.width;
            });
            const draggingState = Vue.observable(draggingMap);
            const resizeable  = (a,b,c) => {
    
    
              let thDom = null;
              const props = b;
              const children = c;
              const {
    
     key, ...restProps } = props;
              let col = null;
              if (key === "selection-column") {
    
    
                // 当前column为全选的时候,要返回全选的 th ,否则无法出现全选
                return <th {
    
    ...restProps} class={
    
    props.class}>{
    
    children}</th>
              } else {
    
    
                col = columns.find((item) => {
    
    
                  const k = item.dataIndex || item.key;
                  return k === key;
                });
              }
          
              if (!col.width) {
    
    
                return <th {
    
    ...restProps} class={
    
    props.class}>{
    
    children}</th>;
              }
              const onDrag = (x) => {
    
    
                draggingState[key] = 0;
                const maxWidth = thDom.parentNode.offsetWidth/2 || 100; // 拖拽最长长度不能超过表格的一半
                col.width = Math.min(Math.max(x, 50), maxWidth);
              };
          
              const onDragstop = () => {
    
    
                draggingState[key] = thDom.getBoundingClientRect().width;
              };
              return (
                <th {
    
    ...restProps} v-ant-ref={
    
    (r) => (thDom = r)} width={
    
    col.width} class={
    
    props.class+" resize-table-th"}>
                  {
    
    children}
                  <vue-draggable-resizable
                    key={
    
    col.key}
                    class="table-draggable-handle"
                    w={
    
    10}
                    x={
    
    draggingState[key] || col.width}
                    z={
    
    1}
                    axis="x"
                    draggable={
    
    true}
                    resizable={
    
    false}
                    onDragging={
    
    onDrag}
                    onDragstop={
    
    onDragstop}
                  ></vue-draggable-resizable>
                </th>
              );
            };
            return {
    
    
              header: {
    
    
                cell: resizeable ,
              },
            }
          }
    }
})

export default Bus;

Escribí el método getTableDragHeader bajo la instancia vue de Bus.
Finalmente, introduje el Bus exportado en main.js y lo monté bajo la instancia de Vue para convertirlo en $ Bus. De hecho, se puede llamar a $ Bus.getTableDragHeader para obtener columnas de encabezado arrastrables, pero debido al método encapsulado previamente $ YGetTableDragHeader , el código Muchos lugares ya han usado la forma de $ YGetTableDragHeader para llamar y obtener, por lo que el nuevo método de $ Bus.getTableDragHeader solo se puede reasignar a él, y no es necesario cambiar el código en otros lugares.
inserte la descripción de la imagen aquí

ultimas palabras

Hay muy poca información disponible en el documento de componentes de la tabla antd, y el documento flexible entre las columnas de la tabla solo brinda un pequeño ejemplo, y este ejemplo tiene muchos problemas, que en mi opinión es problemático en sí mismo. Espero que este artículo pueda brindarle una referencia y resolver los problemas que encuentre. Si tiene otros problemas al usar vue-draggable-resize, puede dejarme un mensaje y lo ayudaré a resolverlo cuando lo vea.

Supongo que te gusta

Origin blog.csdn.net/weixin_43589827/article/details/119446846
Recomendado
Clasificación