vue组件传值-详细代码版

Vue数据传递

关系:父亲、孩子

1.$emit / props / v-model

父传子 props
Father.vue

<template>
    <div>
        <h1>家庭资产:{{ fatherM }}</h1> 
        <Child :fatherM="fatherM" />
    </div>
</template>
<script>
import Child from "./Child.vue";
export default {
    name: "Father",
    components: { Child },
    data() {
        return {
            fatherM: 3000,
        };
    },
};
</script>

Child.vue

<template>
    <div>
        <h2>子女资产:{{ fatherM }}</h2>
    </div>
</template>
<script>
export default {
    name: "child",
    //详细props写法请看另一篇文章 https://blog.csdn.net/Jenny_ljj/article/details/117282848
    props: {
        fatherM: Number,
    },
  
};
</script>

子传父 $emit
Father.vue

<template>
    <div>
    	<h1>家庭资产:{{ fatherM }}</h1>
    	<!-- 有几种写法 -->
        <Child @setMoney="getMoneyUU" />
        <Child @update:value="(value) => (this.fatherM = value)" />
        <Child :value.sync="fatherM" /> <!-- 语法糖  -->
        <Child @setMoney="(fatherM) => (this.fatherM = fatherM)" />
    </div>
</template>
<script>
import Child from "./Child.vue";
export default {
    name: "Father",
    components: {  Child },
    data() {
        return {
            fatherM: 0,
        };
    },
    methods: {
        getMoneyUU(num) {
            this.fatherM = num
        },
    },
};
</script>

Child.vue

<template>
    <div>
        <button @click="getMoney">给爸爸的零花钱</button>
    </div>
</template>
<script>
export default {
    name: "child", 
    methods: {
        getMoney() {
            this.$emit("setMoney", 10000);
            // this.$emit("update:value", 10000);
        },
    },
};
</script>

子传父 v-model
Father.vue

 		<Child
            :fatherM="fatherM"
            @update:fatherM="(fatherM) => (this.fatherM = fatherM)"
        />
        等于
        <Child v-model="fatherM" />

Child.vue

 this.$emit("update:fatherM", 1000);

关系:爷爷,爸爸

2. $refs / ref

子传父 !!!
Grandpa.vue

<template>
    <div>
        <!-- ref : dom节点 => 返回的是dom对象 
        ref : 组件 => 返回的是组件实例 -->
        <Father ref="father" />
    </div>
</template>
<script>
import Father from "./Father.vue";
export default {
    name: "Grandpa",
    components: { Father },
    mounted() {
        console.log(this.$refs.father.name);
        this.$refs.father.getCall();
    }
};
</script>

Father.vue

<script>
export default {
    name: "Father",
    data() {
        return {
            name: "李四",
            age: 12,
            sex: "男",
        };
    },
    methods: {
        getCall() {
            console.log("好吧好吧");
        },
    },
};
</script>

关系:爷爷, 爸爸 , 孩子

3.provide / inject

父传子(爷爷 -> 爸爸 -> 孩子)
grandpa.vue

<template>
    <div>
        <Father />
    </div>
</template>

<script>
import Father from "./Father.vue";
export default {
    // 提供者
    provide() {
        return {
            grandpa: this,
        };
    },
    name: "Grandpa",
    components: { Father },
    data() {
        return {
            name: "张三",
            age: 12,
            sex: "男",
        };
    },
    methods: {
        notice() {
            console.log(1256546);
        },
    },
};
</script>

Father.vue

<template>
    <div>
        <Child />
    </div>
</template>

<script>
import Child from "./Child.vue";
export default {
    name: "Father",
    // 注入
    inject: ["grandpa"],
    components: { Child },
    mounted() {
   // this 是页面自身的实例对象,然后爷爷把自己页面的内容通过inject注入到了父亲自身的实例对象中 如下图
      console.log(this);
    },
};
</script>

Child.vue

<script>
export default {
    // 注入
    inject: ["grandpa"],
    name: "Child",
    mounted() {
    // this 是页面自身的实例对象,然后爷爷把自己页面的内容通过inject注入到了孩子自身的实例对象中 如下图
         console.log(this);
    },
};
</script>

在这里插入图片描述


关系:爷爷, 爸爸 , 孩子

4.$attrs / $listeners

父传子(爷爷 -> 爸爸 -> 孩子)
对比图
在这里插入图片描述


