Vue.js知识——父子组件的通信、父子组件的访问方式

父子组件的通信

在开发中,往往一些数据确实需要从上层传递到下层:

比如在一个页面中,我们从服务器请求到了很多的数据,其中一部分数据,并非是整个页面的大组件来展示,而是需要下面的子组件进行展示。这个个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件将数据传递给小组件。

如何进行父子组件间的通信?

通过props向子组件传递数据(properties)

    const cpn2 = Vue.extend({
      template: `
        <div>
          <h1>{{cmovies}}</h1>
          <h3>哈哈哈<h3>
        </div>
      `,
      props:['cmovies'],
    });
    const app = new Vue({
      el: "#app",
      components: {
        cpn2,
      },
      data:{
        movies:["美国队长1","美国队长2","美国队长3"]
      }
    })

在这里插入图片描述
props不仅仅可以是传入数组,也可以传入对象

 props:{
        //1、类型限制
        cmoives:Array,
        //2、提供一些默认值
        cmoives:{
          type:Array,
          default(){
            return []
          },//默认值,如果默认值是个数组,就必须写成函数形式
          required:true,//如果为true,就是必须传入
        }
      }

props驼峰标识

在命名子组件的props属性时,往往会采取驼峰体,但是在html中是无法有效识别驼峰体代码。
例如:

<body>
  <div id="app">
    <cpn2 :cMovies="movies"></cpn2><!--这里无法识别驼峰体代码-->
  </div>

  <script>
    const cpn2 = Vue.extend({
      template: `
        <div>
          <h1>{{cMovies}}</h1>
          <h3>哈哈哈</h3>
        </div>
      `,
      props:{
        cMovies:{  //命名为驼峰体
          type:Array,
          default(){
            return []
          },
          required:true,
        }
      }
    });
    const app = new Vue({
      el: "#app",
      components: {
        cpn2,
      },
      data:{
        movies:["美国队长1","美国队长2","美国队长3"]
      }
    })
  </script>
 </body>

在这里插入图片描述

此时,数组中什么也没有传过来,所以显示了默认值。需要将html代码中的cMovies改成c-movies,才能显示。
<cpn2 :c-movies="movies"></cpn2>

子组件通过自定义事件向父组件发送消息

什么时候需要自定义事件呢?
当子组件需要向父组件传递数据时,就要用到自定义事件了,之前学习的v-on不仅仅用于监听DOM事件,也可以用于组件间的自定义事件。

<body>
  <div id="app">
    <cpn2 @itemclick="cpnclick"></cpn2>
  </div>

  <script>
    const cpn2 = Vue.extend({
      template: `
        <div>
          <button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button>
        </div>
      `,
        data(){
          return{
            categories:[
              {id:"aaa",name:"热门推荐"},
              {id:"bbb",name:"手机数码"},
              {id:"ccc",name:"家用家电"},
              {id:"ddd",name:"生鲜水果"},
            ]
          }
        },
        methods:{
        btnclick(item){
          //发射事件:自定义事件 
          this.$emit("itemclick",item);
        }
      }
    });
    const app = new Vue({
      el: "#app",
      components: {
        cpn2,
      },
      methods:{
        cpnclick(item){
          console.log(item);
        }
      }
    })
  </script>
</body>

通信案例

<body>
 <div id="app">
  <cpn :number1="num1" :number2="num2"
  @num1change="num1change" @num2change="num2change"></cpn>
 </div>
 
 <template id="cpn">
  <div>
    <h2>props:{{number1}}</h2>
    <h2>data:{{dnumber1}}</h2>
    <input type="text" :value="dnumber1" @input="num1Input">
    <h2>props:{{number2}}</h2>
    <h2>data:{{dnumber2}}</h2>
    <input type="text" :value="dnumber2" @input="num2Input">
  </div>
 
</template>
 <script>
   const app= new Vue({
     el:"#app",
     data:{
       num1:1,
       num2:0
     },
     methods:{
      num1change(value){
        this.num1 = parseFloat(value);
      },
      num2change(value){
        this.num2 = parseFloat(value);
      }
     },
     components:{
       cpn:{
        template:"#cpn",
        props:{
          number1:Number,
          number2:Number,
        },
        data(){
          return {
            dnumber1:this.number1,
            dnumber2:this.number2,
          }
        },
        methods:{
          num1Input(event){
            this.dnumber1 = event.target.value;
            this.$emit("num1change",this.dnumber1);
            this.dnumber2 = this.dnumber1*100;
            this.$emit("num2change",this.dnumber2);
          },
          num2Input(event){
            this.dnumber2 = event.target.value;
            this.$emit("num2change",this.dnumber2);
            this.dnumber1 = this.dnumber2 / 100;
            this.$emit("num1change",this.dnumber1);
          },
        }
       }
     
     }
   })
 </script>
</body>

父子组件的访问方式

有时候需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。

父组件访问子组件:使用$children或 $refs 引用

子组件访问父组件:使用$parent

$children

通过对button进行绑定事件,然后直接获取子组件中的属性。
但是要注意使用$children获取的是一个数组。

在这里插入图片描述

<body>
  <div id="app">
    <cpn></cpn>
    <button @click="btnclick">按钮</button>
  </div>

  <template id="cpn">
    <div>
      <h2>我是内容</h2>
    </div>
  </template>

  <script>
    const app=new Vue({
      el:"#app",
      methods:{
        btnclick(){
          console.log(this.$children[0].name);
          this.$children[0].name = "李四";
          console.log(this.$children[0].name);
        }
      },
      components:{
        cpn:{
          template:"#cpn",
          data(){
            return {name:"张三"}
          }
        }
      }
    })
  </script>
</body>

在这里插入图片描述
如果有多个数组就需要通过索引值来确定获取的需要修改的子组件,这样就造成了一个问题,如果子组件的位置变化,例如中间插入了新的子组件,就要修改索引值,非常麻烦。

这就用到了第二个方法

$refs

通过对子组件进行refs赋值,就可以确定需要获取的子组件。

注意的是不是refs,而是ref
<cpn ref="cpn1"></cpn>

console.log(this.$refs.cpn1.name);

在这里插入图片描述

$parent

子组件可以访问父组件,但是不建议使用,因为复用性不高,如果该子组件运用在其他父组件中,如果该父组件没有该属性就会报错。

<body>
  <div id="app">
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是内容</h2>
      <button @click="btnclick">按钮</button>
    </div>
  </template>

  <script>
    const app = new Vue({
      el: "#app",
      data:{
        age:18,
      },
      components: {
        cpn: {
          template: "#cpn",
          data() {
            return { name: "张三" }
          },
          methods: {
            btnclick() {
              console.log(this.$parent);
            }
          },
        }
      }
    })
  </script>
</body>

在这里插入图片描述

$ root

可以直接访问到Vue实例中的属性。
用法与上述相似。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值