vue组件通信

    

组件间关系

组件 间 嵌套 使用 形成 一下 几种关系 父子、兄弟(祖先后代)

组件间通信

 

父向子通信
      通过props
       1,props值是一个 数组
           // properties 缩写
         let CommonHead = {
             props:["title"],
             template:`
                 <h1>
                     {{ title }}
                 </h1>
             `
        }
         let Home = {
             template:`
                 <div>
                    我是首页
                    <common-head title="我是首页"/>
                 </div>
             `,
             components:{
                 CommonHead
            }
        }

 

  <body>
     <div id="app">
         <home></home>
         <news></news>
     </div>
     <script src="../vue.js"></script>
     <script>
         //properties 缩写
         let CommonHead = {
             props: ["title"],
             template:
                 `
             <h1>
                     {{ title }}
                     <!--
                         <button @click="title='我改变了数据'">按钮</button>
                     -->
                   
                   
                 </h1>
             `
        }
         let Home = {
             template: `
                 <div>
                    我是首页
                    <common-head title="我是首页"/>
                 </div>
             `,
             components: {
                 CommonHead
            }
        }
         let News = {
             template: `
                 <div>
                    我是新闻页
                    <common-head :title="msg"/>
                 </div>
             `,
             data() {
                 return {
                     msg: "我是新闻页"
                }
            },
             components: {
                 CommonHead
            }
        }
         Vue.component("Home", Home);
         Vue.component("News", News);
         // 挂载 (挂载到Vue,全局组件、或者到另一个组件中)
         // 组件名 推荐使用大驼峰(或者下划线、common-head),使用时使用下划线(自动解析)
         let vm = new Vue({
             el: "#app"
        })
     </script>
 </body>
props验证
 props是一个对象,不再是一个数组
       props:{
           title:{
               type:String,
               required:true
          },
           title2:String,
           title3:{
               type:Number,
               default:0
          }
      }
       类型:
           String
           Number
           Boolean
           Array
           Object
           Date
           Function
           Symbol

 

    // properties 缩写 
         let CommonHead = {
             //此时的props不是一个数组 而是一个对象
             props: {
                 title: {
                     type: String,
                     required: true
                },
                 title2: {
                     type: String,
                     default: '我是首页'
                },
                 arr: {
                     type: Array,
                     default: () => [1, 2, 3] //要求出入构造函数 返回一个值
                }
            },
             template: `
               <h1>
                     {{ title }}
                     {{title2}}
                     <ul>
                         <li v-for="(item,index) in arr" :key="index">
                             {{item}}
                         </li>
                     </ul>
                 </h1>
               `
        }

 

  • 注意:

  • 1,props命名 不能 和data或者 计算属性 重名(否则互相影响)

  • 2,props 值 不能在 子组件 内部修改 (只能由传入放修改 props单向数据流)

    //只能由传入放修改  props单向数据流
    let Home = {
               template: `
                   <div>
                      我是首页
                      <common-head title="我是首页"/>
                   </div>
               `,
               components: {
                   CommonHead
              }
          }

     

    //props 值 不能在 子组件 内部修改
    //修改之后(button)也不会报错 会警告 单项数据流 修改之后不易于维护
    let CommonHead = {
               props: ["title"],
               template:
                   `
               <h1>
                       {{ title }}
                       <!--
                           <button @click="title='我改变了数据'">按钮</button>
                       -->
                     
                     
                   </h1>
               `
          }

     

  • 3,props验证中:如果数据类型是 数组或者 对象,要求 默认值是 一个函数返回这个默认值

     arr: {
                     type: Array,
                     default: () => [1, 2, 3] //要求出入构造函数 返回一个值
                }
子向父通信:
  • 自定义事件

    子组件中 this.$emit("事件名",携带的参数)

    父组件中接收

 

  <body>
     <div id="app">
         <home></home>
 
     </div>
     <script src="../vue.js"></script>
     <script>
         // properties 缩写
         let CommonHead = {
             template: `
             <div>
                     <h1>子组件</h1>
                     <button @click="biubiubiu">发射</button>
                 </div>
             `,
             data() {
                 return {
                     msg: "我是子组件的数据"
                }
            },
             methods: {
                 //子组件中 this.$emit("事件名",携带的参数)
                 biubiubiu() {
                     this.$emit("a", this.msg);
                }
            }
        }
         let Home = {
             template: `
                 <div>
                   父组件
                    <common-head @a="receive"/>
                    {{ msg }}
                 </div>
             `,
             data() {
                 return {
                     msg: "哈哈哈"
                }
            },
             methods: {
                 receive(msg) {
                     alert("事件传递过来啦");
                     this.msg = msg;
                }
            },
             components: {
                 CommonHead
            }
        }
         Vue.component("Home", Home);
 
         let vm = new Vue({
             el: "#app"
        })
     </script>
 </body>

 

  组件的第二种分类:
     容器组件 (业务逻辑 处理数据)
     傻瓜组件 (展示、接受数据)
     状态提升:将数据处理 提升到 父组件中
