2.1 Vue.js 关于插槽slot

  我其实也没什么要说的,主要都在代码和相应的注释里面了,这个东西不好说,我感觉只能意会不能言传

匿名插槽 & 具名插槽

  还是放到 VScode 或者 Hbuilder 里面看代码....

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4   <title> </title>
 5 </head>
 6 <body>
 7 <div id="app">
 8   <slot-test>
 9     <p>使用插槽分发内容</p>
10     <h1 slot="header">插槽测试!</h1>
11     <p>在组件中,没有指定插槽名称的元素将被置于默认插槽中</p>
12     <p slot="none">指定到不存在的插槽中的内容将不会被显示</p>
13   </slot-test>
14 </div>
15 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
16 <script type="text/javascript">
17   let SlotTest = {
18     template: '<div>' +
19     '<slot name="header">相当于占位元素,因此这些文字也不会被渲染</slot>' + // 具名插槽
20     '<slot></slot>' + // 默认插槽
21     '</div>'
22   }
23   let vm = new Vue({ // Vue实例
24     el: '#app',
25     components: { SlotTest }
26   })
27 </script>
28 </body>
29 </html>
View Code

  看完并用F12魔法进行操作之后,你会发现,

    1. 一般只要没有被注明 slot = " xxx "  属性的标签 就会被自动纳入到匿名插槽里面

    2. 具名插槽就是 ” 调用 "  有 slot 名字的 标签

作用域插槽

  slot-scope vue 2.5 之前叫 scope ,我先说说我认为的作用域插槽 

    作用域插槽就是为了让父组件能够运用到子组件的数据

  这句话其实也是道不清说不白,我还是建议有缘人拿我的代码来实地操作一下

  主要就是一个这个结构,可能有些点说法张冠李戴,但是大致该怎么用是了解的了,希望有缘人指正批评

  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>组件</title>
 7     <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
 8 </head>
 9 
