Aprendizaje del marco Vue (5) Desarrollo de componentes y valor de transferencia de componentes entre padres e hijos

Sección 6: Desarrollo de componentes de Vue (1) -qué es un componente

1. ¿Qué es un componente?

1.1 Comprensión individual

La comprensión más simple es que un componente también es equivalente a una instancia pequeña de Vue, y el componente también puede tener varias propiedades de la instancia.

组件是一个完整的单位个体,可以有js可以有css和html. (Ahora no incluye css y js).

1.2 Comprensión general

Cualquiera que haya desarrollado html sabe que, de hecho, nuestra interfaz se muestra mediante el diseño de divs, y cada div tiene el contenido de visualización correspondiente. Si imaginamos estos divs como un todo, el conjunto se puede incrustar Set como un todo, y finalmente nuestra interfaz se convertirá en un pequeño módulo.

El desarrollo de componentes de Vue es este modo 先定义一个个组件(相当于一个div),组件可以嵌套,然后组成一个整体.

Como se muestra en la siguiente figura: Por lo general, una aplicación se organizará en forma de árbol de componentes anidado:
[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y subirla directamente (img-vJk7T308-1612834014926) (vue notes 2_files / 1.jpg)]

1.3 Beneficios de los componentes

可复用

低耦合

En segundo lugar, el primer uso de los componentes de Vue.

2.1 La primera forma de crear componentes:

Úselo para Vue.componentcrear un componente

  • El primer parámetro es el nombre del componente (es decir, el identificador del elemento que usaremos más adelante)
  • El segundo parámetro es el objeto, hay muchos parámetros en él, ahora solo una plantilla (plantilla) es donde almacenamos el contenido de la pantalla
Vue.component('component1',{
	template::`
	<div> 
	<h1>hello</h1>
	<h1>我的第一个组件</h1>
	</div>
	`
});

2.2 La segunda forma de crear componentes:

Regístrese en la instancia de Vue, primero defina el objeto y luego registre el componente en la propiedad de componentes de la instancia

//创建组件2 先定义好对象,然后在实例的components属性上把组件注册
const componentA ={
	template:`
	<div><h2>我的第二个组件 Hi </h2> </div>
	`
}
const app = new Vue({
	el:"#app",
	data: {
		number: 0
	},
	components:{
		'compontent2':componentA
	}
})

2.3 Uso de componentes

1) ¿Cómo usar Vue para crear componentes?

Al crear un componente, todos tenemos un logo definido, si se crea usando Vue.component 第一个参数, si está registrado en componentes对象的名称

2) Utilizar (utilizar el componente directamente con el nombre de identificación)

组件的使用必须在Vue实例的div里,超出的实例,vue无法管理就无法使用这个组件了

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>hello Vue</title>
	</head>
	<body>
		<div id="app">
			<!--直接用标识名称来使用组件-->
			<component1></component1>
			<!--组件复用-->
			<component1></component1>
			<component1></component1>
			<component2></component2>
		</div>
	</body>
	<script src="./vue.js"></script>
	<script>
	        // 创建组件1
			Vue.component('component1',{
				template:`
				<div> 
				<h1>hello</h1>
				<h1>我的第一个组件</h1>
				</div>
				`
			});
			//创建组件2 先定义好对象,然后在实例的components属性上把组件注册
			const component2 ={
				template:`
				<div> <h2>我的第二个组件 Hi </h2> </div>
				`
			}
			const app = new Vue({
				el:"#app",
				components:{
					'component2':component2
				}
			})
			
	</script>
</html>

En tercer lugar, el método de escritura independiente de la plantilla del componente Vue.

3.1 ¿Por qué utilizar escritura separada?

Sabemos 组件的展示内容是在属性template定义好的, y luego encontraremos que el contenido del div está escrito directamente en el objeto. Si el contenido simple todavía es posible, pero el desarrollo real debe ser más complicado y funcional. Si es así 直接写在对象里就有点不好维护, no es fácil entender el código. Si se libera el div correspondiente a esta plantilla, entonces nuestro objeto componente se mantendrá bien

3.2 Cómo separar elementos

Hay una plantilla de etiqueta de elemento que se puede hacer por separado. Después de definirla,定义好id,然后在对象里用’#id’就可以了

<template id="component3">
	<div>
		<h2>hhhhhhhhhhh</h2>
	</div>
</template>