组件通信 之 兄弟之间 通信
  event bus  事件中心总线
     原理:新建一个空的 第三方的vue 实例
     由实例 触发自定义事件  由实例来 接收自定义事件
     实例.$emit()
 
     实例.$on("事件名",()=>{
 
    })
 
    let bus = new Vue();
 
     在a组件中
         调用 bus.$emit("事件名",数据)
     在b组件中
         找到bus
         bus.$on("事件名",callback)

 

  <body>
     <div id="app">
         <home></home>
     </div>
     <script src="../vue.js"></script>
     <script>
         let bus = new Vue();
         // properties 缩写
 
         let CommonHead = {
             template: `
         <div>
                     <h1>子组件</h1>
                     <button @click="biubiubiu">发射</button>
                 </div>
         `,
             data() {
                 return {
                     msg: "我是子组件的数据"
                }
            },
             methods: {
                 biubiubiu() {
                     bus.$emit("a", this.msg);
                }
            }
 
        }
         let Child2 = {
             template: `
             <div>
                   <h1>我是另一个子组件</h1>
                  {{msg}}
               </div>
             `,
             data() {
                 return {
                     msg: "我是另一个子组件的数据"
                }
            },
             mounted() {
                 /* bus.$on("a",function(msg){
                      this.msg = msg;
                  }.bind(this)) */
                 /*   bus.$on("a",(msg)=>{
                    this.msg = msg;
                  }) */
                 let _this = this;
 
                 bus.$on("a", function (msg) {
                     _this.msg = msg;
                })
            }
        }
         let Home = {
             template: `
             <div>
                   父组件
                    <common-head></common-head>
                    <child2/>
                    {{ msg }}
                 </div>
             `,
             data() {
                 return {
                     msg: ""
                }
            },
             components: {
                 CommonHead,
                 Child2
            }
        }
 
         Vue.component("Home", Home);
 
         let vm = new Vue({
             el: "#app"
        })
     </script>
 </body>

 

 

 

 

<body>
   <div id="app">
       <common-head></common-head>
   </div>
   <script src="../vue.js"></script>
   <script>
       //定义组件
       let CommonHead = {
           template: `
               <div>
                   <h1>我是公共的头部</h1>            
               </div>
           `,
      }
//全局组件
       Vue.component("CommonHead", CommonHead)
       let vm = new Vue({
           el: "#app"
      })
   </script>
</body>

 

  • 局部组件

      {
               template,
               data(){},
               methods: {},
               components: {
                   Home: Home
              }
          }

     

    <body>
       <div id="app">
           <common-head></common-head>
       </div>
       <script src="../vue.js"></script>
       <script>
           let Child = {
               template:
                   `
                   <h5>我是一个子组件</h5>
               `
          }
           let CommonHead = {
               template: `
                   <div>
                       <h1>我是公共的头部</h1>
                       <child></child>
                   </div>
               `,
               components: {
                   Child
              }
          }
           let vm = new Vue({
               el: "#app",
               components: {
                   CommonHead
              }
          })
       </script>
    </body>

     

  • 注意:

  • 组件 也是 Vue的实例(vm上有的属性和语法、组件都有)

  • 组件的data属性 必须是一个函数 返回一个对象

    data(){
                  return {
                      msg:"我是组件内的"
                  }
              },

     

  • 组件 template 有且只能有一个根元素

     template: `
                   <div>
                       <h1>我是公共的头部</h1>
                       <child></child>
                   </div>
              `,

     

  • 以下三种仅供面试用

   1,ref
               let CommonHead = {
           
                 template:`
                     <div>
                         <h1>子组件</h1>
                         {{ msg }}
                     </div>
                 `,
                 data(){
                     return {
                         msg:"我是子组件的数据"
                    }
                }
             
            }
             let Home = {
                 template:`
                     <div>
                     父组件
                     <common-head ref="child"/>
                     <button @click="change">按钮</button>
                     </div>
                 `,
                 data(){
                     return {
                         msg:""
                    }
                },
                 mounted(){
 
                },
                 methods:{
                     change(){
                         console.log( this.$refs )
                         let childComponent = this.$refs['child'];
                         childComponent.msg = "哈哈哈哈"
                    }
                },
                 components:{
                     CommonHead
                }
            }
 
         
             Vue.component("Home",Home);
             
             let vm = new Vue({
                 el:"#app"
            })
     注意: 不推荐使用,破坏了单向数据流
 
 2.$parent $children
 谨慎使用 理由同上
 
 3,provide inject
 
**以上2个千万不要要  第三个偶尔用用**

3,provide inject

  <body>
     <div id="app">
         <home></home>
 
     </div>
     <script src="./vue.js"></script>
     <script>
         // properties 缩写
         let CommonHead = {
             //子组件接收
             inject: ['arrData'],
             template: `
                 <div>
                     <h1>子组件</h1>
                     {{ msg }}
                 </div>
             `,
             data() {
                 return {
                     msg: "我是子组件的数据"
                }
            },
             mounted() {
                 console.log(this.arrData);
                 console.log(this.$parent)
                 setTimeout(() => {
                     this.$parent.msg = "子组件改变了你"
                }, 2000)
            }
 
        }
         var arr = [1, 2, 3, 4, 5];
         let Home = {
             template: `
                 <div>
                   父组件
                    <common-head ref="child"/>
                   <button @click="change">按钮</button>
                   {{msg}}
                 </div>
             `,
             //父组件提供数据
             provide: {  //我这个组件 提供了 一个数据 key arrData,我的子组件 可以 去拿我提供的这个数据
                 arrData: arr,
                 b: 2
            },
             data() {
                 return {
                     msg: "我是父组件的"
                }
            },
             mounted() {
                 console.log(this.$children)
            },
             methods: {
                 change() {
                     console.log(this.$refs)
                     let childComponent = this.$refs['child'];
                     childComponent.msg = "哈哈哈哈"
                }
            },
             components: {
                 CommonHead
            }
        }
 
 
         Vue.component("Home", Home);
 
         let vm = new Vue({
             el: "#app"
        })
 
     </script>
 </body>

 

原文地址:https://www.cnblogs.com/lilamisu/p/13715533.html