国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

后端開發者的Vue學習之路(三)

番茄西紅柿 / 3021人閱讀

摘要:使用組件全局定義組件,第一個參數是組件名,的值是組件的內容這是個待辦項實例化是必須的,要把使用組件的區域交給管理局部注冊組件局部注冊組件全局注冊往往是不夠理想的。

目錄

  • 上節內容回顧
  • 組件
    • 什么是組件
    • 組件注冊
      • 全局注冊組件
      • 局部注冊組件
    • 使用細節
      • 組件注冊的命名規范:
      • 組件中只有一個根元素
      • 組件也是一個實例
      • 組件在某些元素中渲染出錯
  • 組件間的數據傳遞
    • 父子組件傳遞數據
    • 子組件向父組件傳輸數據
    • 非父子組件之間的傳值
    • 單向數據流
  • Props屬性
    • 命名規范:
      • 大小寫問題
    • 參數校驗
      • 限制props的類型
      • 設置默認值
      • 要求數據必傳
      • 自定義驗證函數:
    • 傳遞靜態或動態Prop
    • 補充:
  • 給組件綁定原生的事件
  • template
    • 在template上使用v-if
    • 使用v-for
  • 插槽
    • 通過插槽分發內容
      • 具名插槽
      • 插槽的默認內容
    • 作用域插槽
  • 動態組件
    • is
    • keep-alive
    • 補充
  • $refs
    • 使用步驟:
    • 獲取組件的引用
  • 動畫效果

首發日期:2019-01-26


上節內容回顧

  • 數據綁定:v-model
  • 樣式綁定:v-bind:class,v-bind:style
  • 事件:v-on
  • Vue指令
  • 數組操作(知道哪些數組操作是能被vm層監聽到并能響應式更新到視圖上的)
  • Vue的元素復用問題(不使用key時會盡量復用)

組件


【官方的話】組件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通??蓮陀玫慕M件構建大型應用。仔細想想,幾乎任意類型的應用界面都可以抽象為一個組件樹:

小菜鳥的話:定義組件就好像定義了一堆“帶名字”的模板,比如說可能會有叫做“頂部菜單欄”的組件,我們可以多次復用這個“頂部菜單欄”而省去了大量重復的代碼。


什么是組件

  • 在以前的多頁面開發的時候,我們可能會經常需要一個“頂部菜單欄”,于是我們在每個html文件中都要加上關于“頂部菜單欄”的代碼??赡苣銜脒@份代碼能夠“復用”就好了。而組件可以定義模板,從而達到復用代碼的作用。
  • 組件可以大大提高我們構建頁面的效率。
  • 你可以將組件進行任意次數的復用
    下面用代碼來演示一下"復用效果":
    
      

代碼效果:


組件注冊

組件注冊就是“定義模板”,只有注冊了的組件,Vue才能夠了解怎么渲染。


全局注冊組件

  • 全局注冊的組件可以用在其被注冊之后的任何 (通過 new Vue) 新創建的 Vue 實例中,也包括其組件樹中的所有子組件的模板中。【一個Vue應用只有一個根實例,但還允許有其他的實例。在 Vue 里,一個組件本質上是一個擁有預定義選項的一個 Vue 實例?!?/li>
  • 全局注冊的行為必須在根 Vue 實例 (通過 new Vue) 創建之前發生
  • 全局注冊的組件可以在另一個組件中使用。


    
        
        
    

    
        


局部注冊組件


全局注冊往往是不夠理想的。比如,如果你使用一個像 webpack 這樣的構建系統,全局注冊所有的組件意味著即便你已經不再使用一個組件了,它仍然會被包含在你最終的構建結果中。這造成了用戶下載的 JavaScript 的無謂的增加。

在這些情況下,你可以通過一個普通的 JavaScript 對象來定義組件:

    
      


上面的全局注冊說了允許在組件中使用其他組件,但注意局部注冊的組件要聲明使用其他組件才能夠嵌套其他組件。例如,如果你希望 ComponentA 在 ComponentB 中可用,則你需要這樣寫:

    
      


使用細節


組件注冊的命名規范:

組件名可以使用類my-component-name(kebab-case (短橫線分隔命名))或MyComponentName的格式(PascalCase 首字母大寫命名法),使用組件的時候可以,但在有些時候首字母大寫命名法定義組件的是不行的,所以通常推薦使用【當你使用首字母大寫命名法來定義組件的時候,不能直接在body中直接寫組件名,而要求寫在template中,如下例】。


    
      


組件中只有一個根元素

每個組件必須只有一個根元素!!
所以下面是不合法的:

如果你確實要有多個元素,那么要有一個根元素包裹它們:


組件也是一個實例


