成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深刻理解Vue中的組件

mdluo / 3206人閱讀

摘要:還可以在某個(gè)實(shí)例中注冊(cè)只有自己能使用的組件。當(dāng)在一個(gè)組件中,使用了其他自定義組件時(shí),就會(huì)利用子組件的屬性和事件來和父組件進(jìn)行數(shù)據(jù)交流。正確的做法是,在父組件中綁定屬性值時(shí),加上修飾符。

2019-06-20更新:

Vue2.6已經(jīng)更新了關(guān)于內(nèi)容插槽和作用域插槽的API和用法,為了不誤導(dǎo)大家,我把插槽的內(nèi)容刪除了。詳情請(qǐng)看官網(wǎng)

2018-07-19更新:

更新作用域插槽的屬性: scope -> slot-scope;

添加了對(duì)象解構(gòu)。

今天看了下Vue官網(wǎng)上關(guān)于組件的教程,感覺內(nèi)容還挺多,現(xiàn)在把組件中基本的知識(shí)梳理一下。

組件的基本使用 注冊(cè)組件

注冊(cè)組件就是利用Vue.component()方法,先傳入一個(gè)自定義組件的名字,然后傳入這個(gè)組件的配置。

 Vue.component("mycomponent",{
    template: `
這是一個(gè)自定義組件
`, data () { return { message: "hello world" } } })

如上方式,就已經(jīng)創(chuàng)建了一個(gè)自定義組件,然后就可以在Vue實(shí)例掛在的DOM元素中使用它。

 

直接使用Vue.component()創(chuàng)建的組件,所有的Vue實(shí)例都可以使用。還可以在某個(gè)Vue實(shí)例中注冊(cè)只有自己能使用的組件。

var app = new Vue({
    el: "#app",
    data: {
    },
    components: {
      "my-component": {
        template: `
這是一個(gè)局部的自定義組件,只能在當(dāng)前Vue實(shí)例中使用
`, } } })
模板的要求

注意:組件的模板只能有一個(gè)根元素。下面的情況是不允許的。

template: `
這是一個(gè)局部的自定義組件,只能在當(dāng)前Vue實(shí)例中使用
`,
組件中的data必須是函數(shù)

可以看出,注冊(cè)組件時(shí)傳入的配置和創(chuàng)建Vue實(shí)例差不多,但也有不同,其中一個(gè)就是data屬性必須是一個(gè)函數(shù)。
這是因?yàn)槿绻馰ue實(shí)例那樣,傳入一個(gè)對(duì)象,由于JS中對(duì)象類型的變量實(shí)際上保存的是對(duì)象的引用,所以當(dāng)存在多個(gè)這樣的組件時(shí),會(huì)共享數(shù)據(jù),導(dǎo)致一個(gè)組件中數(shù)據(jù)的改變會(huì)引起其他組件數(shù)據(jù)的改變。

而使用一個(gè)返回對(duì)象的函數(shù),每次使用組件都會(huì)創(chuàng)建一個(gè)新的對(duì)象,這樣就不會(huì)出現(xiàn)共享數(shù)據(jù)的問題來了。

關(guān)于DOM模板的解析