关系: 爸爸,两兄弟

5.eventBus

兄弟组件传值
Father.vue

<template>
    <div>
        <Child />
        <Child2 />
    </div>
</template>

<script>
	import Child from "./Child.vue";
	import Child2 from "./Child2.vue";
	export default {
	    name: "Father",
	    components: { Child, Child2 },
	    mounted() {
	        this.$eventBus.$on("fatherTouch", (param) => {
	            console.log(param);
	        });
	    },
	};
</script>

Child.vue

<script>
export default {
    name: "Child",
    mounted() {
        this.$eventBus.$on("childTouch", (param) => {
            console.log(param);
        });
        // 子传父 ---- 因为响应问题 有时候这边还没请求 父亲那边就访问了,所以加个$nextTick 避免没有打印的问题
        this.$nextTick(() => {
            this.$eventBus.$emit("fatherTouch", "好了好了");
        });
    },
};
</script>

Child2.vue

<script>
export default {
    name: "Child2",
    mounted() {
        this.$eventBus.$emit("childTouch", "来了来了");
    },
};
</script>
  • 然后我们来创建中间事件 $eventBus
  • 先在src目录下新建一个文件夹 -> 接着创建两个文件
  • 然后在main.js里引入一下

event.js

export default function (Vue) {
	Vue.prototype.$eventBus = new Vue();
}

index.js

import eventExtend from './event';
export { eventExtend };

main.js

// extends是文件夹的名字
import { eventExtend } from './extends';
eventExtend(Vue);
关系:爷爷,爸爸,孩子

6.$dispatch / $broadcast == $parent / $children

简单介绍一下$dispatch / $broadcast == $parent / $children的关系
$dispatch:派发 === $parent 子传父的时候用
$broadcast :广播 === $children 父传子的时候用
可以通过扩展函数再原型上绑定派发、广播事件,原理就是通过 $parent / $children 循环 $emit

Grandpa.vue

<template>
    <div>
        <h1>爷爷的资产:{{ money }}</h1>
        <Father :money="money" @useMoneyAA="useMoneyUU" />
    </div>
</template>

<script>
import Father from "./Father.vue";
export default {
    name: "Grandpa",
    components: { Father },
    data() {
        return {
            money: 10000,
        };
    },
    methods: {
        useMoneyUU(num) {
            this.money -= num;
            //  父传子: 当孩子点击用钱按钮时 就会触发notice事件,爷爷会告诉孩子爸爸 孩子用钱了
            this.$eventBroadcast("notice");
        },
    },
};
</script>

Father.vue

<template>
    <div>
        <h1>爸爸继承爷爷的资产:{{ money }}</h1>
        <Child :money="money" @notice="notice" />
    </div>
</template>

<script>
import Child from "./Child.vue";
export default {
    name: "Father",
    components: { Child },
    props: {
        money: Number,
    },
    methods: {
        notice() {
            console.log("孩子用钱了");
        },
    },
};
</script>

Child.vue

<template>
    <div>
        <h2>孩子继承爸爸的资产:{{ money }}</h2>
        <button @click="useMoney">用钱</button>
    </div>
</template>

<script>
export default {
    name: "Child",
    // 这个方法最前面有 是用来接收父级的money参数 也可称 父传子
    props: {
        money: Number,
    },
    methods: {
        useMoney() {
        	// this.$parent.$emit("useMoney", 100); 这个方法也可用 但只适用于子级数量少的时候!!!!
            // 子传父 : 每次用100块钱,金钱总数减少
            this.$eventDispatch("useMoneyAA", 100); //进行封装过的组件
        },
    },
};
</script>

event.js (前面有写怎么创建需要引入什么,自行看第5个 eventBus)

export default function (Vue) {
	Vue.prototype.$eventDispatch = function (name, value) {
		let parent = this.$parent;
		while (parent) {
			parent.$emit(name, value);
			parent = parent.$parent;
		}
	};

	Vue.prototype.$eventBroadcast = function (name, value) {
		const bc = (children) => {
			children.map((c) => {
				c.$emit(name, value);
				if (c.$children) {
					bc(c.$children);
				}
			});
		};
		bc(this.$children);
	};
}

最后 : 不建议用 $ parent / $ children 以及组件派发/广播,$dispatch1.0是有得,2.0就没有了,因为这样结构不清晰

整理不易 , CTRL+C 请标明来源 !!!3Q~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值