組件也是一個實例,所以組件也可以定義我們之前在根實例中定義的內容:data,methods,created,components等等。
但一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝


組件在某些元素中渲染出錯

在一些html元素中只允許某些元素的存在,例如tbody元素中要求有tr,而不可以有其他的元素(有的話會被提到外面)。下面是一個元素被提到外面的例子【而ul并沒有太嚴格,所以我們在前面的todo-list的例子中能夠演示成功】

下圖可以看的出來div被提到table外面了:

這是為什么呢?目前來說,我們在頁面中其實是先經過html渲染再經過vue渲染的(后面項目話后是整體渲染成功再展示的),當html渲染時,它就發現了tr里面有一個“非法元素”,所以它就把我們自定義的組件提到了table外面。
解決方案:
使用tr元素,元素里面有屬性is,is的值是我們要使用的組件名

    
        



但不會在一下情況中出錯:

  1. 定義組件的時候,template中包含自定義的組件
  2. 單文件組件,也就是說引用vue文件來注冊一個組件的時候(這個東西會在后面講)。
  3. 代碼效果:很明顯的,我們的值成功傳給子組件了。


    子組件向父組件傳輸數據

    • 我們可以在子組件中使用emit來觸發事件,然后在使用這個組件的時候綁定這個事件就可以監聽到這個事件的發生(這時候調用的函數是父組件的處理函數),從而使得父組件接受到子組件傳遞的消息了。
      要給父組件傳遞數據主要有兩個步驟
    1. 在定義組件時,定義一個包含觸發事件的元素,這個事件觸發時將會調用emit來觸發事件【例如可以在按鈕上定義一個onclick事件,這個onclick事件觸發時將會調用emit】
    2. $emit()可以有多個參數,第一個參數是觸發的事件的名稱,后面的參數都是隨著這個事件向外拋出的參數。
    3. 使用組件時,對組件進行事件監聽,監聽的事件與組件內拋出的事件一致
    4. 定義處理目標事件的函數,函數的參數是隨事件向外拋出的多個參數。


    演示代碼如下:

        
            

    【小tips:上面有多重字符串的使用,普通的雙引號和單引號已經不足以嵌套使用了,在外層可以使用反引號` ` `【esc下面那個鍵】來包裹,它也可以達到字符串包裹的效果,特別的是它支持多行字符串?!?/p>


    非父子組件之間的傳值

    祖孫組件傳數據、兄弟組件傳數據都屬于非父子組件之間的傳值。

    1. 【如果是祖孫組件傳數據,可以使用父組件傳給子組件,子組件傳給孫組件。但這是一個費事的做法?!?/li>
    2. 一般都會使用vuex,vuex就像一個變量存儲器,我們可以把一些多個組件都需要用到數據存儲到vuex的store中。【這個由于內容較重要,留到后面再講】
    3. 只有少量組件使用某個數據的時候也可以使用bus模式,bus相當于給每一個組件都加上“同一個”新的vue實例,由于bus是實例之間共享的,當數據發生改變時,可以利用這個vue實例來調用emit方法來拋出新值,而其他組件監聽bus中的事件就可以獲取到新的值,這樣就實現了非父子組件之間的傳值。


    使用bus傳輸數據的步驟:

    1. 在Vue的原型上定義vue:Vue.prototype.bus = new Vue()
    2. 當數據發生變化時,調用emit:this.bus.$emit(change,當前組件的數據)
    3. 在組件上監聽bus的事件:this.bus.$on(change,一個用于賦值的函數)
    4. 在函數中獲取事件觸發帶過來的參數,賦給當前組件,從而實現兩邊數據同步。

    下面的代碼是點擊某個組件發生數據變化時,另一個組件的數據也發生變化:

        
            


    單向數據流

    • 單向數據流:props使得父組件的數據能夠傳輸到子組件,而且傳輸的源數據發生改變時,子組件也會發生改變。但如果在子組件中更改prop,這是不行的,會報警告。
    • 每次父級組件發生更新時,子組件中所有的 prop 都將會刷新為最新的值。如果允許你在子組件中修改父組件傳入的數據的話,使用了父組件的這個數據的所有子組件的數據都會被修改(這樣就降低了組件的復用效果,導致數據流行不確定,難以確定這個數據是在哪個組件中修改的,而且是一個相對危險的行為)
    • 你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發出警告。【這就是單向數據流】
    • 如果你確實需要修改:
      • 那么你應該創建一個子組件內部的數據,這個內部數據由傳入的prop的數據進行初始化。(也就是進行數據拷貝)
      • 又或者你可以使用計算屬性。



    Props屬性


    命名規范:

    大小寫問題

    【有個建議,建議寫屬性名的時候都使用kebab-case (短橫線分隔命名) 命名,因為這個的兼容效果最好】
    HTML 中的特性名是大小寫不敏感的,所以瀏覽器會把所有大寫字符解釋為小寫字符。如果你在props中使用了駝峰命名法,那你在定義屬性的時候需要使用kebab-case (短橫線分隔命名) 命名才能正確傳輸數據【因為短橫線后面的字符可以識別成大寫,從而能夠匹配到】。

    如果在屬性中也使用駝峰命名法命名屬性的時候會報這樣的錯:Prop "mycontent" is passed to component , but the declared prop name is "myContent". Note that HTML attributes are case-insensitive and camelCased props need to use their kebab-case equivalents when using in-DOM templates. You should probably use "my-content" instead of "myContent"

        
            

    同樣的,如果在組件的template屬性中使用駝峰命名法的屬性,那么這個限制就不存在了。


    參數校驗

    限制props的類型

    有時候需要使用第三方的組件的時候,所以會需要傳輸數據給這個組件來渲染。但如何限制傳入的數據的類型呢?

    • 可用于限制數據類型的類型:
      • String:字符串
      • Number:數字
      • Boolean:布爾值
      • Array:數組
      • Object:對象
      • Date:日期
      • Function
      • Symbol


    格式:

    props: {
    // 數據名:數據類型
      title: String,
      likes: Number,
      ...
    }


    如果傳入的類型不對,那么會報Invalid prop: type check failed for prop "xxx". Expected String with value "xxx", got Number with value xxx.的錯誤。


    如果允許多種值,可以定義一個數組:

    props: {
      content: [String,Number]
    }


    設置默認值

    我們也可以給props中的數據設置默認值,如果使用default設置值,那么沒有傳某個數據時默認使用這個數據。

    props: {
      content: {
      type:[String,Number],
      default:'我的默認值'
      }
    }

    如果使用default給數組或對象類型的數據賦默認值,那么要定義成一個函數。


    要求數據必傳

    如果要求某個數據必須傳給子組件,那么可以為它設置required。
    格式:

    props: {
        content: {
           type: String,
           required: true
       }
    }

    如果沒傳,會報Missing required prop: "xxx"的錯。


    自定義驗證函數:

    如果想要更精確的校驗,可以使用validator,里面是一個函數,函數的第一個參數就是傳入的值,當函數內返回true時,這個值才會校驗通過。
    以下的代碼是要求傳入的字符串長度大于6位的校驗:

            Vue.component('child', {
              props: {
                content: {
                    type: String,
                    validator: function(value) {
                        return (value.length > 6)
                    }
                }
              }

    如果驗證不通過,會報Invalid prop: custom validator check failed for prop "xxx"的錯。



    傳遞靜態或動態Prop

    • 傳遞靜態或動態的prop意思就是傳遞的是一個常量還是變量。
    • 傳遞常量的時候:
      • 如果是字符串,可以不使用v-bind。
      • 如果是數字,布爾值,數組,對象,那么需要使用vue的v-bind來設置屬性,因為使用普通的屬性設置會被認為是字符串,使用v-bind的時候會被認為是js表達式(從而成功識別成正確的類型)。
    • 傳遞變量的時候都要使用v-bind,不然無法識別成一個變量。


    補充:

    • 沒有講的內容:非 Prop 的特性



    給組件綁定原生的事件


    用下面的代碼來說一個問題:

    
    
        
        demo
    
        
          


    上面的代碼你會發現點擊了按鈕卻沒有調用函數。
    而下面的按鈕按了會打出child。

    
    
        
        demo
    
        
          


    • 在上面我們提過了父子數據傳遞,我們知道了父組件的數據需要props來傳遞給子組件,說明了父組件的數據是不跟子組件共享的。
    • 而事件也是這樣的,在我們使用組件的時候,并不能直接監聽一些事件的發生。【例如上面的子組件傳數據給父組件也需要使用emit。】
    • 對于父組件來說,這個組件是子組件下的按鈕,所以直接點擊這個按鈕并不會觸發事件【或者說你可以認為點擊了事件了,但是沒有emit出來,所以父組件監聽不到】。
    • 而如果希望點擊按鈕的時候能夠觸發出按鈕的原生事件(不把它當作子組件下的按鈕),那么需要把它綁定成原生事件。我們可以使用.native來修飾事件來說明監聽的是一個原生事件。


    下面的代碼是使用了emit來達到同樣效果的代碼:

    
    
        
        demo
    
        
          



    template

    • template是vue中的一個元素。它是一個不會渲染到頁面的元素,通常地它有如下幾個用處:
      • 由于不會被渲染處理,可以在template上使用使用v-if,把一個