Vue component初認識

what is component

組件是Vue.js最強大的功能之一.組件可以擴展HTMl元素,封裝可重用的代碼.在較高層面上,組件是自定義元素,Vue.js的編譯器為它添加特殊功能.在有些情況下,組件也可以是原生HTML元素的形式,以 'is' 特性擴展.

how to use

注冊全局組件

    Vue.component('kai', {
        template: '<div>我是全局組件</div>'
    })
    var app = new Vue({
            el: "#app"
  })

一定要在初始化跟實例(app)之前注冊組件,否則無效
注冊完之后就可以在dom中跟html元素的使用方式一樣的使用

    <div id="app">
    <kai></kai>
      </div>

注冊局部組件

  var app = new Vue({
          el: "#app",
          components: {
              "localCom": {
                  template: "<p>我系局部組件</p>"
                  }
          }
      })
  • 通過使用組件實例選項(components)注冊可以是組件僅在另一個實例/組件的作用域中可用
  • 上邊注冊的組件 'localCom' 使用駝峰式命名,在使用時 要在每一個駝峰處使用 '-' 隔開
    使用方式:
  <div id="app">
    <kai></kai>
    <local-com></local-com>
  </div>

is特性

由于Vue只有在瀏覽器解析和標準化HTML后才能獲取模板內容.比如<ul>中只可以直接包裹<li>所以當你像下邊這樣使用組件

  <ul>
      <my-component></my-component>
  </ul>

瀏覽器會在Vue解析模板之前,標準化HTML,就會導致一些問題
變通的方案是使用特殊的 is 屬性:

    <ul>
          <li is="my-component"></li>
    </ul>

data 必須是函數

在自定義組件中data選項必須是函數,其實不難理解,如果你像Vue跟實例那樣,在自定義組件中也直接使用對象的形式,那么如果這個組件被多個地方使用,而data是一個對象,在內存中就是同一個內存空間,那如果在某一個地方修改data中的內容,那其他的地方的組件數據也會一起改變,顯然是不合理的,所以data要是一個函數,然后返回一個對象.

    Vue.component("my-component", {
            template: "<span>{{message}}</span>"  
            data:  function () {
                    return {
                          message: "我是自定義全局組件"
                    }
            }
        }
  )

組件間通訊

在Vue中,父子組件的關系可以總結為 props down, events up, 父組件通過props向下傳遞數據給子組件,子組件通過events給父組件發送消息.看下圖

image.png

1. 父 -> 子

組件實例的作用域是孤立的.這意味著不能(也不應該)在子組件的模板內直接 引用父組件的數據.要讓子組件使用粗組件的數據,我們需要這樣做:


        <div id="app">
            <kai msg="niguanwo"></kai>
            <local-com></local-com>
          </div>

        Vue.component('kai', {
            template: '<div>我是全局組件{{msg}}</div>',
            props: ["msg"]
        });
  • HTMl特性是不區分大小寫的,所以當使用的不是字符串模板, 駝峰式命名的 prop 需要轉換為相對應的 短橫線隔開式命名
2.動態綁定props
    <div id="app">
    <input type="text" v-model="time">
    <kai msg="niguanwo" v-bind:timer="time"></kai>
    <local-com></local-com>
</div>
    <script src="./vue.js"></script>
    <script>
    // 注冊全局組件
        Vue.component('kai', {
            template: '<div>我是全局組件{{msg}}時間{{timer}}</div>',
            props: ["msg", "timer"]
        });

        var app = new Vue({
            el: "#app",
            components: {
                "localCom": {
                    template: "<p>我系局部組件</p>"
                }
            },
            data: {
                time: "jidianl"
            }
        })
    </script>
  • 這樣,父組件你的time只要變化,子組件的timer也會動態的跟著改變
3.還可以直接傳遞一個對象,寫法如下
    <div id="app">
    <input type="text" v-model="time">
    <kai v-bind="obj" v-bind:object="obj1"></kai>
    <local-com></local-com>
</div>
    <script src="./vue.js"></script>
    <script>
    // 注冊全局組件
        Vue.component('kai', {
            template: '<div>{{name}}{{age}}{{object.status}}{{object.year}}</div>',
            props: ["name", "age", "object"]
        });

        
        var app = new Vue({
            el: "#app",
            data: {
                obj: {
                    name: "kai",
                    age: 25
                },
                obj1: {
                        status: "ok",
                       year: "2017"
                 }
            }
        })
    </script>
  • 還是要在props顯示地寫出要接收的屬性的名稱,直接使用 v-bind="obj"
4.單向數據流

prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,但是不會反過來。另外,每次父組件更新時,子組件的所有 prop 都會更新為最新值。這意味著你不應該在子組件內部改變 prop。
如果需要修改使用下面兩種方式:
1. 定義一個局部變量,并用 prop 的值初始化它:

      props: ['initialCounter'],
      data: function () {
        return { counter: this.initialCounter }
      }
  1. 定義一個計算屬性,處理 prop 的值并返回。

    props: ['size'],
    computed: {
      normalizedSize: function () {
      return this.size.trim().toLowerCase()
      }
    }
    
5.非props特性
  • 所謂非prop特性,就是它可以直接傳入組件,而不需要定義相應的prop.
  <bs-date-input data-3d-date-picker="true"></bs-date-input>

上邊這個會直接在bs-date-input的組件內添加一個data-3d-date-picker的值為true不過需要在data返回的對象中聲明一個data-3d-date-picker屬性,并初始化一個默認值出來

6.替換/覆蓋現有的特性
  • 對于多數特性來說,傳遞給組件的值會覆蓋組件本身設定的值。即例如傳遞 type="large" 將會覆蓋 type="date" 且有可能破壞該組件!所幸我們對待 class 和 style 特性會更聰明一些,這兩個特性的值都會做合并操作,生成最終的值.

子 -> 父

1. 使用v-on綁定自定義事件
image.png
  1. v-on:aaa 也可簡寫成 @aaa
  2. 父組件可以在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件。
2. 給組件綁定原生事件
    <my-component v-on:click.native="doTheThing"></my-component>
  • v-on:click.native 會監聽組件所在的根實例的(app)doTheThing事件
3. sync 實現子父組件數據同步
image.png
4.其他
  1. 盡管有 props 和 events,但是有時仍然需要在 JavaScript 中直接訪問子組件。為此可以使用 ref 為子組件指定一個索引 ID。|
  <div id="parent">
    <user-profile ref="profile"></user-profile>
  </div>
  var parent = new Vue({ el: '#parent' })
  // 訪問子組件
  var child = parent.$refs.profile
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容

  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,233評論 0 6
  • 下載安裝搭建環境 可以選npm安裝,或者簡單下載一個開發版的vue.js文件 瀏覽器打開加載有vue的文檔時,控制...
    冥冥2017閱讀 6,075評論 0 42
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容。關于...
    云之外閱讀 5,070評論 0 29
  • 1.安裝 可以簡單地在頁面引入Vue.js作為獨立版本,Vue即被注冊為全局變量,可以在頁面使用了。 如果希望搭建...
    Awey閱讀 11,070評論 4 129
  • 此文基于官方文檔,里面部分例子有改動,加上了一些自己的理解 什么是組件? 組件(Component)是 Vue.j...
    陸志均閱讀 3,846評論 5 14