1. 程式人生 > 實用技巧 >9Vue父子元件的傳遞方式

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>