亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

后端開(kāi)發(fā)者的Vue學(xué)習(xí)之路(三)

番茄西紅柿 / 3112人閱讀

摘要:使用組件全局定義組件,第一個(gè)參數(shù)是組件名,的值是組件的內(nèi)容這是個(gè)待辦項(xiàng)實(shí)例化是必須的,要把使用組件的區(qū)域交給管理局部注冊(cè)組件局部注冊(cè)組件全局注冊(cè)往往是不夠理想的。

目錄

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

首發(fā)日期:2019-01-26


上節(jié)內(nèi)容回顧

  • 數(shù)據(jù)綁定:v-model
  • 樣式綁定:v-bind:class,v-bind:style
  • 事件:v-on
  • Vue指令
  • 數(shù)組操作(知道哪些數(shù)組操作是能被vm層監(jiān)聽(tīng)到并能響應(yīng)式更新到視圖上的)
  • Vue的元素復(fù)用問(wèn)題(不使用key時(shí)會(huì)盡量復(fù)用)

組件


【官方的話】組件系統(tǒng)是 Vue 的另一個(gè)重要概念,因?yàn)樗且环N抽象,允許我們使用小型、獨(dú)立和通??蓮?fù)用的組件構(gòu)建大型應(yīng)用。仔細(xì)想想,幾乎任意類型的應(yīng)用界面都可以抽象為一個(gè)組件樹:

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


什么是組件

  • 在以前的多頁(yè)面開(kāi)發(fā)的時(shí)候,我們可能會(huì)經(jīng)常需要一個(gè)“頂部菜單欄”,于是我們?cè)诿總€(gè)html文件中都要加上關(guān)于“頂部菜單欄”的代碼??赡苣銜?huì)想這份代碼能夠“復(fù)用”就好了。而組件可以定義模板,從而達(dá)到復(fù)用代碼的作用。
  • 組件可以大大提高我們構(gòu)建頁(yè)面的效率。
  • 你可以將組件進(jìn)行任意次數(shù)的復(fù)用
    下面用代碼來(lái)演示一下"復(fù)用效果":
    
      

代碼效果:


組件注冊(cè)

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


全局注冊(cè)組件

  • 全局注冊(cè)的組件可以用在其被注冊(cè)之后的任何 (通過(guò) new Vue) 新創(chuàng)建的 Vue 實(shí)例中,也包括其組件樹中的所有子組件的模板中?!疽粋€(gè)Vue應(yīng)用只有一個(gè)根實(shí)例,但還允許有其他的實(shí)例。在 Vue 里,一個(gè)組件本質(zhì)上是一個(gè)擁有預(yù)定義選項(xiàng)的一個(gè) Vue 實(shí)例?!?/li>
  • 全局注冊(cè)的行為必須在根 Vue 實(shí)例 (通過(guò) new Vue) 創(chuàng)建之前發(fā)生
  • 全局注冊(cè)的組件可以在另一個(gè)組件中使用。


    
        
        
    

    
        


局部注冊(cè)組件


全局注冊(cè)往往是不夠理想的。比如,如果你使用一個(gè)像 webpack 這樣的構(gòu)建系統(tǒng),全局注冊(cè)所有的組件意味著即便你已經(jīng)不再使用一個(gè)組件了,它仍然會(huì)被包含在你最終的構(gòu)建結(jié)果中。這造成了用戶下載的 JavaScript 的無(wú)謂的增加。

在這些情況下,你可以通過(guò)一個(gè)普通的 JavaScript 對(duì)象來(lái)定義組件:

    
      


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

    
      


使用細(xì)節(jié)


組件注冊(cè)的命名規(guī)范:

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


    
      


組件中只有一個(gè)根元素

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

如果你確實(shí)要有多個(gè)元素,那么要有一個(gè)根元素包裹它們:


組件也是一個(gè)實(shí)例


組件也是一個(gè)實(shí)例,所以組件也可以定義我們之前在根實(shí)例中定義的內(nèi)容:data,methods,created,components等等。
但一個(gè)組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝


組件在某些元素中渲染出錯(cuò)

