2020-08-29 Vue组件之间通信

1. 父向子组件通信

  • 在子组件中 定义props属性 值是一个数组 数组中 每个元素,就是 从父组件接收的 数据
  • 在父组件中 使用 子组件 的自定义标签中 通过 属性的形式 传入 父组件的数据
<body>
  <div id="app">
    <home></home>
  </div>
</body>
<script>
  //定义组件
  let CommonTitle = {
    props:['title','arr'],
    template:`
      <div>
        <h2>{{ title }}</h2>
      </div>
    `
  }

  let Home = {
    template:`
      <div>
        <common-title :title="title"></common-title>
      </div>
    `,
    data(){
      return {
        title:'home页标题'
      }
    },
    components:{
      CommonTitle
    }
  }

  let vm = new Vue({
    el:'#app',
    data:{

    },
    components:{
        Home
    }
  })
</script>

2. 子向父组件通信

  • 通过 事件 弹射 形式通信
<body>
  <div id="app">
    <home></home>
  </div>
</body>
<script src="./js/vue.js"></script>
<script>

  //子组件
  //this.$emit("事件名",携带的数据)
  let ComTitle = {
    template:`
      <div>
        <button @click="biu">点击传送数据</button>  
      </div>
    `,
    data(){
      return {
        msg:'我是子组件的数据'
      }
    },
    methods:{
      biu(){
        this.$emit('piu',this.msg)
      }
    }
  }

  //父组件
  let Home = {
    template:`
      <div>
        home页
        {{msg}}
        <com-title @piu="fn"></com-title>  
      </div>
    `,
    data(){
      return {
        msg:'我是父组件的数据'
      }
    },
    methods:{
      fn($event){
        //$event 就是子组件传输过来的数据
        this.msg = $event;
      }
    },
    components:{
      ComTitle
    }
  }

  let vm = new Vue({
    el:'#app',
    components:{
      Home
    }
  })
</script>

3. 非父子组件

image.png
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>父组件</div>
    <test-tom></test-tom>
    <test-jack></test-jack>
  </div>

  <!-- ************** -->
  <template id="test-tom">
    <div>
      <div>tom:{{ num }}</div>
      <button @click="handle">点击</button>
    </div>
  </template>

  <template id="test-jack">
    <div>
      <div>jack:{{ num }}</div>
      <button @click="handle">点击</button>
    </div>
  </template>
<!-- ******************* -->
  <script src="./js/vue.js"></script>
  <script>
    //定于一个事件中心
    let eventBus = new Vue();

    //定义一个组件
    let TestTom = {
      data(){
        return {
          num:0
        }
      },
      template:'#test-tom',
      methods:{
        handle(){
          //触发兄弟组件的事件
          eventBus.$emit('jack-event',3)
        }
      },
      mounted(){
        //监听事件
        eventBus.$on('tom-event',(val)=>{
          //写箭头函数是为了方便this指向该组件
          this.num += val;
          //val是兄弟组件传递的值
        })
      }
    }

    //定义一个组件
    let TestJack = {
      data(){
        return {
          num:0
        }
      },
      template:'#test-jack',
      methods:{
        handle(){
          //触发兄弟组件的事件
          eventBus.$emit('tom-event',1)
        }
      },
      mounted(){
        //监听事件
        eventBus.$on('jack-event',(val)=>{
          //写箭头函数是为了方便this指向该组件
          this.num += val;
          //val是兄弟组件传递的值
        })
      }
    }


    let vm = new Vue({
      el:'#app',
      data:{

      },
      methods:{

      },
      components:{
        TestTom,
        TestJack
      }
    })
  </script>
</body>
</html>

props验证

  type
  required
  default

  props:{
    propa:String, //只验证type(类型)可以直接写类型预定义的值
    propb:[String,Number] //type是多个类型中的一个  []
    propc:{
      type:String,
      required:true
    },
    propd:{
      type:String,
      default:'xxx'
    }
  }

注意:
     1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
     2,props名字不能和data中以及methods和计算属性, 不能重名的
     3,如果默认值是 数组或者对象,需要一个函数返回这个默认值
     4,props能否被改变 props保持 单向的  父向子 (子不能改变),易于维护
  type的值:
    String
  Number
  Boolean
  Array
  Object
  Date
  Function
  Symbol

代码段:

<body>
  <div id="app">
    <home></home>
  </div>
  <script>
    let CommonTitle = {
      props:{
        title:String,
        subTitle:{
          type:String,
          required:true
          //default:'二级标题'
        },
        arr:{
          type:Array,
          default:()=>[1,2,3]
        }
      },
      template:`
        <div>
            这是标题
          <h2>
            {{ title }}
            {{ subTitle }}
          </h2>  
          <ul>
            <li v-for="item in arr" :key="item">
              {{ item }}  
            </li>
          </ul>
        </div>
      `
    }
    let Home = {
      template:`
        <div>
          <common-title :title="title"></common-title>  
          home页内容  
        </div>
      `,
      data(){
        return {
          title:"我是home页111"
        }
      },
      components:{
        CommonTitle
      }
    }
    let vm = new Vue({
      el:"#app",
      components:{
        Home
      }
    })
  </script>
</body>

三种不常用的通信

    1. ref通信
 <child ref="child"/>
  在父组件的
    this.$refs.child 就是这个子组件实例
  注意:
    不建议直接通过ref操作子组件 
    1. children , parent
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="app">
    <home></home>
  </div>
  <script>
    let CommonTitle = {
      props:['title','arr'],   //properties  props 父向子 传入的数据列表
      template:`
        <div>
            这是标题
          <h2>
            {{ title }}
          </h2>  
          <ul>
              <li v-for="item in arr" :key="item">
                  {{item}}
              </li>
          </ul>
        </div>
      `,
      data(){
        return {
          msg:123
        }
      },
      mounted(){
        console.log(this.$parent)
      }
    }
    let Home = {
      template:`
        <div>
         
          <common-title :title="title"></common-title>  
          home页内容  
        </div>
      `,
      data(){
        return {
          title:"我是home页111"
        }
      },
      mounted(){
        console.log(this.$children)
      },
      components:{
        CommonTitle
      }
    }
    let vm = new Vue({
      el:"#app",
      components:{
        Home
      }
    })
  </script>
</body>
</html>
    1. provide inject
父组件中
{
  provide:{
    msg:'1234',
    num:12
  },
  data,
  template,
  methods
}

子组件中 
{
  inject:['msg','num']

  // 挂载到了 子组件的 实例的 属性上  注意不要和data或者props或者计算属性或methods重名
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。