Entrevista Vue (3) - Funciones vue avanzadas

Las características avanzadas vue de la prueba regular (puntos de conocimiento)

1. Modelo v personalizado

<template>
    <div>
        <p>vue 高级特性</p>
        <hr>
        <!-- 自定义 v-model -->
        <p>{{name}}</p>
        <CustomVModel v-model="name"/>
        <MixinDemo/>
    </div>
</template>
<script>
 export default {
    components: {
        CustomVModel
    },
    data() {
        return {
            name: 'name'
        }
    }
}
</script>

Color selector de enlace de datos bidireccional

customVModel.vue

<template>
    <!-- 例如:vue 颜色选择 -->
    <input type="text"
        :value="text1"
        @input="$emit('change1', $event.target.value)">
    <!--
        1. 上面的 input 使用了 :value 而不是 v-model
        2. 上面的 change1 和 model.event1 要对应起来
        3. text1 属性对应起来
    -->
</template>

<script>
export default {
    model: {
        prop: 'text1', // 对应 props text1
        event: 'change1'
    },
    props: {
        text1: String,
        default() {
            return ''
        }
    }
}
</script>

2. $ nextTick

  vue es renderizado asíncrono,

  Después de que los datos cambien, el DOM no se representará de inmediato,

  $ nextTick se activará después de la representación DOM para obtener el último nodo DOM

<template>
  <div id="app">
    <ul ref="ul1">
        <li v-for="(item, index) in list" :key="index">
            {{item}}
        </li>
    </ul>
    <button @click="addItem">添加一项</button>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
      return {
        list: ['a', 'b', 'c']
      }
  },
  methods: {
    addItem() {
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)
        // 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
        // 2. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次(使用一次$nextTick)
        this.$nextTick(() => {
          // 获取 DOM 元素
          const ulElem = this.$refs.ul1
          // eslint-disable-next-line
          console.log( ulElem.childNodes.length )
        })
    }
  }
}
</script>

(Defina ref = " ul1 " en el elemento DOM , entonces puede usar esto. $ Refs.ul1 para obtener el elemento DOM)

El efecto de no usar $ nextTick: haga clic una vez para generar 3, haga clic en el segundo para generar 6

Para obtener el resultado de renderizado inmediatamente después de hacer clic: use $ nextTick

3. ranura

  El rol de la ranura del componente: el componente primario pasa el contenido al componente secundario (el contenido de la plantilla)

  Ubicación de la ranura: ubicada en la plantilla del subcomponente

(1) Uso básico

<template>
    <div>
        <p>vue 高级特性</p>
        <!-- slot -->
        <SlotDemo :url="website.url">
            {{website.title}}
        </SlotDemo>
    </div>
</template>

<script>
import SlotDemo from './SlotDemo'
export default {
    components: {
        SlotDemo
    },
    data() {
        return {
            name: '姓名',
            website: {
                url: 'http://imooc.com/',
                title: 'imooc',
                subTitle: '程序员的梦工厂'
            }
        }
    }
}
</script>

SlotDemo.vue

<template>
    <a :href="url">
        <slot>
            显示默认内容,即父组件没设置内容时
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {}
    }
}
</script>

(Efecto: el enlace se mostrará en forma de etiqueta y mostrará el contenido del título)

(2) Ranura de alcance

<template>
    <a :href="url">
        <slot :slotData="website">
            {{website.subTitle}} <!-- 父组件不传内容时默认值显示 subTitle  -->
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {
            website: {
                url: 'http://wangEditor.com/',
                title: 'wangEditor',
                subTitle: '轻量级富文本编辑器'
            }
        }
    }
}
</script>

(Si no se pasa el valor {{website.subTitle}} } , se mostrará el subtítulo predeterminado del subcomponente)

Uso : los datos de ámbito en el componente secundario permiten que el componente primario lo obtenga

<ScopedSlotDemo :url="website.url">
            <template v-slot="slotProps">
                {{slotProps.slotData.title}}
            </template>
 </ScopedSlotDemo>

Efecto: la página muestra el contenido del subcomponente wangEditor

(Pensamientos: defina el atributo dinámico slotData en el espacio, y luego defínalo en el sitio web, que contiene el título y el subtítulo. Luego use ScopedSlotDemo en el índice para definir v-slot = " slotProps " . Luego puede usar slot Props.slot DaTa Obtenga el contenido del sitio web en el componente ScopedSlotDemo, para que pueda obtener el título del sitio web)

(3) Ranura nombrada

La coincidencia de ranuras con nombre basada en el contenido, ningún nombre coincidirá de manera predeterminada

Cuando el componente principal pasa el contenido al componente secundario, debe corresponder al buen nombre

4. Componentes dinámicos y componentes asincrónicos.

(1) Componentes dinámicos

  Uso: : is = " nombre-componente "

  Escenas que deben renderizarse dinámicamente en función de los datos. Es decir, el tipo de componente no está determinado. (Generalmente, se determina el tipo de componente)

Escenario de uso de ejemplo: página de detalles de noticias. (La posición o el tipo del componente es incierto. Es decir, no sabe qué tipo de componente representar, solo los datos. Debe determinar el tipo de componente en función de los datos, luego debe usar el componente dinámico)

