vue 基础之组件化开发

注册组件

  • 组件使用的三个步骤
    • 创建组件构造器
    • 注册组件
    • 使用组件
<div id='app'>
	<my-cpn></my-cpn> ///使用组件
</div>
<script>
const myComponent = Vue.extend({
	template:`
		<div>
			<h2>标题</h2>
			<p>我是段落</p>
		</div>
	`
}); //创建组件构造器(第一步)
Vue.component('my-cpn',myComponent);//注册组件(第二步)
var app = new Vue({
	el:'#app',
})
</script>

上述步骤解析

  • Vue.extend()
    • 调用的是Vue.extend()创建的是一个组件构造器
    • 通常在创建组件构造器时,传入template代表我们自定义的组件
    • 该模板就是在使用组件的地方,要显示HTML代码
  • Vue.component()
  • 调用Vue.component是将刚才的组件构造器注册成为一个组件,并且给呀一个组件的标签名称
  • 需要连个参数:注册组件的标签名和组件构造器的名字
  • 组件必须挂载在vue实例下,否则不生效

全局和局部组件

上述通过Vue.component()注册组件时,组件的注册是全局的;该组件可以再任意Vue实例下使用
如果我们注册的组件是挂载在某个实例下,那就是局部组件

  • 全局组件
<div id='app'>
	<my-cpn></my-cpn>
</div>
<script>
const cpnC = Vue.extend({
	template: `
		<div>
			<h2>标题</h2>
		<div>
	`
}),
Vue.component('mu-cpn',cpnC);
const app = new Vue({
	el:'#app',
})
</script>
  • 局部组件
<div id='app'>
	<my-cpn></my-cpn>
</div>
<script>
var cpnC = Vue.extend({
	template:`
		<div>
			<h2>标题</h2>
		<div>
	`
});
const app = new Vue({
	el:'#app',
	conponents:{
		my-cpn:cpnC,
	}
})
</script>

父组件和子组件

组件和组件之间存在层级关系

<div id='app'>
	<myone></myone>
	<mytwo></mytwo>
</div>
<script>
const myone-c = Vue.extend({
	template:`
		<div>
			<p>正文内容</p>
		</div>
	`
}); //创建子组件构造器
const mytwo-c = Vue.extend({
	template:`
		<div>
			<h2>标题</h2>
		</div>
	`,
	components:{
		myone:myone-c,
	}
}); //创建父组件构造器,并在父组件中,注册子组件
var app = new Vue({
	el:'#app',
	components:{
		mytwo:mytwo-c //vue实例中,注册父组件
	}
})
</script>
  • 错误用法:以字标签的形式在vue实例中使用
  • 子组件注册到父组件中的components时,Vue会编译好父组件的模块
  • 该模块的内容已经决定了父组件将要渲染的HTML
  • <myone></myone>是只能在父组件中识别的,这种用法或被浏览器忽略

注册组件语法糖

可以省去Vue.extend()步骤,直接使用对象来代替

  • 全局组件
Vue.component('my-cpn',{
	template:`
		<div>
			<h2>我是标题1</h2>
			<p>我是内容, 哈哈哈哈</p>
		</div>
	`
});
  • 局部组件
const app = new Vue({
	el:'#app',
	components:{
		'my-cpn':{
			template:`
				<div>
					<h2>我是标题1</h2>
					<p>我是内容, 哈哈哈哈</p>
				</div>
			`
		}
	}
})

模板的分离写法

Vue提供了两种方案来定义HTML模块,使HTML模块能分离出来,然后挂载到对应的组件上

  • 使用<script>标签
  • 使用<template>标签
//script标签必须是text/x-tempalte类型
<script type='text/x-tempalte' id='cpn'>
	<div>
		<h2>我是标题</h2>
		<p>我是内容,哈哈哈</p>
	</div>
</script>

//template标签
<tempalte id='cpn'>
	<div>
		<h2>我是标题</h2>
		<p>我是内容,哈哈哈</p>
	</div>
</tempalte>
Vue.component('myone',{
	template:'#cpn'
});
const app = new Vue({
	el:'#app'
})

组件中的数据

  • 组件访问vue实例数据
  • 组件是一个单独功能模块的封装,有自己的数据data
  • 但是我们不能直接访问vue实例中的data数据,因为vue组件应该有自己保存数据地方
  • 组件数据的存档
  • 组件对象也有一个data属性(也可以有methods等属性)
  • 是指这个data属性必须是一个函数,并且函数返回一个对象,对象内部保存着数据
Vue.component('cpn',{
	template:'#cpn',
	data(){
		retuen {
			title:'abc'
		}
	}
})

组件数据为什么是函数?
首先,如果不是函数,Vue直接就会报错
其次,Vue让每个组件对象都返回一个新的对象

组件中数据传递
  • 父级向子级传递
    • 子组件不能引用父组件或者vue实例的数据
    • 开发中,需要数据从上层传递到下层,这时候,就需要让父组件将数据传递给子组件
  • 父子组件之间如何通信?
    • 父组件通过props向子组件传递数据
    • 子组件通过事件向父组件发送消息
props基本用法
  • 使用props来声明需要从父级接收到的数据
  • props的两种传值方式
    • 方式一:字符串数组,数组中的字符串就暗示传递时的名称
    • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值
      实例
<div id='app'>
	<myone-c :one='messenge'></myone-c>
</div>
<tempalte id='myone'>
	<div>{{messenge}}</div>
</template>
const app = new Vue({
	el:'#app',
	data:{
		messenge:'天气不错',
	},
	components:{
		'myone-c':{
			template:'#myone',
			props:['one']
		}
	}
})
子级向父级传递
  • props用于父组件想子组件传递数据,还有一种是子组件传递数据或者事件到父组件中
  • 我们用自定义事件来完成
    • 什么时候需要自定义事件呢
      • 当子组件需要向父组件传递数据;
      • 之前学习的v-on不仅仅用来监听DOM事件,还可以用于组件之间的自定义事件
    • 自定义事件的流程
      • 在子组件中,使用$emit来触发事件
      • 在父组件中,使用v-on来监听子组件事件
<div id="app">
		<cpn @increment='changeTotal' @decrement='changeTotal'></cpn>
		<h2>点击次数:{{total}}</h2>
	</div>
	<template id="children">
		<div>
			<button type="button" name="button" @click="increment">+1</button>
			<button type="button" name="button" @click="decrement" :disabled="counter <= 0 ">-1</button>
		</div>
	</template>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				total:0
			},
			methods:{
				changeTotal(counter){
					this.total = counter;
				}
			},
			components:{
				'cpn':{
					template:'#children',
					data(){
						return {
							counter:0
						}
					},
					methods:{
						increment(){
							this.counter++;
							this.$emit('increment',this.counter);
						},
						decrement(){
							this.counter--;
							this.$emit('decrement',this.counter);
						}
					}
				}
			}
		})
	</script>
父子组件之间的数据访问
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值