Encapsulación de componentes públicos de Vue y transferencia de valor

Tres elementos de los componentes de Vue

1. Parámetro de accesorios
2. Ranura ranura personalizada
3. Evento Evento personalizado


Desarrollo de componentes básicos

Cree un archivo .vue que contenga plantilla, script y estilo:

<template>
  <div class="headComponent">
    {
   
   { msg }}
  </div>
</template>

<script>
export default {
    props:['data','type'],
    inheritAttrs: false,
    data(){
        return{
            msg:'',
        }
    }
}
</script>
<style scoped>

</style>


Hasta el momento se ha completado un componente básico, para utilizar este componente es necesario introducirlo y registrarlo en otros archivos js:

import Head from '../components/headComponent.vue'

 

 

¿Cómo encapsular un componente común?

  1. Primero cree una nueva carpeta de Componentes en el directorio src.
  2. El componente recién creado que se va a empaquetar se denomina subcarpeta
  3. Cree un nuevo archivo index.vue en la subcarpeta para almacenar los componentes públicos que se encapsularán
  4. Finalmente, cree un nuevo archivo index.js en la carpeta Componentes
  5. Y registrar componentes públicos en el global.
import pageTools from './pageTools/index'
 
export default {
  install(Vue) {
    Vue.component('pageTools', pageTools)
   
  }
}


De esta manera, los componentes comunes se pueden usar en otros componentes sin importar componentes

< pageTools></ pageTools>



 


Transferencia de datos entre componentes

 * Comunicación de componente padre-hijo

  Subensamblaje:

d0a5deb8b1cc155920e0a3a197ef25f8.png

     

    componente padre:

09102a4abc7e6fc38a1568c1e1977200.png

 

 

 

1. El componente principal pasa datos al componente secundario

Los componentes principales pasan datos a los componentes secundarios en forma de atributos, y los componentes secundarios reciben datos mediante accesorios. Sin embargo, los escenarios de aplicación de los componentes comunes son más complicados. Se deben agregar algunas reglas de validación a los parámetros que pasan los accesorios, a saber:

