方案之一:Vue空实例+vm.$emit 和 vm.$on
实现原理:组件之间可以通过vm.$emit发射数据,通过vm.$on接收数据,在处理brother01 和brother02的时候,创建一个空Vue对象来发射与接收数据,任何组件之间,都可以来处理!
当然,父子关系的 建议用系统标签来完成,更简单:参考文档:https://blog.csdn.net/weixin_43343144/article/details/86234141
第一个文件:html(template模板文件)
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<html>
<style >
/* v-cloak解决浏览器闪烁的问题! */
[v-cloak] { display: none,}
</style>
<head>
<link rel="stylesheet" href="./src/css/bootstrap.css">
<link rel="stylesheet" href="./src/css/app.css">
<!-- 模板代码务必单独提出来,不能放在.container中,否则会报错,因为此作用域中的变量,在.container中没有! -->
<template id="mybrother01">
<div>
<ol>
<li>这是一个mybrother01组件{{brother01_data}}</li>
<my-brother01-children></my-brother01-children>
</ol>
<p><button @click='send_brother01(event)'>mybrother01按钮send</button></p>
</div>
</template>
<template id="mybrother01children">
<ol>
<li style="color:red">这是一个mybrother01children组件{{brother01_children_data}} </li>
</ol>
</template>
<template id="mybrother02">
<ol>
<li style="color:red">这是一个mybrother02组件{{brother02_data}}</li>
</ol>
</template>
</head>
<body>
<!--这里的container内部不能嵌入template(有局部作用域变量的),否则会报错!!-->
<div class="container" >
<my-brother01></my-brother01>
<my-brother02></my-brother02>
</div>
</body>
<!--第三方mudule_js库-->
<!--script src="./node_modules/axios/dist/axios.js"></script-->
<script src="./node_modules/jquery/dist/jquery.js"></script>
<script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<!--my_mudule_js库-->
<script type="module" src="./src/js/app.js"></script>
</html>
第二个文件:创建new Vue对象js文件(创建之前导入components.js 产生的对象结果)
//把brother01和brother02对象最终的结果返回,最好的封装性!
import {brother01,brother02} from "./components.js";
//对于new Vue的创建之前,务必让对象把结果处理完毕之后,把最终的结果传入进来即可,防止数据冲突无法访问的问题!
//先处理完毕对象的数据,把最终对象的结果来创建Vue,是最明智的做法,也避免了数据混乱冲突,也是封装的特性!
//全局组件注册原始写法()brother01是一个对象{};
// Vue.component("my-brother01",new Vue.extend(brother01));
// //全局组件注册常用简写法:
// Vue.component("my-brother01",brother01);
$(function() {
const app = new Vue({
el:".container",
data:{
g_data:"new Vue对象的作用域!"
},
//局部组件注册的方式推荐封装对象处理完毕的结果,在来创建new Vue();
components:{
"my-brother01":brother01,
"my-brother02":brother02,
},
});
});
第三个文件: components.js把 brother01 和 brother02 的结果处理完毕在返回(模块封装的特性,避免变量冲突)
//创建一个空Vue,目的用来调用bus.$emit 发射 和 bus.$on 接收方法!
//在此module中,bus是全局变量!
const bus = new Vue();
//创建一个 brother01子组件对象,组件对象的基本创建方法!
const brother01_children = {
template:"#mybrother01children",
data:function() {
return {
brother01_children_data:[],
}
},
//生命周期函数,实时监听发射过来的数据!
//mounted是全局函数,内部的this和全局data中的this一致!
mounted:function() {
console.log("brother01_children_mounted函数已经运行");
//$on方法是异步函数,内部的this会改变,所以用箭头函数来接收!
bus.$on("brother_event",(...args)=> {
console.log(args);
this.brother01_children_data = args;
console.log("brother01_children$on函数已经接收完毕");
});
},
}
//创建一个 brother01组件对象,组件对象的基本创建方法!
const brother01 = {
template: "#mybrother01",
//在自定义组件中,data必须是函数,最终返回一个对象(官方有说明)
data:function(){
return {
brother01_data:"这是一个局部brother01组件模板",
}
},
methods:{
//让组件brother01来发射数据,子组件brother01_children和兄弟组件brother02 或其他任何组件都可以来接收!
send_brother01:function() {
console.log("send_brother01发送成功");
bus.$emit("brother_event",this.brother01_data);
},
},
//注册一个子组件!
components:{
"my-brother01-children":brother01_children,
}
}
//创建一个 brother01子组件对象,组件对象的基本创建方法!
const brother02 = {
template:"#mybrother02",
data:function() {
return {
brother02_data:[],
}
},
//生命周期函数,实时监听发射过来的数据!
//mounted是全局函数,内部的this和全局data中的this一致!
mounted:function() {
//$on方法是异步函数,内部的this会改变,所以用箭头函数来接收!
bus.$on("brother_event",(...args)=> {
console.log(args);
this.brother02_data = args;
console.log("brother02$on函数已经接收完毕");
});
},
}
export {brother01,brother02};