ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

组件化开发

2021-08-11 02:02:20  阅读:206  来源: 互联网

标签:Vue const cpn app 开发 组件 data


目录

什么是组件化

  • 如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。

  • 但如果,我们将一个页面拆分成一个个的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。

Vue组件化思想

  • 提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。

  • 任何的应用都会被抽象成一棵组件树

注册组件的基本步骤

  • 组件的使用分成三个步骤
    • 创建组件构造器
    • 注册组件
    • 使用组件
<div id="app">
	// 3. 使用组件
	<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
	// 1. 创建组件构造器对象
	const contConstructor = Vue.extend({
		template: `
			<div>
				<h2>我是标题</h2>
				<p>我是内容哈哈哈哈哈</p>
				<p>我是内容呵呵呵呵呵</p>
			</div>`
	})

	// 2. 注册组件
	// component有两个参数 1-组建的标签名 2-组件构造器
	Vue.component('my-cpn', contConstructor)
	
	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		}
	})
</script>

全局组件和局部组件

全局组件,意味着可以在多个Vue的实例下面使用

上面的例子即是全局组件,验证:

<div id="app">
	<my-cpn></my-cpn>
	<my-cpn></my-cpn>
	<my-cpn></my-cpn>
</div>
<div id="ppa">
	<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>

	// 1. 创建组件构造器对象
	const contConstructor = Vue.extend({
		template: `
			<div>
				<h2>我是标题</h2>
				<p>我是内容哈哈哈哈哈</p>
				<p>我是内容呵呵呵呵呵</p>
			</div>`
	})

	// 2. 注册组件
	// component有两个参数 1-组建的标签名 2-组件构造器
	Vue.component('my-cpn', contConstructor)

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

	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		}
	})
</script>

局部组件:(开发最常用,而且一般只有一个Vue实例)

<script>

	// 1. 创建组件构造器对象
	const contConstructor = Vue.extend({
		template: `
			<div>
				<h2>我是标题</h2>
				<p>我是内容哈哈哈哈哈</p>
				<p>我是内容呵呵呵呵呵</p>
			</div>`
	})

	// 2. 注册组件
	// component有两个参数 1-组建的标签名 2-组件构造器
	// Vue.component('my-cpn', contConstructor)

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

	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		},
		components : {
			cpn : contConstructor
		}
	})
</script>

父组件和子组件

<div id="app">
 <cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>
 // 子组件
 const cpnC1 = Vue.extend({
  template : `
   <div>
    <h2>我是标题1</h2>
    <p>我是内容,哈哈哈</p>
   </div>
  `
 })
 // 父组件
 const cpnC2 = Vue.extend({
  template : `
   <div>
    <h2>我是标题2</h2>
    <p>我是内容,呵呵呵</p>
    <cpn1></cpn1>
   </div>
  `,
  components : {
   cpn1 : cpnC1
  }
 })
 // root组件
 const app = new Vue({
  el : "#app",
  data : {
   message : "你好",
  },
  components : {
   cpn2 : cpnC2
  }
 })
</script>

注册组件语法糖

<div id="app">
	<cpn1></cpn1>
	<cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>

	// 全局组件语法糖
	Vue.component('cpn1', {
		template : `
			<div>
				<h2>我是标题1</h2>
				<p>我是内容,哈哈哈</p>
			</div>
		`
	})

	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		},
		// 局部组件语法糖
		components : {
			'cpn2' : {
				template : `
			<div>
				<h2>我是标题2</h2>
				<p>我是内容,呵呵呵</p>
			</div>
		`
			}
		}
	})
</script>

组件模板的分离写法

<div id="app">
	<cpn1></cpn1>
	<cpn2></cpn2>
</div>

<!--1. script标签-->
<script type="text/x-template" id="cpn1">
<div>
	<h2>{{message}}1</h2>
	<p>我是内容,哈哈哈</p>
</div>
</script>

<!--2.template标签-->
<template id="cpn2">
	<div>
		<h2>我是标题2</h2>
		<p>我是内容,呵呵呵</p>
	</div>
</template>

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

	// 全局组件语法糖
	Vue.component('cpn1', {
		template : `#cpn1`
	})

	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		},
		components : {
			'cpn2' : {
				template : `#cpn2`
			}
		}
	})
</script>

组件可以访问Vue示例数据吗?

  • 组件是一个单独功能模块的封装:

    • 这个模块有属于自己的HTML模板,也应该有属性自己的数据data
  • 组件中的数据是保存在哪里?顶层的Vue实例中吗?

    • 组件对象也有一个data属性(也可以有methods等属性,下面我们有用到)
    • 只是这个data属性必须是一个函数
    • 而且这个函数返回一个对象,对象内部保存着数据

