Vue.js的组件化思想--下

Vue.js的组件化思想--下

一、组件间的通信

       组件实例的作用域是孤立的;这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。

 

       在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。如下图所示:

  

二、 Prop — 父组件传递数据给子组件

 

       prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项声明 “prop”:

Vue.component(‘child‘, {

// 声明 props

props: [‘message‘],

// 就像 data 一样,prop 可以用在模板内

// 同样也可以在 vm 实例中像 “this.message” 这样使用

template: ‘<span>{{ message }}</span>‘

})

2.1 简单的传值 

 

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Prop — 父组件传递数据给子组件</title>
</head>
<body>
<!-- 父组件 -->
<div id="app">
	<!-- 子组件 -->
	<my-div message="今天要下雨" imgsrc="./img/a.jpg"></my-div>
	<my-div message="明天要出太阳" imgsrc="./img/2.jpg"></my-div>
</div>

<!-- 子组件 -->
<template id="my_div">
	<div>
		<h1>{{message}}</h1>
		<img :src="imgsrc" width="200">
	</div>
</template>

<script_top src="js/vue.js"></script_top>
<script_top>

	// 1.创建组件 全局组件component
	Vue.component(‘my-div‘,{
		template:‘#my_div‘,
		// 希望每一个子组件都不一样。
		// Prop — 父组件传递数据给子组件
		// 声明 props  简单通信
		props:[‘message‘,‘imgsrc‘]
	})

	new Vue({
		el:‘#app‘,
		data:{
			message:‘你好,世界!‘
		}
	})
</script_top>
</body>
</html>

运行结果:

2.2  父组件传值给子组件,动态绑定

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>多次组件之间的通信</title>
</head>
<body>
<div id="app">
	<my-parent :imgtitle="title" :imgsrc="img"></my-parent>
</div>
<!-- 子组件1 -->
<template id="my_img">
	<img :src="imgsrc" width="200">
</template>
<!-- 子组件2 -->
<template id="my_title">
	<h2>{{title}}</h2>
</template>
<!-- 父组件 -->
<template id="my_parent">
	<div>
		<child1 :imgsrc="imgsrc"></child1>
		<child2 :title="imgtitle"></child2>
	</div>
</template>

<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.子组件的实例 子组件构造器Vue.extend
	let Child1 = Vue.extend({
		template:‘#my_img‘,
		props:[‘imgsrc‘]
	});
	let Child2 = Vue.extend({
		template:‘#my_title‘,
		props:[‘title‘]
	});

	// 2.注册父组件 指定组件的名称. 全局组件component
	Vue.component(‘my-parent‘,{
		template:‘#my_parent‘,
		// Prop — 父组件传递数据给子组件
		props:[‘imgtitle‘,‘imgsrc‘],
		// 子组件  局部组件components
		components:{
			‘child1‘:Child1,
			‘child2‘:Child2
		}

	});

	new Vue({
		el:‘#app‘,
		data:{
			title:‘我是不是很美!!!‘,
			img:‘./img/1.jpg‘
		}
	})
</script_top>
</body>
</html>

  

运行结果:

三、自定义事件

      我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!

每个 Vue 实例都实现了事件接口(Events interface),即:

使用 $on(eventName) 监听事件

使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

一个简单的案例帮助我们来理解:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>
    <p>所有按钮一共点击{{totalCounter}}次数</p>
</div>

<template id="my_btn">
	<button @click="total()">点击了{{counter}}次</button>
</template>
<script_top src="js/vue.js"></script_top>
<script_top>
	Vue.component("my-btn",{
		template:"#my_btn",
		data(){
			return {
				counter:0
			}
		},
		methods:{
			total(){
				this.counter+=1; 

				// 通知外界,我调用了这个方法
				this.$emit(‘total‘);
			}
		}
	});

	new Vue({
		el:‘#app‘,
		data:{
			totalCounter:0
		},
		methods:{
			allcounter(){
				this.totalCounter+=1;
			}
		}
	})
</script_top>
</body>
</html>

  

运行结果:

运行结果:子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

四、Slot插槽 — 实现内容分发

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译

       上面话的意思在于:在子组件中定义的数据,只能用在子组件的模板;在父组件中定义的数据,只能用在父组件的模板。如果父组件的数据要在子组件中使用,则需要子组件定义props。

4.1  什么是slot?

slot的意思是插槽,其目的在于让组件的可扩展性更强。打个比方说:假如父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的。

(1) 匿名solt

下面这个示例是一个匿名slot,它只能表示一个插槽:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>24.Vue的匿名solt</title>
</head>
<body>
<div id="app">
    <my-slot>
		<img src="./img/a.jpg" >
		<p>好帅啊!</p>
		<input type="date">
    </my-slot>
</div>

<template id="my_slot">
	<div id="pater">
		<h2 class="pater-header">插槽的头部</h2>
		<!-- 预留一个插槽 -->
		<slot>可以替换任何标签,默认显示提示内容。</slot>
		<footer>插槽的尾部</footer>
	</div>
</template>
<script_top src="js/vue.js"></script_top>
<script_top>
	Vue.component(‘my-slot‘,{
		template:‘#my_slot‘
	});
	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>

  

运行结果:

        结合上述案例,我们再进一步来了解:比如我们定制了一个button组件,在根组件里注册为vButton,从而复用。那么各个button上的文字肯定是不同的,但是这些文字大部分情况下也是不需要动态更新的,那么就不必用props之类的方法从根组件向子组件传递文字,直接用slot即可。

(2) 实名solt

       假设你的电脑主板上的各种插槽,有插CPU的,有插显卡的,有插内存的,有插硬盘的,所以假设有个组件是computer,其模板是:

<template id="computer">

<div>

<slot name="CPU">这儿插你的CPU</slot>

<slot name="GPU">这儿插你的显卡</slot>

<slot name="Memory">这儿插你的内存</slot>

<slot name="Hard-drive">这儿插你的硬盘</slot>

</div>

</template>

那么,你想要配置一台电脑,就可以这么写:

<computer>

<div slot="CPU">Intel Core i7</div>

<div slot="GPU">GTX980Ti</div>

<div slot="Memory">Kingston 32G</div>

<div slot="Hard-drive">Samsung SSD 1T</divt>

</computer>

具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Vue的实名solt</title>
</head>
<body>
<div id="app">
    <my-computer>
    	<div slot="cpu">Inter Core i8</div>
    </my-computer>
</div>

<template id="my_computer">
	<div id="main">
		<slot name="cpu">这里是插cpu的</slot>
		<slot name="gpu">这里是插gpu的</slot>
		<slot name="memory">这里是插内存条的</slot>
		<slot name=" hardpan">这里是插硬盘的</slot>
	</div>
</template>
<script_top src="js/vue.js"></script_top>
<script_top>
	// component全局组件
	Vue.component(‘my-computer‘,{
		template:‘#my_computer‘
	})

	new Vue({
		el:‘#app‘,
		data:{
			message:‘你好,世界!‘
		}
	})
</script_top>
</body>
</html>

  

运行结果:

 

原文地址:https://www.cnblogs.com/yimiflh/p/9280625.html

时间: 2024-10-17 14:31:39

Vue.js的组件化思想--下的相关文章

Vue.js的组件化思想 —下

一.组件间的通信          组件实例的作用域是孤立的:这意味着不能并且不应该在子组件的模板内直接引用父组件的数据.但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件.          在 Vue.js 中,父子组件的关系可以总结为 props down, events up .父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息.如下图所示: 二. Prop — 父组件传递数据给子组件          pr

Vue.js的组件化思想--上

Vue.js的组件化思想--上 一.Vue中的组件 Vue视图层的灵魂 -  组件化 组件(Component)是 Vue.js 最强大的功能之一: 组件可以扩展 HTML 元素,封装可重用的代码: 在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 二.全局组件的创建和注册  全局组件-步骤:1.创建组件Vue.extend(),指定组件的名称--2.注册组件Vue.component()--3.

Vue.js-资料-组件化思想 —上

一.Vue中的组件 Vue视图层的灵魂 -  组件化 组件(Component)是 Vue.js 最强大的功能之一: 组件可以扩展 HTML 元素,封装可重用的代码: 在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 二.全局组件的创建和注册 案例代码: 调用Vue.extend()创建的是一个组件构造器,构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML: 调用Vu

前端组件化思想理解

一.组件化思想概念 1. 思想背景 1.1业务场景 在做一次项目需求开发的过程中,涉及到动态创建多个条件区域,对于每个单独的条件区域,分为左边表格数据区和右边勾选左边表格某些数据行的区域.具体到左边表格数据区,包括一个通过用户输入的某个条件来查询数据,以一个表格分页的形式展示出来.其中这个表格里面包括复选框,可以选择表格中的某些项,然后右边区进行展示. 1.2最开始想的笨办法 因为这个需求是在原有基础上进行开发,平时的思维就是在既有的这个页面的js中进行代码开发.但是在开发过程中,并不是那么理想

Vue.js之组件嵌套小demo

Vue.js之组件嵌套的小demo项目 第一步:初始化一个wabpack项目,这里不在复述.第二步:在components文件夹下新建Header.vue Footer.vue和Users.vue三个组件文件 Header.vue文件: 1 <!--1模板:html结构 --> 2 <template> 3 <header> 4 <h1>{{title}}</h1> 5 </header> 6 </template> 7

Vue.js之组件嵌套

Vue.js中组件嵌套有两种方式 第一种:注册全局组件 例如在components文件夹下新建一个User.vue组件,然后在main.js文件中注册全局组件 1 //注册全局组件 2 Vue.component("users",Users); //前面的users是我们起的名字,后面的Users是我们对应的组件,想要识别这个组件,必须在上面通过import引入, 3 //引入组件 4 import Users from './components/Users' 有了全局组件的话,就可

Vue.js父子组件如何传值

https://blog.csdn.net/qq_40259641/article/details/81265950 Vue.js父子组件如何传值 通俗易懂原创 阿猫阿狗哈 发布于2018-07-28 22:04:42 阅读数 14278 收藏展开父子组件传值原理图 一般页面的视图App.vue应为这样 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Child.vue2.Child.vue的中创建props,然后创建一个名为message的属性 3.在A

Webpack+Vue+ES6 前端组件化开发mobile-multi-page应用实战总结

本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.写在前面 项目上线有一段时间了,一个基于webpack+vue+ES6的手机端多页面应用.其实说是多页面应用,实际上在webpack中属于四个app,  如果真是做纯单页面,那应该有二三十个页面吧.所以我这里的多页面应用,是分为四个SPA.比如微信最下面,有四个导航,微信,通讯录,发现,我. 那么这四个导航,就是我的四个SPA,配置多个入口即可. 在这里就不说太多代码了,项目结构将会放

Vue.js路由组件vue-router如何使用?

使用 Vue.js + vue-router 创建单页应用是非常简单的,只需要配置组件和路由映射,然后告诉 vue-router 在哪里渲染即可.本文和大家分享的就是vue-router的相关使用方法,希望对大家学习Vue.js有所帮助. 一 普通方式基本例子: <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <titl