<!-- 组件的对象使用(’#id’)  -->

Vue.component("component3",{
	template: '#component3'
});

Cuatro, componentes Vue-global y componentes locales

4.1 ¿Qué es un componente global?

Componentes globales: siempre que se utilicen Vue.component 来创建的组件都是全局注册的. En otras palabras, se pueden usar en la plantilla de cualquier instancia raíz de Vue recién creada (nueva Vue) después del registro, y se pueden usar tanto componentes como subcomponentes locales.
Por ejemplo, si instalas dos Vue () nuevos, este componente global se puede usar en ambas instancias. (Pero generalmente no creamos dos instancias)
El siguiente código muestra que creé un componente global, que se puede usar tanto en las instancias app como en app1

<body>
<div id="app"  >
    <component1></component1>
</div>
<div id="app1" >
    <component1></component1>
</div>

<template id="component1">
    <div style="background: darkcyan">
        <h2>我的第一个组件</h2>
    </div>
</template>
</body>
<script src="../css/vue.js"></script>
<script>
    Vue.component('component1', {
        template: '#component1'
    });
    const app = new Vue({
        el: '#app'
    })
    const app1 = new Vue({
        el: '#app1'
    })
</script>

4.2 ¿Qué es un componente parcial?

Ensamblados locales: en 实例的属性componentso 组件里的属性componentssobre el componente de registro, llamado 局部组件, 局部注册的组件在其子组件中不可用si desea usar, requieren varios archivos anidados.

Use el siguiente código para explicar: En la instancia, solo se usa el componente component2 y no se puede usar component1 porque component1 no está registrado en la instancia

<body>
<div id="app"  >
    <component1></component1>
    <!-- component2使用会报错 -->
    <component2></component2>
</div>
<template id="component1">
    <div style="background: darkcyan">
        <h2>我的第一个组件</h2>
    </div>
</template>
<template id="component2">
    <div style="background: aqua">
        <component1></component1>
        <h2>我的第二个组件</h2>
    </div>
</template>

</body>
<script src="./vue.js"></script>
<script>
	const component1 = {
        template: '#component1'
    }
    const component2 = {
        template: '#component2',
        components: {
            'component1': component1
        }
    }
    const app = new Vue({
        el: '#app',
        components: {
            'component2': component2
	       <!--'component1': component1  -->
        }
    })
</script>

manifestación:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
</head>
<body>
<div id="app"  >
    <component1></component1>
    <component2></component2>
</div>

<div id="app1" >
    <component1></component1>
</div>

<template id="component1">
    <div style="background: darkcyan">
        <h2>我的第一个组件</h2>
        <h2>你们好</h2>
    </div>
</template>

<template id="component2">
    
    <div style="background: aqua">
        <component1></component1>
        <h2>我的第二个组件</h2>
    </div>
</template>

</body>
<script src="../css/vue.js"></script>
<script>
    /**
     * 全局组件:只要是用 Vue.component 来创建的组件都是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中,局部组件和子组件都能使用
     * 比如你实例了两个new Vue();这个全局组件就可以在这两个实例上都可以使用。(但是我们一般不会创建两个实例)
     * */
    Vue.component('component1', {
        template: '#component1'
    });

    /**
     * 局部组件:在实例的属性components或者是组件里的属性components上注册组件,叫局部组件,局部注册的组件在其子组件中不可用,如果要使用需要多重嵌套
     * @type {
   
   {template: string}}
     */
    const component2 = {
        template: '#component2'
    }
    const app = new Vue({
        el: '#app',
        components: {
            'component2': component2
        }
    })

    const app1 = new Vue({
        el: '#app1',
    })

</script>
</html>

Cinco, componente principal de Vue y componente secundario

5.1 ¿Qué es un componente padre-hijo?

De hecho, el componente se registra a través de componentes y luego se anida en el componente 嵌套注册组件的就是子组件,被嵌套就是父组件.

Como se muestra en la figura, el área roja es el componente principal y el área azul anidada en el interior es el componente secundario.
[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de cadena antirrobo, se recomienda guardar el imagen y cárguela directamente (img-QZCwS4kA-1612834014930) (vue note 2_files / 2.jpg)]

注意:全局组件不存在父组件和子组件的,因为全局组件在实例里的任何地方都可以使用

5.2 La estructura del componente padre-hijo incorporado en el código

Mira el código del siguiente ejemplo

La instancia de Vue es el componente principal más grande component1注册在实例上, eso component1就是Vue实例的子组件.

component2注册在component1组件上, Eso component2就是component1组件的子组件.

<div id="app">
    <component1></component1>
</div>
<template id="component1">
    <div>
        <h2>我的第一个组件</h2>
        <component2></component2>
    </div>
</template>
<template id="component2">
    <div>
        <h2>我的第二个组件</h2>
    </div>
</template>
</body>
<script src="../css/vue.js"></script>
<script>
    const component1 = {
        template: '#component1',
        components: {
            'component2': {
                template: "#component2"
            }
        }
    }
    const app = new Vue({
        el: '#app',
        components: {
            'component1': component1
        }
    })
</script>

Seis, datos de componentes de Vue

6.1 ¿Puede un componente acceder directamente a los datos de una instancia de Vue? Por ejemplo, use { {}} directamente

La respuesta es no.

Un componente es una encapsulación de un solo módulo funcional (equivalente a una pequeña instancia de Vue), es decir, este módulo tiene su propia plantilla HTML y sus propios datos de atributos.
Echemos un vistazo al siguiente código. Usamos { {mes}} directamente en el componente secundario para usar el valor del atributo de datos del componente principal, mes

<body>
<div id="app">
    <component1></component1>
</div>
<template id="component1">
    <div>
        <h2>{
   
   {mes}}</h2>
    </div>
</template>
</body>
<script src="./vue.js"></script>
<script>
    const component1 = {
        template: '#component1'
    }
    const app = new Vue({
        el: '#app',
        data:{
          mes: "实例数据"
        },
        components: {
            'component1': component1
        }
    })
</script>

[Error en la transferencia de la imagen del enlace externo. Es posible que el sitio de origen tenga un mecanismo anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-2MDeB1Lb-1612834014933) (vue Note 2_files / 3.jpg)]

