vue组件化(vue2)

vue组件化

任何应用都可以抽象成一颗组件树

组件注册过程

  • 创建组件构造器 Vue.extend 要传一个对象,一个模板
  • 注册组件 Vue.component
  • 使用组件
		//1.第一种方法
		//vue cli 脚手架构造vue项目 vue构造vue
		//必须得放在实例中,比如<div>标签下,否则无用,而且得是vue实例
		//全局组件
		<div id="app">
			<my-cpn></my-cpn>
		</div>
		<script type="text/javascript">
			//1.构造
			const cpnC=Vue.extend({
				template:`<h1>Hello World</h1>`
			})
			//2.注册 全剧注册
			//Vue.component(组件名,组件构造器)
			Vue.component('my-cpn',cpnC);
			const app=new Vue({
				el:"#app",
		</script>

全局组件

全局都可以使用

局部组件

局部注册

		<div id="app">
			<my-cpn></my-cpn>
			<!-- <myCpn2></myCpn2> --><!--错误-->
			<my-cpn2></my-cpn2>
		</div>
		<script type="text/javascript">
			//1.构造  全局组件
			const cpnC=Vue.extend({
				template:`<h1>Hello World</h1>`
			})
			//2.注册
			//Vue.component(组件名,组件构造器) 注册方式是全局注册
			Vue.component('my-cpn',cpnC);
			const app=new Vue({
				el:"#app",				
				components:{
					//cpn是注册组件的标签名,不能携带-,否则报错,可以使用驼峰命名,然后标签名用-链接
					myCpn2:cpnC
				}
			})
		</script>

父子组件

		<div id="app">
			<cpn2></cpn2>
			<!-- <cpn1></cpn1> --><!--错误,要么全局,要么在实例中-->
		</div>
		<script type="text/javascript">
			//1.构造 第一个
			const cpnC1=Vue.extend({
				template:`<h1>我是子组件</h1>`
			})
			//2.构造第二个
			const cpnC2=Vue.extend({
				template:`
				<h1>我是父组件</h1>
				<cpn1></cpn1>
				
				`,
				components:{
					//cpnC2父组件,cpnC1子组件 本质来看vue也是一个父组件而且是顶层组件,root
					//关键的父组件必须包含子组件,也就是不能让子组件并行和其她标签显示
					/*
					对的
					template:`
					<div>
						<h1>我是父组件</h1>
						<cpn1></cpn1>
					</div>
					`,
					错的
					template:`
					<h1>我是父组件</h1>
					<cpn1></cpn1>
					`,
					错误为 template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
					也就是说要有个根
					*/
					cpn1:cpnC1
				}
			})
			
			
			const app=new Vue({
				el:"#app",				
				components:{
					//cpn是注册组件的标签名,不能携带-,否则报错,可以使用驼峰命名
					cpn2:cpnC2
				}
			})
		</script>
父子组件语法糖

全局组件

		<div id="app">
			<cpn1></cpn1>
		</div>
		<script type="text/javascript">
			//1.
			Vue.component('cpn1',{
				template:`<div><h1>hello</h1></div>`
			})
			const app=new Vue({
				el:"#app",				
				components:{

				}
			})
		</script>

局部组件

		<div id="app">
			<cpn1></cpn1>
			<cpn2></cpn2>
		</div>
		<script type="text/javascript">
			//1.全局
			Vue.component('cpn1',{
				template:`<div><h1>全局注册语法糖</h1></div>`
			})
			const app=new Vue({
				el:"#app",				
				components:{
					//局部
					'cpn2':{
						template:`<div><h1>局部注册语法糖</h1></div>`
					}
				}
			})
		</script>

组件模板抽离

一旦在模板中出现了很多的html将会很复杂

  • 在script里写
  • template标签里写
	<body>
		<div id="app">
			<cpn1></cpn1>
			<cpn2></cpn2>
		</div>
		<script type="text/x-template" id="cpn">
			<div>
				<h1>
					script type="text/x-template"
					在这个标签里写
				</h1>
			</div>
		</script>
		<template id="cpn2">
			<div>
				<h1>
					template
					在这个标签里写
				</h1>
			</div>
		</template>
		<script type="text/javascript">
			//1.全局
			Vue.component('cpn1',{
				template:"#cpn"
			})
			const app=new Vue({
				el:"#app",				
				components:{
					//局部
					'cpn2':{
						template:"#cpn2"
					}
				}
			})
		</script>
	</body>
	```
### 父子组件通信
* vue组件应该有自己保存数据的地方、
* 组件无法访问vue实例,假设即使可以访问,但是数据过多会臃肿
* 组件也可以传值,在component里传一个data,但不能是对象类型,要return,是一个函数,而且这个和vue很像

组件之间的属性与方法调用
	<div id="app">
		<cpn1></cpn1>
		<cpn2></cpn2>
	</div>
	<script type="text/x-template" id="cpn">
		<div>
			<h1>
				script type="text/x-template"
				在这个标签里写
				{{msg1}}
				计数器:{{counter}}
				<button @click="counter++">+</button>
				<!-- <button @click="add()">+</button> -->
				<button @click="counter--">-</button>
			</h1>
		</div>
	</script>
	<template id="cpn2">
		<div>
			<h1>
				template
				在这个标签里写
				{{msg2}}
			</h1>
		</div>
	</template>
	<script type="text/javascript">
		//1.全局
		Vue.component('cpn1',{
			template:"#cpn",
			data(){
				//不能是类
				return{
					msg1:'abc',
					counter:0
				}
			},
			methods:{
				add(){
					this.counter++;
				}
			}
			
		})
		const app=new Vue({
			el:"#app",
			data:{
				msg:"hhhh"
			},
			components:{
				//局部
				'cpn2':{
					template:"#cpn2",
					data(){
						return{
							msg2:"abc2"
						}
					}
				}
			}
		})
	</script>

父子组件传值
* 子组件注册时,定义props用来接收数据
* 子组件模板定义时,调用数据
* 父组件引用子组件,给他绑定参数,:
* props:可以传数组,也可以类


**父传子**
	<div id="app">
		<cpn1 :cmovies="movies" :cmsg="msg"></cpn1>
	</div>
	<script type="text/x-template" id="cpn">
		<div>
			<h1 v-for="c in cmovies">
				{{c}}
			</h1>
			<h1>{{cmsg}}</h1>
		</div>
	</script>
	<script type="text/javascript">
		//父传子 props
		const cpn={
			template:"#cpn",
			props:['cmovies','cmsg'],
			data(){
				return {}
			}
		};
		//root组件
		const app=new Vue({
			el:"#app",
			data:{   
				movies:['o1','zio','build'],
				msg:"hello"
			},
			components:{
				//局部
				'cpn1':cpn
			}
		})
	</script>
类传值
``` 注意驼峰标识,如果定义时,为大写,使用时要改成—

子传父

		<div id="app">
			<cpn1 @itemclick='cpnClick'></cpn1>
		</div>
		<script type="text/x-template" id="cpn">
			<div>
				<button v-for="(item,index) in categories" @click="btnClick(item)">
				{{item.name}}
				</button>
				{{cl}}
			</div>
		</script>
		<script type="text/javascript">
			//子传父
			const cpn={
				template:"#cpn",
				data(){
					return {
						categories:[
							{id:'aaa',name:'热门推荐'},
							{id:'bbb',name:'手机数码'},
							{id:'ccc',name:'服装衣服'},
							{id:'ddd',name:'电脑办公'}
						],
						cl:''
					}
				},
				methods:{
					btnClick(item){
						//子组件发射事件,事件名字,参数
						this.$emit('itemclick',item);
						this.cl=item.name;
					}
				}
			};
			//root组件
			const app=new Vue({
				el:"#app",
				data:{
				},
				methods:{
					cpnClick(item){
						console.log(item);
						
					}
				},
				components:{
					//局部
					'cpn1':cpn
				}
			})
		</script>

父子组件通信
watch
children-refs
父访问子
parent-root
子访问父

组件插槽solt

使用方法:<slot></slot>此时调用子组件时,在组件标签里往下添加标签即可<cpn1 @itemclick='cpnClick'><button></button></cpn1>
同时也可以给插槽默认值:<slot><button></button></slot>

具名插槽

如何修改具体插槽,给插槽设置name,不同的不会替换,没有Name会替换,同理要提替换,只需组件调用插槽名字即可

		//会显示按钮和左中右
		<div id="app">
			<cpn1 @itemclick='cpnClick'>
				
			</cpn1>
		</div>
		<script type="text/x-template" id="cpn">
			<div>
				<button v-for="(item,index) in categories" @click="btnClick(item)">
				{{item.name}}
				</button>
				{{cl}}
				<!-- <slot><button></button></slot> -->
				 <slot name="left">leftt</slot>
				 <slot name="mid">zhong</slot>
				 <slot name="right">you</slot>
			</div>
		</script>
		//显示标题太
		<div id="app">
			<cpn1 @itemclick='cpnClick'>
				标题太
			</cpn1>
		</div>
		<script type="text/x-template" id="cpn">
			<div>
				<button v-for="(item,index) in categories" @click="btnClick(item)">
				{{item.name}}
				</button>
				{{cl}}
				<!-- <slot><button></button></slot> -->
				 <slot >leftt</slot>
				 <slot>zhong</slot>
				 <slot >you</slot>
			</div>
		</script>
		//显示左中右
		<div id="app">
			<cpn1 @itemclick='cpnClick'>
				标题太
			</cpn1>
		</div>
		<script type="text/x-template" id="cpn">
			<div>
				<button v-for="(item,index) in categories" @click="btnClick(item)">
				{{item.name}}
				</button>
				{{cl}}
				<!-- <slot><button></button></slot> -->
				 <slot name="left">leftt</slot>
				 <slot name="mid">zhong</slot>
				 <slot name="right">you</slot>
			</div>
			
			//标题 zhong you,记住不能直接绑在组件标签里
			<div id="app">
				<cpn1 @itemclick='cpnClick'>
					<span slot="left">标题</span>
				</cpn1>
			</div>
			<script type="text/x-template" id="cpn">
				<div>
					<button v-for="(item,index) in categories" @click="btnClick(item)">
					{{item.name}}
					</button>
					{{cl}}
					<!-- <slot><button></button></slot> -->
					 <slot name="left">leftt</slot>
					 <slot name="mid">zhong</slot>
					 <slot name="right">you</slot>
				</div>
			</script>

编译作用域

作用域插槽,父组件替换插槽的标签,但是内容由子组件来提供

commonJS

let {} require()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值