1. 程式人生 > >細說Vue作用域插槽,匹配應用場景。

細說Vue作用域插槽,匹配應用場景。

5.1 type 全部 應用場景 viewport document -c 技巧 lock

最近在官方文檔中看到,vue新增了一種插槽機制,叫做作用域插槽。要求的版本是2.1.0+。

首先來說一下:顧名思義,所謂作用域插槽,主要就在作用域,需要註意的是(以下幾點看不懂不要緊,配合下面的例子,你會一看就懂):

1. 組件中的slot標簽只能有有一個,而這一個slot用於替代組件調用時的多個標簽。即一個slot代替一組範圍的標簽,即為作用域。

2. 作用域插槽的特殊在於:可在上層作用域中通過臨時變量拿到組件定義時通過作用域插槽傳遞的數據。

3. 作用域插槽的技巧在於:可在上層作用域中通過拿到的數據選擇性地渲染標簽(即修改slot對應的標簽範圍)。

下面通過實際例子來一步一步地細說:

**擁有作用域插槽的組件定義(實際代碼中組件要在根實例創建之前定義):

        Vue.component("list-tpl", {
           props: ["list"],
           template: `
                <ul>
                    <li style="display:block;" v-for="(item, index) in list">
                        <slot :item="item"></slot>   // item為向上層傳遞的數據,單個slot在調用時轉化為作用域內的多個標簽
                    
</li> </ul> ` })

*根實例代碼,主要包括測試數據:

var app = new Vue({
           el: "#app",
           data: {
               list: [
                   {
                       name: "tate",
                       age: 26,
                       single: 
true, // 是否單身 stu: false // 是否是學生 }, { name: "kevin", age: 23, single: true, stu: true }, { name: "harden", age: 28, single: false, stu: false }, { name: "Jimmy", age: 29, single: false, stu: true } ] } })

*最重要的 組件調用

        <list-tpl :list="list">
            <!-- 調用的時候 a 為臨時變量,只用於獲取數據 -->
                <template slot-scope="a">
                    <!-- 若不加任何判斷,整個template中的標簽都會替換為定義時的slot -->
                    <h4>{{a.item.name}}</h4>
                    <h5>{{a.item.age}}</h5>
                    <!-- 技巧就在於通過a拿到的數據選擇性地渲染標簽,即修改單個slot對應的作用域範圍 -->
                    <span v-if="a.item.single">我是單身</span>
                    <span v-if="a.item.stu">我是學生</span>
                    <span v-if="!a.item.single">我不是單身</span>
                    <span v-if="!a.item.stu">我不是學生</span>
                </template>
        </list-tpl>

*下面看一下本例子的實際效果:

技術分享圖片

*本例的全部代碼如下,可自行運行查看效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <slot-test>
            <template slot="top">定制top</template>
        </slot-test>
        <list-tpl :list="list">
            <!-- 調用的時候 a 為臨時變量,只用於獲取變量 -->
                <template slot-scope="a">
                    <!-- 若不加任何判斷,整個template中的標簽都會替換為定義時的slot -->
                    <h4>{{a.item.name}}</h4>
                    <h5>{{a.item.age}}</h5>
                    <!-- 技巧就在於通過a拿到的數據選擇性地渲染標簽,即修改單個slot對應的作用域範圍 -->
                    <span v-if="a.item.single">我是單身</span>
                    <span v-if="a.item.stu">我是學生</span>
                    <span v-if="!a.item.single">我不是單身</span>
                    <span v-if="!a.item.stu">我不是學生</span>
                </template>
        </list-tpl>
    </div>
   <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
   <script>
       Vue.component("slot-test", {
           template: "<div>                <slot name=‘top‘>                    <p>默認top</p>                </slot>                <slot name=‘mid‘>                    <p>默認mid</p>                </slot>                <slot name=‘bottom‘>                    <p>默認bototm</p>                </slot>            </div>"

       })
       Vue.component("list-tpl", {
           props: ["list"],
           template: `
                <ul>
                    <li style="display:block;" v-for="(item, index) in list">
                        <slot :item="item"></slot>   // item為向上層傳遞的數據,單個slot在調用時轉化為作用域內的多個標簽
                    </li>
                </ul>
           `
       })
       var app = new Vue({
           el: "#app",
           data: {
               list: [
                   {
                       name: "tate",
                       age: 26,
                       single: true,
                       stu: false
                   },
                   {
                       name: "kevin",
                       age: 23,
                       single: true,
                       stu: true
                   },
                   {
                       name: "harden",
                       age: 28,
                       single: false,
                       stu: false
                   },
                   {
                       name: "Jimmy",
                       age: 29,
                       single: false,
                       stu: true
                   }
               ]
           }
       })
   </script>
</body>
</html>

細說Vue作用域插槽,匹配應用場景。