脚本宝典收集整理的这篇文章主要介绍了Vue2与Vue3的组件通讯对比,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
父传子比较简单, 主要通过以下步骤实现
父在template
中为子绑定属性
<Child :childData='pMsg'/>
<!-- 也可以写死 -->
<Child childData='123'/>
子用props
接收数据, props
的值可以是数组或对象
props: ["childData"]
子在template
中或其他地方任意使用接受到的数据
<h2>我得到了{{childData}}</h2>
列出完整例子:
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</style>
</head>
<body>
<div id="app">{{ message }}</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</body>
</html>
<!--@html-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
<!--@javascript-start-->
Vue.component("Parent", {
data() {
return {
pMsg: "小楼昨夜又东风",
};
},
//步骤一
template: `<div><fieldset><legend>父组件</legend><input type="text" v-model="pMsg"/><Child :childData='pMsg'/></fieldset></div>`,
});
Vue.component("Child", {
//步骤三
template: `<div><fieldset><legend>子组件</legend>来自父组件的数据: {{ childData }}</fieldset></div>`,
//步骤二
props: ["childData"],
});
var vm = new Vue({
el: "#app",
data() {
return {
msg: "往input中输入东西试试",
};
},
template: `<div><fieldset><legend>App组件</legend>{{ msg }}<Parent/></fieldset></div>`,
});
<!--@javascript-end-->
<h2> <Child @childHandler="childHandler" /></h2>`
this
中的话,最好在data
中预留一个key
methods: {
childHandler(val) {
this.ChildData = val
}
}
@input="change(data)"
再在方法中使用$emit
调用父组件中的方法this.$emit("childHandler", val)
触发父组件中的自定义事件
$emit
: 触发当前实例上的事件。附加参数都会传给监听器回调
完整例子:
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">{{ message }}</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</body>
</html>
<!--@html-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
<!--@javascript-start-->
Vue.component("Parent", {
data() {
return {
ChildData: "",
};
},
//步骤一
template: `<div><fieldset><legend>父组件</legend><p>来自子组件的数据: {{ ChildData }}</p><Child @childHandler="childHandler" /></fieldset></div>`,
// 步骤二
methods: {
// 处理从子组件中获取的数据
childHandler(val) {
this.ChildData = val;
},
},
});
Vue.component("Child", {
data() {
return {
data: "故国不堪回首月明中",
};
},
//步骤三
template: `<div><fieldset><legend>子组件</legend><input type="text" v-model="data" @input="change(data)" /></fieldset></div>`,
methods: {
// 调用$emit方法
change(val) {
this.$emit("childHandler", val);
},
},
});
var vm = new Vue({
el: "#app",
data() {
return {
msg: "在input中输入东西试试",
};
},
template: `<div><fieldset><legend>App组件</legend>{{msg}}</h1><Parent/></fieldset></div>`,
});
<!--@javascript-end-->
父组件里使用provide
, 子组件里使用inject
完整例子
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">{{ message }}</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</body>
</html>
<!--@html-end-->
<!--@javascript-start-->
Vue.component("Parent", {
data() {
return { data: "小楼昨夜又东风" };
},
template: `<div><fieldset><legend>父组件</legend><p>父组件数据: {{ data }}</p><Child /></fieldset></div>`,
// 步骤一
provide() {
return {
data: this.data,
};
},
});
Vue.component("Child", {
template: `<div><fieldset><legend>子组件</legend><GrandSon /></fieldset></div>`,
});
Vue.component("GrandSon", {
// 步骤二
// 接收祖辈的数据 data
inject: ["data"],
data() {
return {
// 通过this.x取值
parentData: this.data,
};
},
template: `<div><fieldset><legend>孙组件</legend><p>祖辈的数据: {{ parentData }}</p></fieldset></div>`,
});
var vm = new Vue({
el: "#app",
data() {
return {
msg: "观察组件的数据",
};
},
template: `<div><fieldset><legend>App组件</legend><p>{{ msg }}</p><Parent/></fieldset></div>`,
});
<!--@javascript-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
注意, 这种方法传值不是响应数据 你可以把数据变为object类型, 让其可以同步修改
$bus
该属性是一个Vue
实例对象this.$bus.$emit
完整例子:
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">{{ message }}</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</body>
</html>
<!--@html-end-->
<!--@javascript-start-->
// 步骤一 添加$bus属性
Vue.prototype.$bus = new Vue();
Vue.component("Child1", {
data() {
return { data: "小楼昨夜又东风" };
},
methods: {
update() {
// 步骤二 使用$emit触发自定义事件, 传入数据
this.$bus.$emit("handlerData", this.data);
},
},
template: `<div><fieldset><legend>子组件</legend><p>子组件发送的数据: <input type="text" v-model="data" @input="update()"/></p></fieldset></div>`,
});
Vue.component("Child2", {
data() {
return {
data: "",
};
},
mounted() {
// 步骤三 处理传过来的数据
this.$bus.$on("handlerData", (val) => {
this.data = val;
});
},
template: `<div><fieldset><legend>子组件</legend><p>子组件接收的数据: {{ data }}</p></fieldset></div>`
});
var vm = new Vue({
el: "#app",
data() {
return {
msg: "往input中输入数据试试",
};
},
template: `<div><fieldset><legend>App组件</legend><p>{{msg}}</p><Child1 /> <Child2 /></fieldset></div>`,
});
<!--@javascript-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
由于vue3
将vue2
的选项变为了组合API, 而且把data
和methods
集合到了setup
中, 故而使用起来有所区别, 但也大差不差
ref
或reactive
将数据变为响应数据props
接收
关于
props
见: props
setup
中使用, 使用如下方法:props: ["data"],
setup(props, context) {
props.data
}
完整例子
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">
<fieldset>
<legend>app组件</legend>
{{ data }}
<!-- 使用组件 -->
<Parent />
</fieldset>
</div>
<script src="https://unpkg.com/vue@3.2.26/dist/vue.global.js"></script>
</body>
</html>
<!--@html-end-->
<!--@javascript-start-->
const AttributeBindingApp = {
name: "App",
setup() {
const data = "往input中输入东西试试";
return {
data,
};
},
};
const app = Vue.createApp(AttributeBindingApp);
app.component("Parent", {
setup() {
// 变为响应数据
const parentData = Vue.ref("故国不堪回首月明中");
return {
parentData,
};
},
template: `<fieldset><legend>父组件</legend> <input type="text" v-model="parentData" /> <Child :parentData="parentData" /></fieldset>`,
});
app.component("Child", {
props: ["parentData"],
setup() {
const childData = "childData";
return {
childData,
};
},
template: `<fieldset><legend>子组件</legend>{{ parentData }}</fieldset>`,
});
app.mount("#app");
<!--@javascript-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
template
中为子组件绑定自定义事件context.emit
方法总的来说, 原理与Vue2差不多, 但由于要在
setup
中获取值, 故要使用参数接收
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">
<fieldset>
<legend>app组件</legend>
{{ data }}
<!-- 使用组件 -->
<Parent />
</fieldset>
</div>
<script src="https://unpkg.com/vue@3.2.26/dist/vue.global.js"></script>
</body>
</html>
<!--@html-end-->
<!--@javascript-start-->
const AttributeBindingApp = {
name: "App",
setup() {
const data = "往input中输入东西试试";
return {
data,
};
},
};
const app = Vue.createApp(AttributeBindingApp);
app.component("Parent", {
setup(props, context) {
const childData = Vue.ref("");
// 步骤一 定义处理接收数据的方法
const receive = (e) => {
// 处理从子组件中传来的数据
childData.value = e;
};
return {
receive,
childData,
};
},
// 步骤二 自定义事件 触发处理接收数据的方法
template: `<fieldset><legend>父组件</legend><p>子组件中的数据: {{ childData }}</p><Child @inputText="receive" /></fieldset>`,
});
app.component("Child", {
props: ["parentData"],
setup(props, context) {
const data = Vue.ref("小楼昨夜又东风");
// 步骤四 调用context.emit
const toParent = () => {
// input时调用
// 调用inputText事件
context.emit("inputText", data.value);
};
return {
data,
toParent,
};
},
// 步骤三 触发事件
template: `<fieldset><legend>子组件</legend><input type="text" @input="toParent" v-model="data" /></fieldset>`,
});
app.mount("#app");
<!--@javascript-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
和vue2一样, 同样使用
provide
和inject
但不同的是, 我们可以使用ref
和reactive
将数据转换为响应式数据
<!--@html-start-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>title</title>
</head>
<body>
<div id="app">
<fieldset>
<legend>app组件</legend>
{{ data }}
<!-- 使用组件 -->
<Parent />
</fieldset>
</div>
<script src="https://unpkg.com/vue@3.2.26/dist/vue.global.js"></script>
</body>
</html>
<!--@html-end-->
<!--@javascript-start-->
const AttributeBindingApp = {
name: "App",
setup() {
const data = "往两个input中都输入试试";
return {
data,
};
},
};
const app = Vue.createApp(AttributeBindingApp);
app.component("Parent", {
setup() {
// 响应的数据
const data = Vue.ref("");
// 步骤一 使用provide
// 把data 标记为 "parentData"
Vue.provide("parentData", data);
return {
data,
};
},
template: `<fieldset><legend>父组件</legend>从子孙辈中获取的数据: <input type="text" v-model="data" /> <Child /></fieldset>`,
});
app.component("Child", {
template: `<fieldset><legend>子组件</legend><GrandSon /></fieldset>`,
});
app.component("GrandSon", {
setup() {
// 步骤二 接收数据
// 接收 parentData
const data = Vue.inject("parentData");
return {
data,
};
},
template: `<fieldset><legend>孙组件</legend><p>从父辈中获取的数据: <input type="text" v-model="data" /></p></fieldset>`,
});
app.mount("#app");
<!--@javascript-end-->
<!--@css-start-->
fieldset {
margin-top: 30px;
}
<!--@css-end-->
以上是脚本宝典为你收集整理的Vue2与Vue3的组件通讯对比全部内容,希望文章能够帮你解决Vue2与Vue3的组件通讯对比所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。