6.2 Almacenamiento de datos de componentes

El objeto componente también tiene un atributo de datos, pero data属性必须是一个函数, entonces 返回的对象, estos datos están garantizados dentro del objeto.

<body>
<div id="app">
    <component1></component1>
</div>
<template id="component1">
    <div>
        <h2>{
   
   {mes}}</h2>
    </div>
</template>
</body>
<script src="./vue.js"></script>
<script>
    const component1 = {
        template: '#component1',
        data(){
            return{mes: "实例数据"}
        },
    }
    const app = new Vue({
        el: '#app',
        components: {
            'component1': component1
        }
    })
</script>

6.3 ¿Por qué los datos del componente Vue son una función?

为什么组件的data是一个函数El sitio web oficial dice :, 一个组件的 data 选项必须是一个函数por lo que cada instancia puede mantener una copia independiente del objeto devuelto

Todos sabemos que una vez que se crea un objeto, se le asignará una dirección. Cuando todos usan el objeto, modifican el valor de propiedad del objeto. ¿Se cambia la dirección? Recuerde que muchas veces el uso de un componente tiene que repetirse. Sí, cuando reutilice, pensará que los datos de cada componente se mantienen por separado y no se afectan entre sí. 如果对象都是只是创建一次,那就会出问题了,现在有一个组件使用了两次,data内存地址都是一个,那一个组件修改了data,另一个组件的值也会跟着改变, Esto es lo último que queremos ver. Eso data是一个函数的话就不一样了,函数每次返回的对象都是一个新对象, para que los objetos de cada componente no se quieran afectar entre sí

Una oración:就是为了保证每个组件的data对象都是相互独立

Siete, comunicación del componente Vue: el componente principal pasa parámetros al componente secundario

Dijimos antes que los componentes no pueden usar directamente los datos de las instancias de Vue, pero en el proceso de desarrollo real, es normal que los componentes usen los datos de las instancias de Vue.

7.1 ¿Cómo puede un componente utilizar los datos del componente principal?

通过 Prop 向子组件传递数据

7.2 Uso de utilería

1) El valor del atributo props数组

definición

在组件对象里使用props属性,然后直接定义数组,数组的对应的值就是获取的传参的对象。

 const component1 = {
	template: "#component1",
	props: ['propsMessage','propsmessage1'],
}

usar

Al usar el componente, siempre que coloque estos valores para definir una matriz de bueno, 当成是组件的属性值puede 直接传递参数subir. (El uso de v-bind puede usar los datos del componente principal)

 <!-- 使用v-bind可以使用父组件的data数据 -->
 <component1 v-bind:props-message=message propsmessage1='参数1'></component1>

2) El valor del atributo props es un objeto.

El propósito del objeto: permite la configuración de opciones avanzadas, como 类型检测、自定义验证和设置默认值.

Puede utilizar las siguientes opciones según la sintaxis del objeto:

Valor de atributo de objeto Descripción
tipo Lo siguiente puede ser un constructor de orígenes: String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定义构造函数、或上述内容组成的数组. Verificará si un accesorio es del tipo dado; de lo contrario, se lanzará una advertencia.
predeterminado: cualquiera Especifique un valor predeterminado para esta propiedad. Si la propiedad no se pasa, use este valor en su lugar. 对象或数组的默认值必须从一个工厂函数返回.
obligatorio: booleano Defina si se requiere el accesorio. En un entorno de no producción, si este valor es verdadero y no se pasa la propiedad, se lanzará una advertencia de consola.
validador: Función 自定义验证函数会将该 prop 的值作为唯一的参数代入. En un entorno de no producción, si la función devuelve un valor falso (es decir, la verificación falla), se lanzará una advertencia de consola.