<template>
    <div>
        <p>vue 高级特性</p>
        <!-- 动态组件 -->
        <!-- <component :is="NextTickName"/> -->
        <div v-for="(index, value) in newsData" :key="index">
            <component :is="value.type"></component>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            name: 'name',
             // NextTickName: "NextTick",
            newsData: {
                1: {type: 'text'},
                2: {type: 'text'},
                3: {type: 'image'},
            }
        }
    }
}
</script>

(Render basado en los componentes adquiridos (texto, imagen))

(2) componentes asincrónicos

  Función de importación

  Cargue componentes grandes a pedido y de forma asincrónica

(Cada vez que lo usa, lo carga en cualquier momento. Si no lo usa, nunca se cargará. Es adecuado para componentes más grandes y complejos, lo que optimizará el rendimiento)

Use la declaración import SlotDemo from './SlotDemo' para cargar sincrónicamente

<!-- 异步组件 -->
        <FormDemo v-if="showFormDemo"/>
        <button @click="showFormDemo = true">show form demo</button> 

// 然后在components里面写
components: {
       FormDemo: () => import('../BaseUse/FormDemo'),
    }

Efecto: FormDemo no se cargará cuando no haya clic, se cargará y se representará después de hacer clic

5. mantener vivo

  Componente de caché

  Cambio frecuente, no es necesario repetir el renderizado

  Vue optimización de rendimiento común

KeepAlive.Vue presenta tres componentes KeepAliveAtageA, KeepAliveAtageB, KeepAliveAtageC son tres botones

Haga clic en el efecto BC a su vez:

No use mantener vivo

Use keepalive

Un montado

Un destruido

B montado

B destruido

C montado

C destruido

Un montado

Un creado

B creado

C creado

<KeepAliveStageA v-if = "state === 'A'" /> 

<KeepAliveStageB v-if = "state === 'B'" />

<KeepAliveStageC v-if = "state === 'C'" />

 

<keep-alive> <! - tab 切换 ->

            <KeepAliveStageA v-if = "state === 'A'" />

            <KeepAliveStageB v-if = "state === 'B'" />

            <KeepAliveStageC v-if = "state === 'C'" />

 </keep-alive>

La diferencia entre usar keep-alive y v-show:

v-show está controlado por CSS nativo (uso: las etiquetas son relativamente simples)

Keepalive es la representación de objetos JS a nivel de marco vue (caso de uso: cambio de componentes complejos con cambio de nivel o tabulación)

<template>
    <div>
        <button @click="changeState('A')">A</button>
        <button @click="changeState('B')">B</button>
        <button @click="changeState('C')">C</button>

        <keep-alive> <!-- tab 切换 -->
            <KeepAliveStageA v-if="state === 'A'"/> <!-- v-show -->
            <KeepAliveStageB v-if="state === 'B'"/>
            <KeepAliveStageC v-if="state === 'C'"/>
        </keep-alive>
    </div>
</template>

<script>
import KeepAliveStageA from './KeepAliveStateA'
import KeepAliveStageB from './KeepAliveStateB'
import KeepAliveStageC from './KeepAliveStateC'

export default {
    components: {
        KeepAliveStageA,
        KeepAliveStageB,
        KeepAliveStageC
    },
    data() {
        return {
            state: 'A'
        }
    },
    methods: {
        changeState(state) {
            this.state = state
        }
    }
}
</script>

keepAliveStateA.vue

<template>
    <p>state A</p>
</template>

<script>
export default {
    mounted() {
        // eslint-disable-next-line
        console.log('A mounted')
    },
    destroyed() {
        // eslint-disable-next-line
        console.log('A destroyed')
    }
}
</script>

6. mixin

  Múltiples componentes tienen la misma lógica, extraída de ellos

  Mixin no es la solución perfecta, habrá problemas

  La composición API propuesta por Vue 3 tiene como objetivo resolver estos problemas

(Mixin es una pieza de código js)

Problemas con Mixin

(1) La fuente de la variable es desconocida, lo que no es propicio para la lectura

(2) Múltiples mixins pueden causar conflictos de nombres

(3) Puede haber una relación de muchos a muchos entre Mixin y los componentes, con alta complejidad

<template>
    <div>
        <p>{{name}} {{major}} {{city}}</p>
        <button @click="showName">显示姓名</button>
    </div>
</template>

<script>
import myMixin from './mixin'

export default {
    mixins: [myMixin], // 可以添加多个,会自动合并起来
    data() {
        return {
            name: 'zs',
            major: 'web'
        }
    },
    methods: {
    },
    mounted() {
        // eslint-disable-next-line
        console.log('component mounted', this.name)
    }
}
</script>

mixin.js

export default {
    data() {
        return {
            city: '北京'
        }
    },
    methods: {
        showName() {
            // eslint-disable-next-line
            console.log(this.name)
        }
    },
    mounted() {
        // eslint-disable-next-line
        console.log('mixin mounted', this.name)
    }
}

 

Publicado 26 artículos originales · ganó 6 · vistas 1393

Supongo que te gusta

Origin blog.csdn.net/Sabrina_cc/article/details/105366601
Recomendado
Clasificación