9Vue父子组件的传递方式

 

写个计数器组件,雏形如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./vue.js"></script>
  <title>Document</title>
</head>
<body>
  <div id="app">
    <counter></counter>
    <counter></counter>
  </div>
</body>
<script>
  var counter={
    template:'<div>0</div>'
  }
  var vm=new Vue({
    el:"#app",
    components:{
      counter:counter
    }
  })
</script>
</html>

1.可以通过属性传值

注意:“count”和“:count”的区别。

<body>
  <div id="app">
    <!--父组件 可以通过属性向子组件传值 ,通过props接受-->
    <!-- <counter count="0"></counter>这种形式也可以传值,不过传的值是字符串 -->
    <!-- 下面这种形式传值,传递的是引号内的js表达式 ,传的是数字-->
    <counter :count="0"></counter>
    <counter :count="2"></counter>
  </div>
</body>
var counter={
    props:['count'],
    template:'<div>{{count}}</div>'
  }
  var vm=new Vue({
    el:"#app",
    components:{
      counter:counter
    }
  })

结果如下图:

 

 

接下来做点击就+1的效果

  var counter={
    props:['count'],
    template:'<div @click="handleClick">{{count}}</div>',
    methods:{
      handleClick:function(){
        this.count++;
      }
    }
  }
  var vm=new Vue({
    el:"#app",
    components:{
      counter:counter
    }
  })

这里直接操控count做+1动作,是可以实现需求的。但是控制台会警告:

 

 这是因为Vue不允许在子组件中修改父组件传递的值。假如父组件传递的值是一个对象,那么子组件接收的是这个对象的引用,如果这个对象还有其他组件在使用,我们修改了这个对象的值,就会造成其他组件的值的改变,这样是不允许的。

 

解决方法:在子组件中用data创建一个变量,将父组件的值赋给这个变量,通过改变data中的这个变量即可。

 var counter={
    props:['count'],
    data:function(){
      return {
        number:this.count //赋值
      }
    },
    template:'<div @click="handleClick">{{number}}</div>',
    methods:{
      handleClick:function(){
        this.number++;//使用子组件中的number,不会影响父组件的值
      }
    }
  }
  var vm=new Vue({
    el:"#app",
    components:{
      counter:counter
    }
  })

这样计数器就可以实现了。

 

再加一个将两个计数器值求和的功能。

通过this.$emit设置就行

 <div id="app">
    <counter @inc="handleInc" :count="0"></counter>
    <counter @inc="handleInc" :count="0"></counter>
    <div>总计:{{total}}</div>
  </div>

 

 

 

var counter={
    props:['count'],
    data:function(){
      return {
        number:this.count
      }
    },
    template:'<div @click="handleClick">{{number}}</div>',
    methods:{
      handleClick:function(){
        this.number++;
        //触发inc事件,并传参数1
        this.$emit('inc',1)
      }
    }
  }
  var vm=new Vue({
    el:"#app",
    data:{
      total:0
    },
    components:{
      counter:counter
    },
    methods:{
      handleInc:function(step){
        //每次触发就加1
        this.total+=step;
      }
    }
  })

 

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./vue.js"></script>
  <title>Document</title>
</head>
<body>
  <div id="app">
    <!-- 监听inc事件 -->
    <counter @inc="handleInc" :count="0"></counter>
    <counter @inc="handleInc" :count="0"></counter>
    <div>总计:{{total}}</div>
  </div>
</body>
<script>
  var counter={
    props:['count'],
    data:function(){
      return {
        number:this.count
      }
    },
    template:'<div @click="handleClick">{{number}}</div>',
    methods:{
      handleClick:function(){
        this.number++;
        //触发inc事件,并传参数1
        this.$emit('inc',1)
      }
    }
  }
  var vm=new Vue({
    el:"#app",
    data:{
      total:0
    },
    components:{
      counter:counter
    },
    methods:{
      handleInc:function(step){
        //每次触发就加1
        this.total+=step;
      }
    }
  })
</script>
</html>

 

posted @ 2020-12-08 18:45  ellenxx  阅读(183)  评论(0编辑  收藏  举报