10 <body>
11     <div id="app">
12         <!-- 这个是测试组件调用的情况 -->
13         <component :is="view">
14         </component>
15         <span style="color: grey;font-size: smaller;"><i>/////// 分割线 //////</i></span>
16         <br>
17         <!-- 测试插槽 -->
18         <view_2 :text="text">
19             <!-- 大的其实是作用域插槽 -->
20             <template slot-scope="{shit}">
21                 <!-- 记住了,一定是对象储存 不能是 slo-scope = "shit" 不然输出是{ "shit" : xxx } -->
22                 <h2 style="color:rgb(219, 144, 144)">{{shit}}</h2> <!-- 这个是作用域插槽里面的匿名插槽(因为没有名字) -->
23                 <h2 slot="namedSlot" style="color:rgb(174, 184, 228)">这是具名插槽 &nbsp; shit:{{shit}}</h2> <!-- 具名插槽 -->
24             </template>
25         </view_2>
26         <!-- 测试组件切换 -->
27         <button @click="toggle('view_1')">点击变成view_1</button>
28         <button @click="toggle('view_2')">点击变成view_2</button>
29     </div>
30 </body>
31 
32 <script>
33     let view_1 = {
34         template: "<h1> view_1 </h1>"
35     }
36     let view_2 = {
37         props: {
38             text: {
39                 type: Number,
40                 default() {
41                     return
42                 }
43             }
44         },
45         template: function () {             // 为什么写函数呢,可能会有人会问,因为这个东西会让风格统一,而且是个立即执行函数,不然页面没输出
46             return '<div> \n ' +            // 这里一个要写一个大的盒子框起来,不然这个东西只会认一个标签
47                 '       <h1> this is a test for slot-scope </h1> \n' +
48                         // 匿名插槽 
49                 '       <slot :shit="text+111"></slot>\n' +
50                         // 具名插槽 
51                 '       <slot name="namedSlot" :shit="text"></slot>\n' +
52                 '   </div>'
53         }()
54 
55         //  其实你这样写也没差的
56         // template: 
57         //         '   <div> \n '+            // 这里一个要写一个大的盒子框起来,不然这个东西只会认一个标签
58         //         '       <h1> this is a test for slot-scope </h1> \n' +
59         //         '       <slot :shit="text+111"></slot>\n'+
60         //         '       <slot name="namedSlot" :shit="text"></slot>\n'+
61         //         '   </div>'
62 
63     }
64     var vm = new Vue({
65         el: '#app',
66         components: {
67             view_1,
68             view_2
69         },
70         data() {
71             return {
72                 text: 123,
73                 view: view_2
74             }
75         },
76         methods: {
77             toggle(view) {
78                 this.view = view
79             }
80         }
81     });
82 </script>
83 
84 </html>
View Code

   在看完之后,你会发现,shit 是一个 插槽里面定义的 一个由 上级组件 传的text 定义的 然后 shit又被回传给了上级组件

  slotscope = "{shit}",确实感觉有点像套娃 捞数据的

  但是 大致的简单例子就是这样,复杂的可以用来做表格,比如我从书里看到的这个,有缘人可以尝试看一下,收获良多

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4   <title></title>
  5 </head>
  6 <body>
  7 <style>
  8   .btn {
  9     outline: none;
 10     border: none;
 11     cursor: pointer;
 12     padding: 5px 12px;
 13   }
 14   .btn-text {
 15     color: #409eff;
 16     background-color: transparent;
 17   }
 18   .btn-text:hover {
 19     color: #66b1ff;
 20   }
 21   .fly-table {
 22     width: 400px;
 23     text-align: left;
 24     line-height: 42px;
 25     border: 1px solid #eee;
 26     user-select: none;
 27   }
 28 </style>
 29 <div id="app">
 30   <h2>Fly Table Component</h2>
 31   <button
 32     class="btn btn-text"
 33     title="点击使数组倒序"
 34     @click="handleReverse">
 35     倒序
 36   </button>
 37   <fly-table
 38     :fields="fields"
 39     :goods="goods">
 40     <!-- 组件标签包裹着的内容将被分发 -->
 41     <!-- 思考下,是否可以在fly-table组件中直接书写这段代码? -->
 42     <template slot-scope="{ row, col }">
 43       <span
 44         v-if="col.prop !== 'operate'">
 45           {{ row[col.prop] }}
 46         </span>
 47       <button
 48         class="btn btn-text"
 49         v-else
 50         @click="handleMarked(row)">
 51         {{row.isMarked?"取消标记":'标记'}}
 52       </button>
 53     </template>
 54 
 55   </fly-table>
 56 </div>
 57 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
 58 <script type="text/javascript">
 59   let FlyTable = {
 60     props: { // 组件接收从父组件传入的数据
 61       fields: {
 62         type: Array,
 63         default () {
 64           return []
 65         }
 66       },
 67       goods: {
 68         type: Array,
 69         default () {
 70           return []
 71         }
 72       }
 73     },
 74     template: function () {
 75       return '<table class="fly-table">\n' +
 76         '    <tr>\n' +
 77         '      <th\n' +
 78         '        v-for="(col, cIndex) in fields"\n' +
 79         '        :key="cIndex">\n' +
 80         '        {{ col.label }}\n' +
 81         '      </th>\n' +
 82         '    </tr>\n' +
 83         '    <tr\n' +
 84         '      v-for="(row, rIndex) in goods"\n' +
 85         '      :key="rIndex"\n' +
 86         '      :style="{color: row.isMarked ? \'#ea4335\' : \'\'}">\n' +
 87         '      <td\n' +
 88         '        style="border-top: 1px solid #eee"\n' +
 89         '        v-for="(col, cIndex) in fields"\n' +
 90         '        :key="cIndex">\n' +
 91         // slot应写在子组件中,用于接收父组件分发的内容
 92         '        <slot :row="row" :col="col"></slot>\n' +
 93         '      </td>\n' +
 94         '    </tr>\n' +
 95         '  </table>'
 96     }() // 其实这个template 就是一个字符串 但是作者写了函数来看 风格统一 但是必须是立即执行函数 不然没有这个字符串
 97   }
 98   // 声明 Vue 实例
 99   let vm = new Vue({
100     el: '#app',
101     components: { FlyTable },
102     data () {
103       return {
104         fields: [
105           {
106             label: '名称',
107             prop: 'name'
108           },
109           {
110             label: '数量',
111             prop: 'quantity'
112           },
113           {
114             label: '价格',
115             prop: 'price'
116           },
117           {
118             label: '',
119             prop: 'operate'
120           }
121         ],
122         goods: [
123           {
124             name: '苹果',
125             quantity: 200,
126             price: 6.8,
127             isMarked: false
128           },
129           {
130             name: '西瓜',
131             quantity: 50,
132             price: 4.8,
133             isMarked: false
134           },
135           {
136             name: '榴莲',
137             quantity: 0,
138             price: 22.8,
139             isMarked: false
140           }
141         ]
142       }
143     },
144     methods: {
145       handleReverse () {
146         this.goods.reverse()
147       },
148       handleMarked (row) {
149         row.isMarked = !row.isMarked
150       }
151     }
152   })
153 </script>
154 </body>
155 </html>
View Code

 

总结

  前几天只是看到了有slot这个东西,也不是很理解,今天看弄懂了一点,然后自己试着敲了一下代码才知道有些地方不对

  好了 该吃饭了

  请有缘人发现错误 给我说一哈

  

posted @ 2021-02-01 17:57  WaterMealone  阅读(116)  评论(0编辑  收藏  举报