对于组件中的data为什么是一个函数,是保证每个组件每次返回都是独立的对象

注:其实组件原型就是指向Vue对象,所以基本上Vue有的组件都有

<div id="app">
	<cpn1></cpn1>
	<cpn2></cpn2>
</div>

<!--1. script标签-->
<script type="text/x-template" id="cpn1">
<div>
	<h2>{{message1}}1</h2>
	<p>我是内容,哈哈哈</p>
</div>
</script>

<!--2.template标签-->
<template id="cpn2">
	<div>
		<h2>{{message2}}</h2>
		<p>我是内容,呵呵呵</p>
	</div>
</template>

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

	// 全局组件语法糖
	Vue.component('cpn1', {
		template : `#cpn1`,
		data() {
			return {
				message1 : '我是标题1'
			}
		}
	})

	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		},
		components : {
			'cpn2' : {
				template : `#cpn2`,
				data() {
					return {
						message2 : '我是标题2'
					}
				}
			}
		}
	})
</script>

父子组件的通信

  • 子组件是不能引用父组件或者Vue实例的数据的。

  • 但是,在开发中,往往一些数据需要从上层传递到下层

    • 比如,在一个页面中,我们从服务器请求到了很多的数据。

    • 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。

    • 这个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件将数据传递给小组件。

  • 如何进行父子组件间的通信?Vue官方提到:

    • 通过props向子组件传递数据
    • 通过事件向父组件发送消息

props基本用法

  • 在组件中,使用选项props来声明需要从父级接收到的数据。

  • props的值有两种方式:

    • 方式一:字符串数组,数组中的字符串就是传递时的名称

    • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。

方式一:字符串数组

方式二:对象

一方面明明是一个对象,却传一个数组很奇怪,另一方面当需要对props进行类型等验证时,就需要对象写法了。

<div id="app">
	<!--<cpn :cmovies="movies" :cmessage="message" ></cpn>-->
	<cpn :cmessage="message" ></cpn>
</div>

<template id="cpn">
	<div>
		<p>{{cmessage}}</p>
		<ul>
			<li v-for="item in cmovies">
				{{item}}
			</li>
		</ul>
	</div>
</template>

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

	// 父组件传子组件 props
	const cpn = {
		template : `#cpn`,
		// 1-字符串类型
		// props : ['cmovies', 'cmessage']
		// 2-对象类型
		props : {
			// 1. 类型限制
			// cmovies : Array, cmessage : String
			// 2. 类型限制+默认值
			cmovies : {
				type : Array,
				// default : [] 如果是Array类型,或Object类型,默认值必须给一个工厂方法
				default() {
					return []
				}
			},
			cmessage : {
				type : String,
				default: '我不想看',
				required : true // 动态绑定处为必传项
			}
		}
	}

	const app = new Vue({
		el : "#app",
		data : {
			message : '我要去看',
			movies : ['海王', '海贼王', '海尔兄弟']
		},
		components : {
			cpn
		}
	})
</script>

·注意:当在props中使用驼峰命名法的时候,在动态绑定父类对象的时候一定用’-‘连接·

<div id="app">	<cpn :c-info="info" :child-my-message="message"></cpn></div><template id="cpn">	<div>		<h2>{{cInfo}}</h2>		<h2>{{childMyMessage}}</h2>	</div></template>

在props中定义为cInfo,childMyMessage

从子组件传递给父组件

  • 通常是子组件中产生一些事件,希望父组件知道,这时需要使用自定义事件来完成。

  • v-on不仅可以用于监听DOM事件,也可用于组件间的自定义事件。

    • 在子组件中,通过$emit()来触发事件

    • 在父组件中,通过v-on来监听子组件事件

<div id="app">
	<cpn @itemclick="cpnClick"></cpn>
</div>
<template id="cpn">
	<div>
		<ul>
			<li v-for="item in categories">
				<button @click="btnClick(item)">{{item.name}}</button>
			</li>
		</ul>
	</div>
</template>
<script src="../js/vue.js"></script>
<script>
	const cpn = {
		template : `#cpn`,
		data() {
			return {
				categories: [
					{id : 1, name : '热门推荐'},
					{id : 2, name : '手机数码'},
					{id : 3, name : '家用家电'},
					{id : 4, name : '电脑办公'}
				]
			}
		},
		methods : {
			btnClick(item) {
				console.log(item.name);
				this.$emit('itemclick', item)
			}
		}
	}
	const app = new Vue({
		el : "#app",
		data : {
			info : {
				name : 'lidx',
				age : 25,
				height : 1.88
			},
			message : '你好'
		},
		methods : {
			cpnClick(item) {
				console.log('父组件'+item.name);
			}
		},
		components : {
			cpn
		}
	})
</script>

父子组件通信案例

