其他分享
首页 > 其他分享> > 组件化开发

组件化开发

作者:互联网

目录

什么是组件化

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示例数据吗?

对于组件中的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>

父子组件的通信

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

从子组件传递给父组件

<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