當(dāng)使用 DOM 作為模版時(shí) (例如,將 el 選項(xiàng)掛載到一個(gè)已存在的元素上), 你會(huì)受到 HTML 的一些限制,因?yàn)?Vue 只有在瀏覽器解析和標(biāo)準(zhǔn)化 HTML 后才能獲取模板內(nèi)容。尤其像這些元素

    ,
      ,,
      ...

      自定義組件 被認(rèn)為是無效的內(nèi)容,因此在渲染的時(shí)候會(huì)導(dǎo)致錯(cuò)誤。這時(shí)應(yīng)使用特殊的 is 屬性:

      也就是說,標(biāo)準(zhǔn)HTML中,一些元素中只能放置特定的子元素,另一些元素只能存在于特定的父元素中。比如table中不能放置divtr的父元素不能div等。所以,當(dāng)使用自定義標(biāo)簽時(shí),標(biāo)簽名還是那些標(biāo)簽的名字,但是可以在標(biāo)簽的is屬性中填寫自定義組件的名字。

      應(yīng)當(dāng)注意,如果您使用來自以下來源之一的字符串模板,這些限制將不適用:

      當(dāng)父組件傳遞值為基本類型時(shí),在子組件中更改這個(gè)屬性會(huì)報(bào)錯(cuò)。正確的做法是,在父組件中綁定屬性值時(shí),加上.sync修飾符。

      然后在子組件中改變相應(yīng)的屬性

          methods: {
           changeArray () {
             this.counter++
             this.$emit("update:childArray", this.counter)
           }
         }

      子組件希望對(duì)傳入的prop進(jìn)行操作

      一般來說,是不建議在子組件中對(duì)父組件中傳遞來的屬性進(jìn)行操作的。如果真的有這種需求,可以這樣:

      父組件傳遞了一個(gè)基本類型值,那么可以在子組件中創(chuàng)建一個(gè)新的屬性,并以傳遞進(jìn)來的值進(jìn)行初始化,之后就可以操作這個(gè)新的屬性了

      props: ["initialCounter"],
      data: function () {
        return { counter: this.initialCounter }
      }

      父組件傳遞了一個(gè)引用類型值,為了避免更改父組件中相應(yīng)的數(shù)據(jù),最好是對(duì)引用類型進(jìn)行復(fù)制。復(fù)雜的情況,肯定應(yīng)該是深復(fù)制。

      給子組件傳遞正確類型的值

      同樣是上面的原因,靜態(tài)的給子組件的特性傳遞值,它都會(huì)把他當(dāng)做一個(gè)字符串。

      
      

      子組件中,特性的值是字符串 "1" 而不是 number 1。如果想傳遞正確的數(shù)值,應(yīng)該使用v-bind傳遞,這樣就能把傳遞的值當(dāng)做一個(gè)表達(dá)式來處理,而不是字符串。

      
      
      Prop驗(yàn)證

      我們可以給組件的props屬性添加驗(yàn)證,當(dāng)傳入的數(shù)據(jù)不符合要求時(shí),Vue會(huì)發(fā)出警告。

      Vue.component("example", {
        props: {
          // 基礎(chǔ)類型檢測(cè) (`null` 意思是任何類型都可以)
          propA: Number,
          // 多種類型
          propB: [String, Number],
          // 必傳且是字符串
          propC: {
            type: String,
            required: true
          },
          // 數(shù)字,有默認(rèn)值
          propD: {
            type: Number,
            default: 100
          },
          // 數(shù)組/對(duì)象的默認(rèn)值應(yīng)當(dāng)由一個(gè)工廠函數(shù)返回
          propE: {
            type: Object,
            default: function () {
              return { message: "hello" }
            }
          },
          // 自定義驗(yàn)證函數(shù)
          propF: {
            validator: function (value) {
              return value > 10
            }
          }
        }
      })

      type 可以是下面原生構(gòu)造器:

      String

      Number

      Boolean

      Function

      Object

      Array

      Symbol

      type 也可以是一個(gè)自定義構(gòu)造器函數(shù),使用 instanceof 檢測(cè)。

       // 自定義Person構(gòu)造器
       function Person(name, age) {
          this.name = name
          this.age = age
        }
        Vue.component("my-component", {
          template: `
      名字: {{ person-prop.name }}, 年齡: {{ person-prop.age }}
      `, props: { person-prop: { type: Person // 指定類型 } } }) new Vue({ el: "#app2", data: { person: 2 // 傳入Number類型會(huì)報(bào)錯(cuò) } })
      非Prop類型的屬性

      也可以像在html標(biāo)簽中添加data-開頭的自定義屬性一樣,給自定義組件添加任意的屬性。而不僅限于data-*形式,這樣做的話,Vue會(huì)把這個(gè)屬性放在自定義組件的根元素上。一個(gè)自定義組件的模板只能有一個(gè)根元素。

      覆蓋非Prop屬性

      如果父組件向子組件的非prop屬性傳遞了值,那么這個(gè)值會(huì)覆蓋子組件模板中的特性。

      上面渲染的結(jié)果是,divatt屬性是helloParent。
      注意:前面已經(jīng)提到過,覆蓋原則對(duì)于classstyle不適用,而是采用了合并(merge)的原則。

      上面的渲染結(jié)果是,div的類名是class1 class2,行內(nèi)樣式是color:red; background:yellow;。

      自定義事件

      通過prop屬性,父組件可以向子組件傳遞數(shù)據(jù),而子組件的自定義事件就是用來將內(nèi)部的數(shù)據(jù)報(bào)告給父組件的。

      如上所示,共分為以下步驟:

      子組件在自己的方法中將自定義事件以及需要發(fā)出的數(shù)據(jù)通過以下代碼發(fā)送出去

       this.$emit("myclick", "這是我暴露出去的數(shù)據(jù)", "這是我暴露出去的數(shù)據(jù)2")

      第一個(gè)參數(shù)是自定義事件的名字

      后面的參數(shù)是依次想要發(fā)送出去的數(shù)據(jù)

      父組件利用v-on為事件綁定處理器

      這樣,在Vue實(shí)例的methods方法中就可以調(diào)用傳進(jìn)來的參數(shù)了

      注意: 在使用v-on綁定事件處理方法時(shí),不應(yīng)該傳進(jìn)任何參數(shù),而是直接寫v-on:myclick="onClick",不然,子組件暴露出來的數(shù)據(jù)就無法獲取到了

      綁定原生事件

      如果想在某個(gè)組件的根元素上監(jiān)聽一個(gè)原生事件。可以使用 .native 修飾 v-on

      探究v-model

      v-model可以對(duì)表單控件實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,它的原理就是利用了綁定屬性和事件來實(shí)現(xiàn)的。比如input控件。不使用v-model,可以這樣實(shí)現(xiàn)數(shù)據(jù)的雙向綁定:

      {{text}}

      上面的代碼同樣實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定。其本質(zhì)就是:

      inputvalue特性綁定到Vue實(shí)例的屬性text上,text改變,input中的內(nèi)容也會(huì)改變

      然后把表單的input事件處理函數(shù)設(shè)置為Vue實(shí)例的一個(gè)方法,這個(gè)方法會(huì)根據(jù)輸入?yún)?shù)改變Vue中text`的值

      相應(yīng)的,在input中輸入內(nèi)容時(shí),觸發(fā)了input事件,把event.target.value傳給這個(gè)方法,最后就實(shí)現(xiàn)了改變綁定的數(shù)據(jù)的效果。

      v-model就是上面這種方式的語法糖,也就是把上面的寫法封裝了一下,方便我們使用。

      使用自定義事件創(chuàng)建自定義的表單輸入組件

      理解了v-model的內(nèi)幕,也就可以把這個(gè)效果用在自定義表單組件上了。
      來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的只能輸入hello的表單輸入組件。

      {{hello}}
      定制組件的v-model

      默認(rèn)情況下,一個(gè)組件的 v-model 會(huì)使用 value 屬性和 input 事件,但是諸如單選框、復(fù)選框之類的輸入類型可能把 value 屬性用作了別的目的。model 選項(xiàng)可以回避這樣的沖突:

      Vue.component("my-checkbox", {
        model: {
          prop: "checked",   // 將輸入的特性改為checked
          event: "change"        // 觸發(fā)的自定義事件類型為change
        },
        props: {
          checked: Boolean,
          // this allows using the `value` prop for a different purpose
          value: String
        }
      })

      這樣設(shè)置的話,

      上面的代碼就等同于

      實(shí)際使用時(shí),與之前不同的地方是:

      把子組件中接收外部數(shù)據(jù)的prop屬性改為checked

      向父組件發(fā)出事件時(shí),事件類型應(yīng)改為change

      Vue.component("my-component3", {
          template: ``,
          props: ["checked"],        // 屬性名改變
          model: {
            prop: "checked",
            event: "change"
          },
          methods: {
            checkInput (value) {
              var hello = "hello"
              if (!hello.includes(value)) {
                this.$emit("change", hello)   // 事件類型改變
                this.$refs.input.value = hello
              } else {
                this.$emit("change", value)  // 事件類型改變
              }
            }
          }
        })
      動(dòng)態(tài)組件

      通過使用保留的 元素,動(dòng)態(tài)地綁定到它的 is 特性,可以讓多個(gè)組件使用同一個(gè)掛載點(diǎn),并動(dòng)態(tài)切換:

       

      也可以直接綁定到組件對(duì)象上:

      var Home = {
        template: `
      這是home組件
      ` } new Vue({ el: "#app6", data: { currentComponent: Home } })
      保留切換出去的組件,避免重新渲染

      如果把切換出去的組件保留在內(nèi)存中,可以保留它的狀態(tài)或避免重新渲染。為此可以添加一個(gè) keep-alive 指令參數(shù):

      
        
          
        
      

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84697.html

相關(guān)文章

  • Vue.js學(xué)習(xí)系列二 —— vuex學(xué)習(xí)實(shí)踐筆記(附DEMO)

    摘要:有興趣的同學(xué)可以查看之前發(fā)布的文章學(xué)習(xí)系列一學(xué)習(xí)實(shí)踐筆記附學(xué)習(xí)系列二學(xué)習(xí)實(shí)踐筆記附學(xué)習(xí)系列三和網(wǎng)絡(luò)傳輸相關(guān)知識(shí)的學(xué)習(xí)實(shí)踐學(xué)習(xí)系列四打包工具的使用學(xué)習(xí)系列五從來聊聊學(xué)習(xí)系列項(xiàng)目地址項(xiàng)目暫時(shí)有點(diǎn)亂,之后會(huì)進(jìn)行整理優(yōu)化。 上次學(xué)習(xí)了vue-router的使用,讓我能夠在各個(gè)頁面間切換,將頁面搭建了起來。這次則要學(xué)習(xí)vue的狀態(tài)管理模式——vuex。它類似于redux來應(yīng)用的全局狀態(tài)。 注:本...

    DobbyKim 評(píng)論0 收藏0
  • Vue原理】VModel - 白話版

    摘要:執(zhí)行的時(shí)候,會(huì)綁定上下文對(duì)象為組件實(shí)例于是中的就能取到組件實(shí)例本身,的代碼塊頂層作用域就綁定為了組件實(shí)例于是內(nèi)部變量的訪問,就會(huì)首先訪問到組件實(shí)例上。其中的獲取,就會(huì)先從組件實(shí)例上獲取,相當(dāng)于。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得...

    keke 評(píng)論0 收藏0
  • react.js,angular.js,vue.js學(xué)習(xí)哪個(gè)好?

    摘要:好好打基礎(chǔ),然后多嘗試不同風(fēng)格的框架,因?yàn)橹挥袊L試過后才能理解比如徐飛提到的各種權(quán)衡,也只有嘗試過后才能知道哪個(gè)能真正提升自己的開發(fā)效率。 今天看了幾篇關(guān)于這三個(gè)主流框架的PK,如標(biāo)題:react.js,angular.js,vue.js學(xué)習(xí)哪個(gè)好?相信每個(gè)人都有這種問題。 現(xiàn)在的前端框架層出不窮,作為前端開發(fā)者何去何從?fackbook的react.js盛世火熱,react nati...

    Towers 評(píng)論0 收藏0
  • 反思總結(jié)然后整裝待發(fā)

    摘要:保證上線后的版本不會(huì)因?yàn)g覽器緩存而產(chǎn)生影響。前端部分之后會(huì)有多人合作,為了提高效率決定采用組件化開發(fā)。對(duì)之后的維護(hù)工作造成了一點(diǎn)困擾。之后的日子里做到一周更新兩篇博文,主要是實(shí)際項(xiàng)目中遇到的具體問題來加以總結(jié)和分析,未完待續(xù)。 原文鏈接: http://xdlrt.github.io/2016/1...距離上次更博已經(jīng)過去兩個(gè)月了,終于也有時(shí)間能靜下心來想一些事情,也對(duì)這幾個(gè)月的生活做...

    twohappy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<