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

資訊專欄INFORMATION COLUMN

理解vue中的組件(二)

Nino / 2962人閱讀

摘要:往往定義組件的構造器后,不需要手動的進行初始化,而是在其他組件的模板中當成標簽來使用,這時候需要調用注冊成組件。這樣設計的目的是防止從子組件意外改變父級組件的狀態,從而導致應用的數據流向難以理解。

上節說到組件https://segmentfault.com/a/1190000009236700,這一節繼續來學習組件:

原文博客地址,歡迎學習交流:點擊預覽
從github上獲取本文代碼:示例代碼

封裝的組件要具備復用性和通用性。

先來說復用,復用主要是復用 HTML 結構,外加這塊結構中的交互 js,和針對這一塊設置的 css。 這三者是構成一個組件最基本的要素,這三者相互隔離有相互作用,將三者聚合起來,在需要使用的地方,類似一個變量(標簽對)一樣,會引用這一塊的所有功能,可以多次使用。

在 vue 中提供了單文件組件,一個文件就是一個組件,這樣把組件模塊化的方式,讓開發者更方便的利用組件堆積頁面。將三者聚合在一個文件中,孤立的存在,減少了改動組件而影響外界的風險,極大的提高了代碼可維護性。

再說通用性,在討論通用性這點上,要向兩個方面思考:

外界使用組件,對組件所需要的數據進行定制,由外界傳遞進來(內部可以設置默認值)

組件內部的交互要通知給外界,并在外界的控制下產生影響,做不同事情。

組件達到復用后,可以在多個地方使用,而使用的位置不同,需要展示的數據也不同,此時封裝的組件要具有通用性,組件內部則由外界使用組件時來決定將要顯示的數據,需要將數據傳遞給組件。

組件的內部除了需要數據外,不可避免的還有交互,當完成一個交互后,需要對外界產生影響,這不能在組件內部做具體的事情,因為使用的位置不同,所產生的效果也不一樣,而完成這一系列事情則交給外界來決定,需要組件內部通信給外界,告訴外界,內部完成了一次交互。

注冊使用組件

從封裝一個自定義的下拉框 custom-select 組件開始。

要達到封裝性好,并且可以寫多種功能的代碼塊,那么組件本身就是一個函數或者類,需要使用 Vue.extend( options ) 來創建構造器,這個構造器可以由開發者自己手動初始化掛載,也可以注冊成組件在其他組件的模板中使用。

在 body 中放置掛載點:

定義組件的構造器,并手動初始化,手動掛載:

let customeSelect = Vue.extend({
    template: `
        

這是一個定義的下拉框

請選擇:北京

  • 北京
  • 上海
  • 杭州
` }) // 手動初始化,掛載到頁面的掛載點上 new customeSelect().$mount("#app");

選擇手動初始化的方式,調用內置方法 $mount 方法進行掛載,隨后組件的模板進行編譯,替換掉掛載點,渲染在頁面中。

往往定義組件的構造器后,不需要手動的進行初始化,而是在其他組件的模板中當成標簽來使用,這時候需要調用 Vue.component( id, [definition] ) 注冊成組件。

// 注冊組件,傳入一個擴展過的構造器
Vue.component("my-component", Vue.extend({ /* ... */ }))

// 注冊組件,傳入一個選項對象 (自動調用 Vue.extend)
Vue.component("my-component", { /* ... */ })

// 獲取注冊的組件 (始終返回構造器)
var MyComponent = Vue.component("my-component")

根據注冊組件的語法,其實是可以省略調用 Vue.extend 這一步,只需要傳入 選項對象即可,內部會自定調用 Vue.extend ,所以定義組件變成了這樣的簡寫方式:

Vue.component("custome-select",{
    template: `
        

這是一個定義的下拉框

請選擇:北京

  • 北京
  • 上海
  • 杭州
` })

將來 custome-select 就當成了標簽使用在其他組件的模板中 < custome-select>< /custome-select>,Vue在編譯模板時,就回去找這種自定義標簽是否是一個組件,如果已經注冊的話,就會把注冊的構造器進行初始化,編譯組件模板,最終將編譯后的模板替換掉自定義標簽的位置。如果沒有注冊直接使用,則會拋出錯誤。

關于組件名稱的命名:

采用烤串(kebab-case)命名,custome-select

采用駝峰命名( PascalCase), customeSelect

名稱不能是HTML規定的標簽名,比如div、span、header、footer等等。。。

注意:注冊時隨便使用兩種命名方式的任何一種,在模板中一律采用烤串命名才有效。

定義掛載點,并使用組件:

啟動應用:

new Vue({
    el: "#app"
})

