Vue.js 学习笔记九:组件化开发之组件数据存放二

目录

组件数据存放二

双向绑定案例

methods 实现

watch 实现

父组件中使用 v-model

父子组件访问方式


组件数据存放二

双向绑定案例

 

methods 实现

		<div id="app">
			<my-input :input="inputVule" @change="changeVal" />			
		</div>
		<template id="my-input">
			<div>
				<input type="text" v-model="value" @input="change" />
                <!-- 等同于 -->
                <!-- <input type="text" @input="change(value = $event.target.value)" /> -->
				<p>props 当前值:{{ input }}</p>
				<p>data 当前值:{{ value }}</p>
			</div>
		</template>
		<script type="text/javascript">
			const app = new Vue({
				el: '#app',
				data:{
					inputVule: ‘props value’
				},
				methods:{
					changeVal(value) {
						this.inputVule = value
					}
				},
				components:{
					'my-input': {
						props: {
							input : String
						},
						template: '#my-input',
						methods: {
							change() {
								this.$emit('change', this.value)
							}
						},
						data() {
							return {
								value: 'data value'
							}
						}
					}
				}
			})
		</script>

 

watch 实现

		<div id="app">
			<my-input @change="changeVal" :input="inputVule" />			
		</div>
		<template id="my-input">
			<div>
				<input type="text" v-model="value" />
				<p>props 当前值:{{ input }}</p>
				<p>data 当前值:{{ value }}</p>
			</div>
		</template>
		<script type="text/javascript">
			const app = new Vue({
				el: '#app',
				data:{
					inputVule: 'props value'
				},
				methods:{
					changeVal(value) {
						this.inputVule = value
					}
				},
				components:{
					'my-input': {
						props: {
							input : String
						},
						template: '#my-input',
						data() {
							return {
								value: 'data value'
							}
						},
						watch: {
							value(newVal, oldVal) {
								console.log(newVal)
                                console.log(oldVal)
								this.$emit('change', newVal)														}
						}
					}
				}
			})
		</script>

 

父组件中使用 v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的model 选项可以用来避免这样的冲突:

<div id="app">
			<my-checkbox v-model="checkValue" />			
		</div>
		<template id="my-checkbox">
			<div>
				<input type="checkbox" :checked="checked" @change="changeVal" />
				<p>props 当前值:{{ checked }}</p>
				<p>data 当前值:{{ value }}</p>
			</div>
		</template>
		<script type="text/javascript">
			const app = new Vue({
				el: '#app',
				data:{
					checkValue: false
				},
				components:{
					'my-checkbox': {
						props: {
							checked : Boolean
						},
						model: {
							prop: 'checked',
							event: 'change'
						},
						template: '#my-checkbox',
						data() {
							return {
								value: false
							}
						},
						methods: {
							changeVal(event) {
								this.value = event.target.checked
								this.$emit('change', this.value)
							}
						}
					}
				}
			})
		</script>

 

父子组件访问方式

有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问跟组件。

父组件访问子组件:使用 $children$refs

子组件访问父组件:使用 $parent

$children

		<div id="app">
			<parent-c></parent-c>
		</div>
		<template id="parent">
			<div>
				<button @click="getChildC">获取所有子组件信息</button>
				<child-c1></child-c1>
				<child-c2></child-c2>
			</div>
		</template>
		<template id="child1">
			<div>
				<p>{{ msg }}</p>
			</div>
		</template>
		<template id="child2">
			<div>
				<p>{{ msg }}</p>
			</div>
		</template>
		<script type="text/javascript">
			Vue.component('parentC', {
						template: '#parent',
						methods: {
							getChildC() {
								const children = this.$children;
								for (let child of children) {
									console.log(child.msg);		
								}														
							}
						},
						components:{
							'child-c1': {
								template: '#child1',
								data() {
									return {
										msg: '我是子组件1信息'
									}
								}
							},
							'child-c2': {
								template: '#child2',
								data() {
									return {
										msg: '我是子组件2信息'
									}
								}
							}
						}
					})
			const app = new Vue({
				el: '#app'
			})
		</script> 

$refs

$children有个缺陷,通过 $children 访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值。但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至还可能会发生变化。有时候,我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs

$refsref 指令通常是一起使用的。

我们先通过 ref 给某一个子组件绑定一个特定的 ID。再通过this.$refs.ID 就可以访问到该组件了。

		<div id="app">
			<parent-c></parent-c>
		</div>
		<template id="parent">
			<div>
				<button @click="getChildC">获取所有子组件信息</button>
				<child-c1 ref="child1"></child-c1>
				<child-c2 ref="child2"></child-c2>
			</div>
		</template>
		<template id="child1">
			<div>
				<p>{{ msg }}</p>
			</div>
		</template>
		<template id="child2">
			<div>
				<p>{{ msg }}</p>
			</div>
		</template>
		<script type="text/javascript">
			Vue.component('parentC', {
						template: '#parent',
						methods: {
							getChildC() {
								/* const children = this.$children;
								for (let child of children) {
									console.log(child.msg);		
								} */
								console.log(this.$refs.child1.msg);	
								console.log(this.$refs.child2.msg);
							}
						},
						components:{
							'child-c1': {
								template: '#child1',
								data() {
									return {
										msg: '我是子组件1信息'
									}
								}
							},
							'child-c2': {
								template: '#child2',
								data() {
									return {
										msg: '我是子组件2信息'
									}
								}
							}
						}
					})
			const app = new Vue({
				el: '#app'
			})
		</script>

$parent

如果我们想在子组件中直接访问父组件,可以通过$parent

		<div id="app">
			<parent-c></parent-c>
		</div>
		<template id="parent">
			<div>
				<button @click="getChildC">获取所有子组件信息</button>
				<child-c1 ref="child1"></child-c1>
				<child-c2 ref="child2"></child-c2>
			</div>
		</template>
		<template id="child1">
			<div @click="showParent">
				<p>{{ msg }}</p>
			</div>
		</template>
		<template id="child2">
			<div @click="showParent">
				<p>{{ msg }}</p>
			</div>
		</template>
		<script type="text/javascript">
			Vue.component('parentC', {
						template: '#parent',
						data() {
							return {
								msg: '我是父组件信息'
							}
						},
						methods: {
							getChildC() {
								/* const children = this.$children;
								for (let child of children) {
									console.log(child.msg);		
								} */
								console.log(this.$refs.child1.msg);	
								console.log(this.$refs.child2.msg);
							}
						},
						components:{
							'child-c1': {
								template: '#child1',
								data() {
									return {
										msg: '我是子组件1信息'
									}
								},
								methods: {
									showParent() {
										console.log(this.$parent.msg)
									}
								}
							},
							'child-c2': {
								template: '#child2',
								data() {
									return {
										msg: '我是子组件2信息'
									}
								},
								methods: {
									showParent() {
										console.log(this.$parent.msg)
									}
								}
							}
						}
					})
			const app = new Vue({
				el: '#app'
			})
		</script>

注意事项: 尽管在 Vue 开发中,我们允许通过 $parent 来访问父组件,但是在真实开发中尽量不要这样做。 子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。 如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题。 另外,更不好做的是通过 $parent 直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stary1993

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值