vue slot scope使用_Vue使用日記(10):插槽slot的使用
技術標籤:vue slot scope使用vue template 複用vue 只在父級容器移動vue 獲取元素寬度vue吸頂導航欄vue導航欄
在進行插槽的說明之前,先對一個概念進行說明:編譯作用域。
1、編譯作用域
官方給出的解析是:父模板裡的所有內容都是在父級作用域中編譯的;子模板裡的所有內容都是在子作用域中編譯的。
舉一個例子:
<div id="app"> <my-cpn v-show="isShow">my-cpn>div><template id="myCpn"> <h2>能否顯示出來呢h2>template><script> Vue.component('my-cpn',{ template:"#myCpn", data() { return { isShow:false } } } let app = new Vue({ el:"#app", data: { isShow:true } })script>
說明:這裡的元件能正常顯示出來,說明使用的是Vue例項身上的isShow屬性。
1)isShow屬性包含在子元件中,也包含在Vue例項中;
2)最終可以渲染出來,也就是說使用的是Vue例項的屬性;
3)使用的時候,是在父元件(Vue例項)中使用,那麼它的作用域就是父元件;
4)所以使用的是Vue例項中的isShow屬性,而不是子元件的。
2、插槽:slot
生活中有很多類似於插槽概念的事物:電腦的USB,插座的電源插槽,電腦主機板插槽等等。這些插槽的出現,目的是讓我們的裝置具有更多的可擴充套件性。比如電腦的USB可以使用我們插入U盤、手機、鍵盤、滑鼠和其他外接裝置。
元件的插槽也是出於同一個目的——使我們封裝的元件具有可擴充套件性,讓使用者決定元件內部到底展示什麼內容。
舉個例子,移動網站中的導航欄。移動開發中,幾乎每個頁面都會有導航欄,導航欄必然要封裝成一個元件,比如名為nav-bar,一旦封裝好了這個元件,我們就可以在其他頁面複用。但是,每個頁面的導航欄都長得一樣嗎?不是的,比如京東M站的導航欄。
說明:我們發現各個頁面的導航欄元件的內容是不相同的,但是同一個元件卻在多個頁面使用了,也就是說它既實現了可複用性,又實現了可擴充套件性。我們要怎樣實現元件的可複用性和可擴充套件性呢?答案就是使用插槽。
如何利用插槽實現上述這類元件的封裝呢?
原則是:抽取共性,保留不同。
像上面的導航欄元件,共性有很多,不同點也有很多。比如都是分為左中右三個部分,高度寬度這些都相同。但是每一部分內容都不同:有些是返回按鈕,有些卻是選單按鈕;中間部分有些是搜尋框,有些是標題等等。
使用slot的步驟:
1)在子元件中,使用特殊的元素就可以為子元件開啟一個插槽;
2)該插槽插入什麼內容取決於父元件如何使用。
注意:是在父元件使用子元件時,在父元件環境內將子元件的插槽替換成其他內容。
先從一個簡單的例子說明slot的使用:
<div id="app"> <my-cpn>my-cpn> <my-cpn> <h2>我是用來替換插槽預設內容的內容h2> my-cpn>div><template id="myCpn"> <div> <slot>我是插槽的預設內容slot> div>template><script> Vue.component('my-cpn',{ template:"#myCpn" } let app = new Vue({ el:"#app" })script>
說明:在父元件中(Vue例項中)使用元件,父元件中如果沒有在元件中插入內容,則顯示插槽的預設內容,否則替換插槽的預設內容。注意,插槽slot元素外部要使用根元素,一般使用div元素。
3、具名插槽
上面的例子中只簡單地使用了一個插槽,但是當子元件的功能複雜時,子元件的插槽可能並非只有一個。比如上面的京東導航欄元件,封裝時可能就需要三個插槽,分別代表左邊、中間、右邊。
那麼,外面(父元件)在給插槽插入內容時,如何區分替換的是哪一個呢?
這個時候,我們就需要給插槽起一個名字。
這種具有名字的插槽就稱為具名插槽。
具名插槽使用步驟:
1)非常簡單,只要給slot元素一個name屬性即可;
2)例如:;
3)替換時,使用slot屬性指出名字即可:slot="left">返回。
舉例說明:
<div id="app"> <my-cpn> <span slot="left">返回span> <span slot="center">標題span> <span slot="right">選單span> my-cpn>div><template id="myCpn"> <div> <slot name="left">我是左邊slot> <slot name="center">我是中間slot> <slot name="right">我是右邊slot> div>template><script> Vue.component('my-cpn',{ template:"#myCpn" } let app = new Vue({ el:"#app" })script>
說明:這裡將子元件中的插槽分別根據名字(left、center、right)替換成不同的內容:返回、標題和選單,當然這裡只是簡單的封裝和使用了導航欄元件。
另外,也可以只替換其中一部分插槽,例如:
<my-cpn> <span slot="left">返回span>my-cpn>
4、作用域插槽
某些情況下,我們需要父元件僅僅替換標籤元素,但是內容由子元件提供,這種插槽稱為作用域插槽。
總結就是:父元件替換插槽的標籤,但是內容由子元件來提供。
舉例說明:
<div id="app"> <my-cpn> <template slot-scope="slotData"> <ul> <li v-for="info in slotData.data">{{info}}li> ul> template> my-cpn>div><template id="myCpn"> <div> <slot :data="pLanguages">slot> div>template><script> Vue.component('my-cpn',{ template:"#myCpn", data(){ return { pLanguages:['JavaScript', 'Python', 'Swift', 'Go', 'C++'] } } }script>
說明:
1)子元件中的插槽綁定了data,並將pLanguages賦值給它;
2)然後在父元件中通過特定的指令slot-scope獲取子元件繫結的屬性,該指令後面的slotData是允許任意取的名字;
3)接著從slotData中取出子元件插槽繫結的data值:slotData.data。
注意:子元件中繫結屬性時,屬性名字不能是name這種特殊含義的名詞,可以使用data、age、height這些普通含義的名詞,因為name具有特殊含義,比如指代具名插槽,使用name會出錯。
然後在第三步取值時這樣取:slotData.data、slotData.age、slotData.height……
以上,是Vue插槽的使用說明,後續將對Vue其他知識點進行總結說明。