最終渲染后的結構為:

這是一個定義的下拉框

請選擇:北京

  • 北京
  • 上海
  • 杭州
給組件定制數據傳遞props

目前 HTML 達到了復用的目的,但使用多次依然顯示的是寫死的數據。作為顯示數據的 HTML 結構,在不同地方使用,所要展示的數據由外界來決定,這就需要給組件傳遞數據。

而傳遞參數實際上就是給組件的構造器傳遞參數,本質上就是給函數傳參。函數的參數分為實參和形參兩個部分:

實參是實際傳遞給函數的參數

形參是用來接收數據所聲明的變量

現在組件寫在模板中以標簽對的形式呈現,需要傳遞實際的參數,唯一的地方就是寫在行間作為自定義屬性,而傳遞的參數會有很多個,最好表明具體的含義,需要和組件約定好屬性名,傳遞參數:

在組件中需要顯示的用 props 接收傳遞的數據,這樣的好處就是一旦看到組件,就會很清晰快速的了解到組件所需要的數據。

注意: 在行間寫上自定義屬性,要解析為數組,在屬性名前加上 v-bind,解析為 javascript 表達式,否則只能當成是字符串。

具體如下:

Vue.component("custome-select",{
    // 關于props具體參考:
    // https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E7%B1%BB%E5%9E%8B
    // https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E9%AA%8C%E8%AF%81
    props:{
        title: {
            type: String,
            default: "這是一個定義的下拉框"
        },
        list:{
            type: Array,
            default(){return []}
        },
        selectIndex:{
            type: Number,
            default:0
        }
    },
    template: `
        

{{title}}

請選擇:{{list[selectIndex]}}

  • {{item}}
` })

在組件中約定了三個需要接收的參數,分別寫出了接受的類型和默認值,props參數文檔如下:

屬性 說明 類型 默認值
title 定制組件的標題 String "這是一個定義的下拉框""
list 定制組件的下拉列表 Array []
selectIndex 選擇要展示的一項 String 0

有了文檔,很清晰的知道每一個屬性代表的意思,傳入響應的參數后,就會達到預期的效果。

組件自身狀態data

以上渲染后直接把下拉框顯示了出來,下拉框應該是在點擊 p 標簽時候才能顯示,再次點擊就隱藏掉,要實現這樣的一個顯示隱藏切換功能。

Vue 中不提倡直接操作 DOM,需要設置一個狀態來確定 DOM 的狀態,當需要改變 DOM 時,只需要改變設置好的狀態即可,把我們的關注點放在狀態的維護上,而無需手動操作 DOM 改變。

這個狀態不受外界的影響,屬于是組件自身的狀態變化,定義在組件內部,并且改變時只能由組件自身更改。

具體如下:

Vue.component("custome-select",{
    ... 省略了props設置
    data(){
        return {
            show: false  // 一開始狀態為false,也就是不顯示下拉列表
        }
    },
    template: `
        

{{title}}

請選擇:{{list[selectIndex]}}

  • {{item}}
`, methods:{ toggleShow(){ this.show = !this.show; } } })

以上做了三件事情:

data 中設置一個狀態為 show,初始值為 false,來表示下拉列表為隱藏狀態

在模板上使用指令 v-show="show" 控制 DOM 的顯示隱藏

p 綁定事件,切換 show 的值,一旦改變,自動更新 DOM 到對應狀態上,也就是 true 顯示,false 隱藏

Vuejs 這個框架要做的就是狀態和UI保持同步。

單向數據流

單向數據流顧名思義就是單方向的數據流向,也就是數據只能從一邊流向另一邊,反過來則不行,如黃河之水從天上來,卻不能再流回到天上去。具體到組件中,就是:父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,子組件改變不能改變父組件。這樣設計的目的是防止從子組件意外改變父級組件的狀態,從而導致應用的數據流向難以理解。

與之對應的就是雙向數據流,父組件子組件都可以任意修改,互相產生影響,這樣的話使用這套數據的其他組件也會跟著變化,變得非常的詭異。

在復雜的應用中,控制數據有規則的改變和傳遞非常重要,如果不是單向數據流的限制,任何組件都能修改數據,就跟定義全局的數據在任何程序都能修改一樣,最終經過多個函數的調用修改后,出現了問題,不能準確的定位到具體的函數中,排查問題會變的非常的困難。

每次父級組件發生更新時,子組件中所有的 prop 都將會刷新為最新的值。由父組件傳遞給子組件的數據,子組件內部不能改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發出警告。

