1. 程式人生 > >Vue-組件嵌套之 父組件向子組件傳值

Vue-組件嵌套之 父組件向子組件傳值

總結 點擊 size asc 分享圖片 default component one con

父組件向子組件傳值步驟:

在這裏先定義一下,相對本案例來說:App.vue是父組件,Second-module.vue是子組件。

一、首先,值肯定是定義在父組件中的,供所有子組件共享。所以要在父組件的data中定義值:

技術分享圖片

二、其次,父組件要和子組件有契合點:就是在父組件中調用、註冊、引用子組件:

  調用:

技術分享圖片

  註冊:

技術分享圖片

  引用:

技術分享圖片

三、接下來,就可以在父組件和子組件鏈接的地方(即引用子組件的標簽上),把父組件的值綁定給子組件:

技術分享圖片

這裏我綁定了兩個值,一個是數組,一個是字符串。

四、最後,子組件內部肯定要去接受父組件傳過來的值:props(小道具)來接收:

技術分享圖片

五、這樣,子組件內部就可以直接使用父組件的值了。

技術分享圖片

但是有要註意的點:

子組件接受的父組件的值分為——引用類型和普通類型兩種,

普通類型:字符串(String)、數字(Number)、布爾值(Boolean)、空(Null)

引用類型:數組(Array)、對象(Object)

其中,普通類型是可以在子組件中更改,不會影響其他兄弟子組件內同樣調用的來自父組件的值,

但是,引用類型的值,當在子組件中修改後,父組件的也會修改,那麽後果就是,其他同樣引用了改值的子組件內部的值也會跟著被修改。除非你有特殊的要求這麽去做,否則最好不要這麽做。

父組件傳給子組件的值,在子組件中千萬不能修改,因其數據是公用的,改了所有引用的子組件就都改了。

先看一個效果頁面:

左邊的列表欄是引用父組件值的第一個子組件,右邊是引用了同樣值的第二個子組件,他們都有一樣的信息:

技術分享圖片

開發工具中看也是明顯的6條數據:

技術分享圖片

註意對比看最後一條數據: 點擊右邊區域第一個藍色按鈕後,就少了一組數據,當然是兩邊同時少的。

技術分享圖片

同樣看開發工具中,App組件的數據是少了一條的。

技術分享圖片

但是傳遞的是字符串、數字、布爾值的時候,在一個組件中修改就不會影響到其他組件的信息。就沒有關系。

我點擊第二個藍色按鈕,,就只有第二個子組件裏的title改變了,第一個的組件沒有變動

技術分享圖片

嘗試過後,值確實改了,但是vue給我彈出了一個警告:

警告:避免直接對一個道具進行修改,因為當父組件重新呈現時,該值將被覆蓋。相反,使用基於支柱的數據或計算屬性。

技術分享圖片

總結:

你可以這麽理解:傳值就是復制過去了一個值的副本,副本是可以自己隨便改的,但是引用是復制了個快捷方式,是一個指針,他們用的都是父組件中的那一個。

其實理解了js的原型鏈和面向對象原理後就不難理解這個:

把子組件想象成父組件的實例,那麽有可能父組件引用屬性的值(即方法),都是在父組件的原型上的。然後其他子組件,共享這一個在父組件原型上的引用值,所以牽一發而動全身。

(父組件原型:我習慣將其想象成爺爺的身份,構造函數是爸爸,實例是孫子,孫子一切都來自於爺爺,比如說形式。。扯遠了)

但是父組件傳給子組件的值,就像是構造函數中創建的屬性一樣,是由父組件(爸爸)拿著的。

所以當子組件(孫子們)自立門戶(被創建)的時候,父組件將值一人給了一份(爸爸的家產分給了每一個孩子)。那麽子組件在自己家裏改動,不會影響同用這個屬性的兄弟組件家裏的值的。

最後說明:純屬個人為了理解時胡亂連接的關系,不是真正的就是這樣的,不要太在意。。

不貼源碼的講解就是耍流氓!

父組件App.vue源碼:

<template>
  <div id="app">
   <app-header></app-header>
   <app-nav></app-nav>
   <app-cont></app-cont>
   <first-module v-bind:newlists = "newlists" v-bind:secondlist = "secondlist"></first-module>
   <!-- 實現父組件給子組件傳值 -->
   <second-module v-bind:newlists ="newlists" v-bind:secondlist = "secondlist"></second-module>
   <app-footer></app-footer>
  </div>
</template>

<script>

  import Header from ‘./components/Header‘
  import Footer from ‘./components/Footer‘
  import Navbar from ‘./components/Navbar‘
  import Content from ‘./components/Content‘
  import Firstmodule from ‘./components/First-module‘
  import Secondmodule from ‘./components/Second-module‘

  export default {
    name: ‘app‘,
    data () {//父組件中定義全局的數據,好傳給需要的子組件們
      return {//return 一定要有,因為data在這裏是一個函數方法,不然函數返回的就是undefiend,找不到數據啊
        newlists: [//傳一個引用:數組
          {title: "Vue-初識Vue及引入CDN",time: "2017/08/15"},
          {title: "Vue-實例化Vue對象",time: "2017/08/15"},
          {title: "Vue-數據和方法",time: "2017/08/15"},
          {title: "Vue-屬性綁定",time: "2017/08/15"},
          {title: "Vue-事件(點擊:雙擊:鼠標事件)",time: "2017/08/15"},
          {title: "Vue-鍵盤事件及鍵值修飾符(alt:enter)",time: "2017/08/15"}
        ],
        secondlist: "我是父組件傳給第二個子組件的文本"//傳一個值:字符串
      }
    },
    components: {//局部註冊組件這裏,可能會定義多個組件,所以component這個單詞加上“s”
      "app-header": Header,
      "app-footer": Footer,
      ‘app-nav‘: Navbar,
      "app-cont": Content,
      "first-module": Firstmodule,
      "second-module": Secondmodule
    }
  }
</script>

<style>
  #app {
    font-family: ‘微軟雅黑‘, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 10px;
  }
  #app:after{
    content: "";
    clear: both;
    display: block;
    visibility: hidden;
  }
  ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
  }
  .lists{
  }
  .lists li{
    padding: 10px 20px;
    text-align: left;
   }
   .lists li:nth-child(odd){
    background: #f5f5f5;
   }
  .lists a{
    color: #222;
    text-decoration: none;
  }
  .lists a p{
    margin: 5px 0;
  }
  .lists a span{
    color: #999;
    font-size: 12px;
  }
</style>

子組件Second-module.vue源碼:

見另一篇文章底部:http://www.cnblogs.com/padding1015/p/7878741.html

聲明:

  請尊重博客園原創精神,轉載或使用圖片請註明:

  博主:xing.org1^

  出處:http://www.cnblogs.com/padding1015/

Vue-組件嵌套之 父組件向子組件傳值