props: {
    propA: Number,  // 基础类型检测 (`null` 意思是任何类型都可以)
    propB: [String, Number],   // 多种类型
    propC: {  // 必传且是字符串
      type: String,
      required: true
    },
    propD: {   // 数字,有默认值
      type: Number,
      default: 100
    },
    propE: {   // 数组/对象的默认值应当由一个工厂函数返回
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    propF: {   // 自定义验证函数
      validator: function (value) {
        return value > 10
      }
    }
  }

 


Debido al problema del flujo de datos de un solo elemento, los datos pasados ​​del componente principal al componente secundario no deben modificarse directamente, ya que los datos del componente principal también se modificarán y surgirán problemas cuando estos datos también se transfieran. pasa a otros componentes. Vue2.5 ha sido optimizado para accesorios, y este problema ya no existe. Si debe tener una operación de este tipo, puede escribirla así:

let copyData = JSON.parse(JSON.stringify(this.data))

¿Por qué no simplemente escribir let myData = this.data? Debido a la asignación directa, es solo una copia superficial de objetos y matrices, que apunta a la misma dirección de memoria, y cambiar uno de ellos también cambiará el otro. Sin embargo, después de la conversión inversa de JSON, se realiza la copia profunda, que no puede afectarse entre sí.

 

 

2. El componente secundario pasa datos al componente principal

El componente secundario pasa datos al componente principal: active el método del componente principal y pase los datos del parámetro al componente principal

handleSubmit(data){
    this.$emit('submitToParent', data)
}



¿Cómo obtiene el componente principal los datos que pasa el componente secundario?

<header @submitToParent="parentSubmit"></header>

methods: {
    parentSubmit(data){
        // 父组件的业务逻辑
    }
}

 

3. El componente hijo cambia los datos del componente padre

Cuando pasamos los datos del elemento principal al componente secundario, necesitamos pasar un tipo no básico, es decir, pasar el objeto o la matriz, y el componente secundario manipula los datos accediendo a las propiedades del objeto. y las matrices se pasan por referencia, se modifican en el componente secundario, el componente principal también cambiará sincrónicamente, de la siguiente manera:

// 父组件要props传递给子组件的数据
data:{
    info:'父组件信息'
}
 
// 子组件
 <template id="tpl">
    <div>
        <button @click="change">change</button>
        <p>{
   
   {data.info}}</p>
    </div>
</template>
... 省略部分无关代码 ...
props:['data'],
methods:{
    change(){
        this.data.info = 'change info'
    }
}

Cuando el componente secundario hace clic en el botón de cambio para cambiar los datos, el componente principal también cambiará sincrónicamente



4. Usa tragamonedas

Un componente de uso general a menudo no es adecuado para todos los escenarios de aplicación, por lo que solo el 80 % de la función del componente debe completarse al encapsular el componente, y el 20 % restante lo resuelve el componente principal a través de solt. Por ejemplo: hay dos botones en un componente público, uno es "Agregar" y el otro es "Eliminar", pero cuando se usa este componente en otra escena, los dos botones deben hacer cosas diferentes, como "Ver" y " Modificar". Por lo tanto, cuando encapsulamos el componente, no debemos escribir directamente el botón, sino colocar una ranura en una posición adecuada, que en realidad es un marcador de posición. Reserve una posición para la configuración del botón de antemano y luego escríbala en el botón del componente principal. .

 

Subensamblaje:

<div class="child-btn">
    <!-- 具名插槽 -->
    <slot name="button"></slot>
    <!-- 匿名插槽(每个组件只能有一个) -->
    <slot><slot>
</div>


componente padre:

<child>
    <!-- 对应子组件中button的插槽 -->
    <button slot="button">slot按钮</button>
</child>

Al desarrollar componentes comunes, siempre que no sean componentes muy independientes, es mejor agregar una ranura. Además, durante el proceso de desarrollo, a menudo es necesario agregar contenido nuevo en el subcomponente. En este momento, se pueden dejar uno o más sockets dentro del subcomponente y luego agregar contenido al llamar a este subcomponente, y el contenido agregado se distribuirá a la correspondiente En la ranura:

Subensamblaje:

<template>
  <div class="headComponent">
    <h3>这是一个头部组件</h3>
    <slot></slot>
    <slot name="s1"></slot>
    <slot name="s2"></slot>
  </div>
</template>

componente padre:

<head-component>
    <h2>不具名插槽</h2>
    <h2 slot="s1">这里对应的是s1插口</h2>
    <h2 slot="s2">这里对应的是s2插口</h2>
</head-component>



La ranura también se puede usar como ámbito para definir variables en el componente secundario y luego personalizar el método de representación en el componente principal: (se usa más en el proyecto, los datos obtenidos por ajax en vue+elementUI se muestran en el tabla, y muchas veces cada pieza de datos no se muestra directamente, se requiere algún procesamiento adicional)

Subensamblaje:

<template>
  <div class="headComponent">
    <h3>这是一个头部组件</h3>
    <slot name="head" v-for="head in heads" :text="head.text"></slot>
  </div>
</template>

componente padre:

<head-component>
    <template slot="head" scope="props">
        <li> {
   
   { props.text }} </li>
    </template>
</head-component>

En el ejemplo anterior, primero agregue una ranura en el componente secundario y defina los encabezados de variables de matriz en el componente secundario y luego agregue contenido en el componente principal con la plantilla de alcance, donde el alcance es una propiedad inherente y su valor corresponde a una variable temporal accesorios, y los accesorios recibirán los encabezados de parámetros pasados ​​del componente principal al componente secundario

**************************************************** ***********************************

Cómo usar las tragamonedas:

¿Qué son las tragamonedas?

  1. Slot (Slot) es un concepto propuesto por Vue, al igual que su nombre, el slot se utiliza para decidir insertar el contenido transportado en una posición específica, de modo que la plantilla se divida en bloques, con características modulares y mayor de reutilización.
  2. El componente principal controla si la ranura se muestra o no y cómo se muestra, y el componente secundario controla dónde se muestra la ranura.
  3. El componente principal tiene una estructura y el componente secundario usa una ranura para ocupar el lugar
  4. El intervalo de alcance es una forma de pasar parámetros del elemento secundario al principal, lo que resuelve el problema de que los intervalos ordinarios no pueden acceder a los datos secundarios en el elemento principal;

¿Cómo usar las tragamonedas?

ranura predeterminada

componente principal

<template>
  <div>
    我是父组件
    <slotOne1>
      <p style="color:red">我是父组件插槽内容</p>
    </slotOne1>
  </div>
</template>

 

Escriba el contenido que desea mostrar en el componente secundario al que hace referencia el componente principal (las etiquetas se pueden usar o no)

Subcomponente (slotOne1)

<template>
  <div class="slotOne1">
    <div>我是slotOne1组件</div>
    <slot></slot>
  </div>
</template>

Escriba la ranura en el componente secundario, donde se encuentra la ranura es el contenido que mostrará el componente principal

157191a183b117bf5f57ed00c76669ea.png

  • Por supuesto, también se pueden escribir otros componentes en el componente secundario al que hace referencia el componente principal.

componente principal

<template>
  <div>
    我是父组件
    <slotOne1>
      <p style="color:red">我是父组件插槽内容</p>
      <slot-one2></slot-one2>
    </slotOne1>
  </div>
</template>

 

Subcomponente (slotOne2)

<template>
  <div class="slotOne2">
    我是slotOne2组件
  </div>
</template>

ad03e75b766a552dd75059aca0ffe502.png

ranura con nombre

Subensamblaje

<template> 
  <div class="slottwo"> 
    <div>slottwo</div> 
    <slot name="header" ></slot> 
    <slot></slot> 
    <slot name="footer" ></slot> 
  </div> 
</plantilla>

Se definen tres etiquetas de ranura en el subcomponente, dos de las cuales se agregan con el encabezado y el pie de página del atributo de nombre, respectivamente.

componente principal

<template> 
  <div> 
    Soy el componente principal 
    <slot-two> 
      <p>La la la, la la la, soy un poco experto en vender periódicos</p> <template slot="header"> 
          <p> Soy el espacio cuyo nombre es encabezado</p> 
      </template> 
      <p slot="footer">Soy el espacio cuyo nombre es pie de página</p> 
    </slot-two> 
  </div> 
</template>
     

Use la plantilla en el componente principal y escriba el valor del espacio correspondiente para especificar la posición real del contenido en el componente secundario (por supuesto, no tiene que escribirlo en la plantilla). Otro contenido sin valores correspondientes se colocarse en el componente secundario sin agregar el nombre En la ranura del atributo

4019642f15f5b1b33a1b1da75abc439b.png

El contenido predeterminado de la ranura.

componente principal

<template>
  <div>
    我是父组件
    <slot-two></slot-two>
  </div>
</template>

Subensamblaje

<template>
  <div class="slottwo">
    <slot>我不是卖报的小行家</slot>
  </div>
</template>

 

Puede escribir contenido en la etiqueta de ranura del componente secundario. Cuando el componente principal no escribe contenido, mostrará el contenido predeterminado del componente secundario. Cuando el componente principal escribe contenido, reemplazará el contenido predeterminado del componente secundario. .

db95bb91116564862420cdb8f393ae5d.png

ámbito de compilación

 

componente principal

<template>
  <div>
    我是父组件
    <slot-two>
      <p>{
   
   {name}}</p>
    </slot-two>
  </div>
</template>
<script>
export default {
  data () {
    return {
      name: 'Jack'
    }
  }
}
</script>

Subensamblaje

<template>
  <div class="slottwo">
    <slot></slot>
  </div>
</template>

85b54c89ce5b0befda0100eb33e09d00.png

Ranuras con alcance

  • El intervalo de alcance es una forma de pasar parámetros del elemento secundario al principal, lo que resuelve el problema de que los intervalos ordinarios no pueden acceder a los datos secundarios en el elemento principal;

Subensamblaje

<plantilla> 
  <div> 
    Soy un subcomponente de ranuras con ámbito 
    <ranura :datos="usuario" ></ranura> 
  </div> 
</plantilla> 

<script> 
export default { 
  nombre: 'ranuratres', 
  datos ( ) { 
    return { 
      usuario: [ 
        {nombre: 'Jack', sexo: 'niño'}, 
        {nombre: 'Jone', sexo: 'niña'}, 
        {nombre: 'Tom', sexo: 'niño'} 
      ] 
    } 
  } 
} 
</script>

Enlace el valor requerido en la etiqueta de la ranura del componente secundario

 

 

componente principal

<plantilla> 
  <div>
    我是作用域插槽
    <ranura-tres> 
      <template slot-scope="usuario" > 
        <div v-for="(elemento, índice) en usuario.datos " :key="índice" > 
        { 
  
  {elemento}} 
        </div> 
      </plantilla> 
    </ranura-tres> 
  </div> 
</plantilla>

 

Use el atributo de alcance de ranura en el componente principal, user.data es el valor pasado desde el componente secundario

7bf5cebe56c1d14351e6653cdc5e8a67.png

Completo, use el atributo props para pasar el valor, la ranura del alcance

componente padre:

<template> 
    <div> 
        <p>vue 高级特性</p> 
        <hr> 

        <ScopedSlotDemo :url="website.url"> 
            <template slot-scope="slotProps" > 
                { 
  
  {
   slotProps.slotData .title}} 
            < /template> 
        </ScopedSlotDemo> 
    </div> 
</template> 
<script> 
importar ScopedSlotDemo desde './ScopedSlotDemo' 
exportar predeterminado { 
    data() { 
        return { 
            nombre:'小米', 
             sitio web: { 
                url: 'http:/ /imooc.com/',
                título: 'imooc',
  


                subtítulo: 'DreamWorks del programador' 
            },
        }; 
    }, 
    componentes:{ 
        
        ScopedSlotDemo 
    } 

}; 
</script> 

<estilo alcance lang="css"> 

</style>

 

Subensamblaje

<template> 
    <a :href="url"> 
        <slot :slotData="website1" > 
            { 
  
  {website1.subTitle}} <!-- El valor predeterminado muestra subtítulo, es decir, cuando el componente principal no pasa contenido - -> 
        </slot> </a> 
    </template> 
<script> 

exportar 
predeterminado {    props: ['url'], 
    data() { 
        return { website1: { 
                url: 'http://wangEditor.com/', 
                título: 'wangEditor', 
                subtítulo: 'Editor ligero de texto enriquecido' 
            } 
        } 
    } 
} 
</script>
 
            


 

 

 


 

 

Supongo que te gusta

Origin blog.csdn.net/admin12345671/article/details/127840095
Recomendado
Clasificación