來個例子說明一下。上面的例子中,需要在下拉框中選擇具體的的一項,顯示在 p標簽中,要顯示的數據是通過外界傳遞的 selectIndex 來決定從 list 中選取哪一項。那我們可以這樣來做,在點擊下拉框的某一項時,改變 selectIndex 為點擊的一項的下標即可,具體如下:

HTML 代碼:

JavaScript代碼:

Vue.component("custome-select",{
    props:{
        // 省略了title和list....
        selectIndex:{
            type: Number,
            default:0
        }
    },
    data(){
        return {
            show: false  // 一開始狀態為false,也就是不顯示下拉列表
        }
    },
    template: `
        

{{title}}

請選擇:{{list[selectIndex]}}

  • {{item}}
`, methods:{ toggleShow(){ this.show = !this.show; }, changeIndex(index){ // 改變為選中的下標,此時會報錯 this.selectIndex = index; } } }) new Vue({ el: "#app" })

以上代碼做的事情:

接收外界傳入的 selecteIndex,在模板中選擇對應的值{{list[selectIndex]}}

給下拉框的每一項綁定事件,并傳遞各自的下標

傳遞下標給到 changeIndex 函數,改變selectIndex的值

控制臺報錯:[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop"s value. Prop being mutated: "selectIndex"大致的意思是:不能直接修改組件的props值,當父組件重新渲染時候會重寫這個。在組件中使用data或者computed屬性來代替修改prop的值。

以上的報錯已經警告了,不能直接修改props的值,但是組件內部是可以修改組件內部數據 data ,所以修改如下:

// 其他代碼省略
Vue.component("custome-select",{
    data(){
        return {
            currentIndex: this.selectIndex // 把selectIndex作為currentIndex的初始值
        }
    },
    template: `
        

{{title}}

請選擇:{{list[currentIndex]}}

  • {{item}}
`, methods:{ changeIndex(index){ // 改變自己內部狀態currentIndex this.currentIndex = index; } } })

以上代碼分析:

在 data 中定義組件內部狀態currentIndex,將props中的selectIndex的值,作為currentIndex的初始值

修改模板中取值的selectIndex為currentIndex

點擊改變currentIndex,此時修改的是組件內部狀態,不是props的值,修改成功

從以上的例子中可以看出來,data 中定義的就是組件內部狀態,只在組件內部更改,而傳遞的 props 不能在組件內修改,可以通過賦值給data,修改data的值來更新組件自身的狀態。

父組件監聽,子組件發布

上面說的是父組件向子組件定制數據傳遞 props,在子組件內部會產生一些交互。

子組件內部交互一旦發生后,父組件是需要根據子組件的交互會產生一些影響,比如改變顏色,顯示文字等。父組件這些變換又不能寫在子組件的交互中,因為子組件是通用的組件。一旦寫了某個父組件的業務代碼,只能和這個父組件綁定在一起,不能使用在別的地方了了,此時組件不能達到通用的目的。

舉個例子:
以下使用了兩次 custome-select 組件,當點擊第一個組件的下拉框某一項時候,就需要改變 class 為 test1 的div 樣式為 red 色。當點擊第二個組件的下拉框某一項時候,就需要改變 class 為 test2 的div 樣式為 blue 色。

第一個需求
第二個需求

使用了兩次組件,組件內部點擊下拉框時不能寫具體的處理第一個需求還是第二個需求。而是交到外部的父組件來決定,這時候父組件就需要知道子組件內部是否點擊了下拉框。而點擊下拉框這個動作是由用戶觸發的,不知何時會觸發一次,那怎么辦呢?
跟原生的元素處理思路一樣,假定以后用戶點擊了這個元素后,需要改變頁面中樣式,那么就需要監控這個元素的點擊事件,只要用戶點擊了,觸發事件處理函數,在函數中寫具體改變樣式這個動作。
HTML代碼:

JavaScript代碼:

以上代碼是 DOM0 級時代的寫法,直接在行間寫監聽事件,這樣寫更直觀。目的就是當有用戶點擊了按鈕一下,瀏覽器內部就會發布一個 click 事件,而正好我們在元素上監聽了 click 事件,就會把對應的事件處理函數觸發,從而達到開發者的目的,對頁面做出一些變化。

組件標簽使用在模板中,此時外界需要知道組件內部發生了的交互,那么思路一致,也需要在行間監聽事件,不過此事件名字不限于是 w3c 規定的事件名,可以自定義事件名,結合 Vue 中綁定事件的方式,代碼如下:

第一個需求
第二個需求

把事件處理函數寫在選項對象中:

new Vue({
    el: "#app",
    data: {
        color1: "",
        color2: ""
    },
    methods: {
        // 第一個需求
        changeTest1Handle(){
            this.color1 = "red";
        },
        // 第二個需求
        changeTest2Handle(){
            this.color2 = "blue";
        }
    }
})

以上代碼準備完畢,去點擊下拉選項,并沒有觸發父組件的函數,并沒有完成需求,為什么呢?
在原生元素上在行間監控事件,用戶點擊元素后,瀏覽器會發布 click 事件。而現在換做是使用自定義事件來監控子組件內部產生的交互,這就需要在子組件內部自己發布這個自定義的事件,否則監控的自定義事件是無效的。

那什么時候發布事件呢?就是在用戶點擊了下拉框的選項時候發布這個自定義事件即可。

你可以這樣來理解,監聽原生事件 click ,只需要監聽,開發者無需手動的在瀏覽器內部寫發布事件,click 事件名是瀏覽器給開發者約定的名字。而現在我們需要自己設計子組件發布事件,父組件監聽這樣的機制。所以需要開發者自己約定事件的名字和手動的在組件中發布事件。在 Vue 中這樣的訂閱/發布模式已經寫好,開發者只需要調用即可。

在子組件中發布事件:

// 其他代碼省略
methods:{
    changeIndex(index){
        this.currentIndex = index;
        // 在點擊選項時候產生交互,手動發布事件,通知父組件
        this.$emit("click-option");
    }
}

當點擊選項時候,父組件中會完成不同的需求,改變不同元素的顏色。

以上代碼父子組件之間完全的解耦,父組件中不使用這個組件,依然可以工作,子組件不使用在這個組件中,可以使用在任意其他的組件中。如果父組件關系子組件內部選中下拉框一項這個交互,只需要監聽 click-option這個自定義事件,不關心則不監聽。

總結

以上可以看出一個組件數據的來源有兩個:

組件自身的數據,寫在 data 中

父組件傳遞的數據,寫在props中

父子組件之間通信:

父 ---> 子,使用 props

子 ---> 父,訂閱發布模式

以上屬于個人理解,如有偏差歡迎指正學習,謝謝。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98081.html

相關文章

  • Vue.js學習系列 —— vuex學習實踐筆記(附DEMO)

    摘要:有興趣的同學可以查看之前發布的文章學習系列一學習實踐筆記附學習系列二學習實踐筆記附學習系列三和網絡傳輸相關知識的學習實踐學習系列四打包工具的使用學習系列五從來聊聊學習系列項目地址項目暫時有點亂,之后會進行整理優化。 上次學習了vue-router的使用,讓我能夠在各個頁面間切換,將頁面搭建了起來。這次則要學習vue的狀態管理模式——vuex。它類似于redux來應用的全局狀態。 注:本...

    DobbyKim 評論0 收藏0
  • Vue學習日記()——Vue核心思想

    摘要:前言是一個提供數據雙向綁定的庫,其核心思想無非就是數據驅動組件系統數據驅動的核心是一個響應的數據綁定系統,它讓數據與保持同步非常簡單。和所以只兼容及以上版本,可稱為基于依賴收集的觀測機制。核心是,即,保證數據和視圖的一致性。 前言 Vue.js是一個提供MVVM數據雙向綁定的庫,其核心思想無非就是: 數據驅動 組件系統 數據驅動 Vue.js 的核心是一個響應的數據綁定系統,它讓數...

    taohonghui 評論0 收藏0
  • Vue學習日記()——Vue核心思想

    摘要:前言是一個提供數據雙向綁定的庫,其核心思想無非就是數據驅動組件系統數據驅動的核心是一個響應的數據綁定系統,它讓數據與保持同步非常簡單。和所以只兼容及以上版本,可稱為基于依賴收集的觀測機制。核心是,即,保證數據和視圖的一致性。 前言 Vue.js是一個提供MVVM數據雙向綁定的庫,其核心思想無非就是: 數據驅動 組件系統 數據驅動 Vue.js 的核心是一個響應的數據綁定系統,它讓數...

    Scholer 評論0 收藏0
  • 前端面試匯總VUE()

    摘要:采用了新舊的對比,獲取差異的,最后一次性的更新到真實上。對基本屬性進行監聽對對象進行監聽對對象某一個屬性監聽監聽自定義指令全局指令,第一個參數是指令名,第二個參數是一個對象,對象內部有個的函數,函數里有這個參數,表示綁定了這個指令的元素。 11.vue 虛擬DOM的理解 Web界面由DOM樹(樹的意思是數據結構)來構建,當其中一部分發生變化時,其實就是對應某個DOM節點發生了變化,??...

    Sanchi 評論0 收藏0

發表評論

0條評論

Nino

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<