在一些html元素中只允許某些元素的存在,例如tbody元素中要求有tr,而不可以有其他的元素(有的話會(huì)被提到外面)。下面是一個(gè)元素被提到外面的例子【而ul并沒(méi)有太嚴(yán)格,所以我們?cè)谇懊娴膖odo-list的例子中能夠演示成功】

下圖可以看的出來(lái)div被提到table外面了:

這是為什么呢?目前來(lái)說(shuō),我們?cè)陧?yè)面中其實(shí)是先經(jīng)過(guò)html渲染再經(jīng)過(guò)vue渲染的(后面項(xiàng)目話后是整體渲染成功再展示的),當(dāng)html渲染時(shí),它就發(fā)現(xiàn)了tr里面有一個(gè)“非法元素”,所以它就把我們自定義的組件提到了table外面。
解決方案:
使用tr元素,元素里面有屬性is,is的值是我們要使用的組件名

    
        



但不會(huì)在一下情況中出錯(cuò):

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


    子組件向父組件傳輸數(shù)據(jù)

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


    演示代碼如下:

        
            

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


    非父子組件之間的傳值

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

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


    使用bus傳輸數(shù)據(jù)的步驟:

    1. 在Vue的原型上定義vue:Vue.prototype.bus = new Vue()
    2. 當(dāng)數(shù)據(jù)發(fā)生變化時(shí),調(diào)用emit:this.bus.$emit(change,當(dāng)前組件的數(shù)據(jù))
    3. 在組件上監(jiān)聽(tīng)bus的事件:this.bus.$on(change,一個(gè)用于賦值的函數(shù))
    4. 在函數(shù)中獲取事件觸發(fā)帶過(guò)來(lái)的參數(shù),賦給當(dāng)前組件,從而實(shí)現(xiàn)兩邊數(shù)據(jù)同步。

    下面的代碼是點(diǎn)擊某個(gè)組件發(fā)生數(shù)據(jù)變化時(shí),另一個(gè)組件的數(shù)據(jù)也發(fā)生變化:

        
            


    單向數(shù)據(jù)流

    • 單向數(shù)據(jù)流:props使得父組件的數(shù)據(jù)能夠傳輸?shù)阶咏M件,而且傳輸?shù)脑磾?shù)據(jù)發(fā)生改變時(shí),子組件也會(huì)發(fā)生改變。但如果在子組件中更改prop,這是不行的,會(huì)報(bào)警告。
    • 每次父級(jí)組件發(fā)生更新時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。如果允許你在子組件中修改父組件傳入的數(shù)據(jù)的話,使用了父組件的這個(gè)數(shù)據(jù)的所有子組件的數(shù)據(jù)都會(huì)被修改(這樣就降低了組件的復(fù)用效果,導(dǎo)致數(shù)據(jù)流行不確定,難以確定這個(gè)數(shù)據(jù)是在哪個(gè)組件中修改的,而且是一個(gè)相對(duì)危險(xiǎn)的行為)
    • 你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告?!具@就是單向數(shù)據(jù)流】
    • 如果你確實(shí)需要修改:
      • 那么你應(yīng)該創(chuàng)建一個(gè)子組件內(nèi)部的數(shù)據(jù),這個(gè)內(nèi)部數(shù)據(jù)由傳入的prop的數(shù)據(jù)進(jìn)行初始化。(也就是進(jìn)行數(shù)據(jù)拷貝)
      • 又或者你可以使用計(jì)算屬性。



    Props屬性


    命名規(guī)范:

    大小寫問(wèn)題

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

    如果在屬性中也使用駝峰命名法命名屬性的時(shí)候會(huì)報(bào)這樣的錯(cuò):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屬性中使用駝峰命名法的屬性,那么這個(gè)限制就不存在了。


    參數(shù)校驗(yàn)

    限制props的類型

    有時(shí)候需要使用第三方的組件的時(shí)候,所以會(huì)需要傳輸數(shù)據(jù)給這個(gè)組件來(lái)渲染。但如何限制傳入的數(shù)據(jù)的類型呢?

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


    格式:

    props: {
    // 數(shù)據(jù)名:數(shù)據(jù)類型
      title: String,
      likes: Number,
      ...
    }


    如果傳入的類型不對(duì),那么會(huì)報(bào)Invalid prop: type check failed for prop "xxx". Expected String with value "xxx", got Number with value xxx.的錯(cuò)誤。


    如果允許多種值,可以定義一個(gè)數(shù)組:

    props: {
      content: [String,Number]
    }


    設(shè)置默認(rèn)值

    我們也可以給props中的數(shù)據(jù)設(shè)置默認(rèn)值,如果使用default設(shè)置值,那么沒(méi)有傳某個(gè)數(shù)據(jù)時(shí)默認(rèn)使用這個(gè)數(shù)據(jù)。

    props: {
      content: {
      type:[String,Number],
      default:'我的默認(rèn)值'
      }
    }

    如果使用default給數(shù)組或?qū)ο箢愋偷臄?shù)據(jù)賦默認(rèn)值,那么要定義成一個(gè)函數(shù)。


    要求數(shù)據(jù)必傳

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

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

    如果沒(méi)傳,會(huì)報(bào)Missing required prop: "xxx"的錯(cuò)。


    自定義驗(yàn)證函數(shù):

    如果想要更精確的校驗(yàn),可以使用validator,里面是一個(gè)函數(shù),函數(shù)的第一個(gè)參數(shù)就是傳入的值,當(dāng)函數(shù)內(nèi)返回true時(shí),這個(gè)值才會(huì)校驗(yàn)通過(guò)。
    以下的代碼是要求傳入的字符串長(zhǎng)度大于6位的校驗(yàn):

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

    如果驗(yàn)證不通過(guò),會(huì)報(bào)Invalid prop: custom validator check failed for prop "xxx"的錯(cuò)。



    傳遞靜態(tài)或動(dòng)態(tài)Prop

    • 傳遞靜態(tài)或動(dòng)態(tài)的prop意思就是傳遞的是一個(gè)常量還是變量。
    • 傳遞常量的時(shí)候:
      • 如果是字符串,可以不使用v-bind。
      • 如果是數(shù)字,布爾值,數(shù)組,對(duì)象,那么需要使用vue的v-bind來(lái)設(shè)置屬性,因?yàn)槭褂闷胀ǖ膶傩栽O(shè)置會(huì)被認(rèn)為是字符串,使用v-bind的時(shí)候會(huì)被認(rèn)為是js表達(dá)式(從而成功識(shí)別成正確的類型)。
    • 傳遞變量的時(shí)候都要使用v-bind,不然無(wú)法識(shí)別成一個(gè)變量。


    補(bǔ)充:

    • 沒(méi)有講的內(nèi)容:非 Prop 的特性



    給組件綁定原生的事件


    用下面的代碼來(lái)說(shuō)一個(gè)問(wèn)題:

    
    
        
        demo
    
        
          


    上面的代碼你會(huì)發(fā)現(xiàn)點(diǎn)擊了按鈕卻沒(méi)有調(diào)用函數(shù)。
    而下面的按鈕按了會(huì)打出child。

    
    
        
        demo
    
        
          


    • 在上面我們提過(guò)了父子數(shù)據(jù)傳遞,我們知道了父組件的數(shù)據(jù)需要props來(lái)傳遞給子組件,說(shuō)明了父組件的數(shù)據(jù)是不跟子組件共享的。
    • 而事件也是這樣的,在我們使用組件的時(shí)候,并不能直接監(jiān)聽(tīng)一些事件的發(fā)生?!纠缟厦娴淖咏M件傳數(shù)據(jù)給父組件也需要使用emit?!?/li>
    • 對(duì)于父組件來(lái)說(shuō),這個(gè)組件是子組件下的按鈕,所以直接點(diǎn)擊這個(gè)按鈕并不會(huì)觸發(fā)事件【或者說(shuō)你可以認(rèn)為點(diǎn)擊了事件了,但是沒(méi)有emit出來(lái),所以父組件監(jiān)聽(tīng)不到】。
    • 而如果希望點(diǎn)擊按鈕的時(shí)候能夠觸發(fā)出按鈕的原生事件(不把它當(dāng)作子組件下的按鈕),那么需要把它綁定成原生事件。我們可以使用.native來(lái)修飾事件來(lái)說(shuō)明監(jiān)聽(tīng)的是一個(gè)原生事件。


    下面的代碼是使用了emit來(lái)達(dá)到同樣效果的代碼:

    
    
        
        demo
    
        
          



    template

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