要求实现:

  1. 改变子组件中的数字,让父组件中的值改变
  2. 让子组件一中的值永远是子组件二中的值的100倍
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>

<div id="app">
	<h2>父{{num1}}</h2>
	<h2>父{{num2}}</h2>
	<cpn :number1="num1"
	     :number2="num2"
	     @num1change="num1haschange"
	     @num2change="num2haschange"></cpn>
</div>

<template id="cpn">
	<div>
		<h2>props:{{number1}}</h2>
		<h2>data:{{dnumber1}}</h2>
		<input type="text" v-model="dnumber1">
		<!--<input type="text" :value="dnumber1" @input="num1input">-->
		<h2>props:{{number2}}</h2>
		<h2>data:{{dnumber2}}</h2>
		<input type="text" v-model="dnumber2">
		<!--<input type="text" :value="dnumber2" @input="num2input">-->
	</div>
</template>
<script src="../js/vue.js"></script>
<script>
	const app = new Vue({
		el : "#app",
		data : {
			num1 : 1,
			num2 : 2
		},
		methods : {
			num1haschange (value) {
				this.num1 = parseInt(value)
			},
			num2haschange (value) {
				this.num2 = parseInt(value)
			}
		},
		components : {
			cpn : {
				template : `#cpn`,
				props : {
					number1 : {
						type : Number
					},
					number2 : {
						type : Number
					}
				},
				data () {
					return {
						dnumber1 : this.number1,
						dnumber2 : this.number2
					}
				},
				watch : {
					dnumber1(newValue) {
						this.dnumber2 = newValue * 100
						this.$emit('num1change', newValue)
					},
					dnumber2(newValue) {
						this.dnumber1 = newValue / 100
						this.$emit('num2change', newValue)
					}
				}
				/*methods : {
					num1input ( event ) {
						this.dnumber1 = event.target.value
						this.$emit('num1change', this.dnumber1)

						this.dnumber2 = this.dnumber1 * 100
						this.$emit('num2change', this.dnumber2)
					},
					num2input (event) {
						this.dnumber2 = event.target.value
						this.$emit('num2change', this.dnumber2)

						this.dnumber1 = this.dnumber2 / 100
						this.$emit('num1change', this.dnumber1)
					}
				}*/
			}
		}
	})
</script>

</body>
</html>

watch:检测对象的变化

父访问子

两种方式:

  1. 下标值(不推荐)$children==》数组,获取所有子组件
  2. 起别名 $refs==》对象,获取有ref属性的子组件
<div id="app">
	<cpn ref="cpn1"></cpn>
	<button @click="btnClick">按钮</button>
</div>

<template id="cpn">
	<div>我是子组件</div>
</template>

<script src="../js/vue.js"></script>
<script>
	const app = new Vue({
		el : "#app",
		data : {

		},
		methods : {
			btnClick() {
				console.log(this.$children[0].name);
				console.log(this.$children);  // 方式一,获取所有子组件
				this.$children[0].showMessage() // 方式一,执行子组件方法
				console.log(this.$refs.cpn1.name);
				console.log(this.$refs);      // 方式二,获取所有有ref属性的子组件
				this.$refs.cpn1.showMessage() // 方式二,执行子组件方法
			}
		},
		components : {
			cpn : {
				template : `#cpn`,
				data() {
					return {
						name : 'cpn'
					}
				},
				methods : {
					showMessage() {
						console.log("showMessage()");
					}
				}
			}
		}
	})
</script>

子访问父

开发当中不常用,也有两种

  1. $parent,访问上一级组件
  2. $root,访问根组件
<div id="app">
	<parentcpn></parentcpn>
</div>

<template id="cpn">
	<div>
		<h2>我是子组件</h2>
		<button @click="btnClick">按钮</button>
	</div>
</template>

<tempalte id="cpn_parent">
	<div>
		<h2>二级组件</h2>
		<cpn></cpn>
	</div>
</tempalte>

<script src="../js/vue.js"></script>
<script>
	const app = new Vue({
		el : "#app",
		data : {
			message : "你好",
		},
		methods : {
			showMessage2() {
				console.log('我是父组件Vue的方法');
			}
		},
		components : {
			parentcpn : {
				template : `#cpn_parent`,
				methods : {
					showMessage1() {
						console.log('我是二级组件的方法');
					}
				},
				components: {
					cpn : {
						template : `#cpn`,
						methods : {
							btnClick() {
								console.log(this.$parent);
								console.log(this.$root);
								console.log('我是子组件的方法');
								this.$parent.showMessage1()
								this.$root.showMessage2()
							}
						}
					}
				}
			}
		}
	})
</script>

标签:Vue,const,cpn,app,开发,组件,data
来源: https://www.cnblogs.com/coderElian/p/15126499.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有