definición

Similar al número de grupos, el atributo props es la capa más grande de objetos, 属性值是传递参数对象y luego se pueden realizar varios ajustes personalizados para los parámetros pasados.

Ejemplo:

<body>
<div id="app">
    <component1 v-bind:props-message=message height="哈哈" age= -1></component1>
    <!--如果不使用v-bind会识别不了data的数据-->
   <component1 props-message=message></component1>
</div>
<template id="component1">
    <div>
        <h2>{
   
   {propsMessage}}</h2>
        <h2>{
   
   {height}}</h2>
        <h2>{
   
   {age}}</h2>
    </div>
</template>
</body>
<script src="./vue.js"></script>
<script>
    const component1 = {
        template: "#component1",
        props: {
            // 检测类型
            propsMessage: String,
            height: String,
            // 检测类型 + 其他验证
            age: {
                type: Number,
                default: 0,
                required: true,
                validator: function (value) {
                    return value >= 0
                }
            }
        }
    }
    const app = new Vue({
        el: '#app',
        data: {
            message: "你好"
        },
        components: {
            'component1': component1
        }
    })
</script>

8. Eventos personalizados de comunicación de componentes de Vue de componentes secundarios a componentes principales

1) Cómo pasar datos del componente secundario al componente principal

Cuando el componente hijo pasa datos al componente padre, es necesario utilizarlo 自定义事件para lograr

El flujo de eventos personalizados:

  • En subcomponentes, pase $emitpara desencadenar eventos

  • En el componente principal, v-onhasta escuchar los eventos del componente secundario

<!--子组件-->
<template id="component1">
    <div>
        <button @click="but">子组件按钮触发父组件事件</button>
        <button @click="but1">子组件按钮触发父组件事件并带参数</button>
    </div>
</template>

子组件的对象定义( 注意这个驼峰标识不能用,需要使用 kebab-case)

const component1 = {
        template: "#component1",
        methods: {
            but() {
                console.log("子组件按钮被触发了");
                //注意这个驼峰标识不能用,需要使用 kebab-case
                this.$emit('cpn-but');
            },
            but1() {
                console.log("子组件按钮并带参数被触发了");
                //注意这个驼峰标识不能用,需要使用 kebab-case
                //子组件按钮触发父组件事件并带参数,就在this.$emit加多一个参数对象
                this.$emit('cpn-but1', 'hhhh');
            }
        }
    }

2) Definición del componente principal

Cuando el componente principal usa el componente secundario, v-onse usa la instrucción y el valor del atributo es el nombre de este. $ Emit ('cpn-but') definido por el componente secundario

<!--父组件-->
<div id="app">
    <component1 @cpn-but="cpnBut" @cpn-but1="cpnBut1"></component1>
</div>

Luego, escriba el método de activación en los métodos del componente principal que puede aceptar la activación del componente secundario.

const app = new Vue({
        el: '#app',
        data: {
            message: "你好"
        },
        components: {
            'component1': component1
        },
        methods: {
            cpnBut() {
                console.log("父组件的方法被触发了");
            },
            cpnBut1(val) {
                console.log("父组件事件并带参数被触发了");
                console.log("参数:" + val);
            }
        }
    })

Ejemplo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
</head>
<body>
<!--父组件-->
<div id="app">
    <component1 @cpn-but="cpnBut" @cpn-but1="cpnBut1"></component1>
</div>

<!--子组件-->
<template id="component1">
    <div>
        <button @click="but">子组件按钮触发父组件事件</button>
        <button @click="but1">子组件按钮触发父组件事件并带参数</button>
    </div>
</template>

</body>
<script src="../css/vue.js"></script>
<script>
    const component1 = {
        template: "#component1",
        methods: {
            but() {
                console.log("子组件按钮被触发了");
                //注意这个驼峰标识不能用,需要使用 kebab-case
                this.$emit('cpn-but');
            },
            but1() {
                console.log("子组件按钮触并带参数被触发了");
                //注意这个驼峰标识不能用,需要使用 kebab-case
                //子组件按钮触发父组件事件并带参数,就在this.$emit加多一个参数对象
                this.$emit('cpn-but1', 'hhhh');
            }
        }
    }

    const app = new Vue({
        el: '#app',
        data: {
            message: "你好"
        },
        components: {
            'component1': component1
        },
        methods: {
            cpnBut() {
                console.log("父组件的方法被触发了");
            },
            cpnBut1(val) {
                console.log("父组件事件并带参数被触发了");
                console.log("参数:" + val);
            }
        }
    })

</script>
</html>

Referencia: https://blog.csdn.net/qq_30442207/article/details/108813033

Supongo que te gusta

Origin blog.csdn.net/weixin_44433499/article/details/113766202
Recomendado
Clasificación