vue之渲染函數slot應用


關於vue渲染函數中slot的應用

基於vue3創建的示例:

1. 創建一個Child.js文件為子組件:

 1 // 子組件 Child.js
 2 import { h, reactive, toRefs } from '@vue/runtime-core';
 3 export default {
 4   props: {
 5     book: {
 6       type: String,
 7       default: 'vue',
 8     },
 9     version: {
10       type: Number,
11       default: 1,
12     },
13     user: {
14       type: String,
15       default: 'engineeer',
16     },
17   },
18   emit: ['ChildClick'],
19   setup(props, context) {
20     // 將props中的屬性轉換為響應式ref對象, 在setup中讀取時,使用prop.value取值,eg:book.value
21     const { book, version, user } = toRefs(props);
22     // 生成響應式reactive對象
23     const info = reactive({
24       user,
25     });
26     // 必須返回對象或者函數
27     return () =>
28       h(
29         'div',
30         {
31           style: { height: '500px', backgroundColor: 'yellow !important' },
32           class: {
33             foo: true,
34             bar: false,
35           },
36           onClick() {
37             // setup中的渲染函數中的emit的寫法
38             context.emit('ChildClick');
39           },
40         },
41         [
42           h('h1', 'Vue3渲染函數式組件應用'),
43           `BOOK: 《${book.value}》`,
44           // setup中this不是當前實例的引用,但slots等屬性可以通過setup的第二個參數(當前是context對象)獲取
45           context.slots.header({ version: version.value }),
46           context.slots.main({ user: info.user }),
47           context.slots.default(), // 子組件這樣寫必須要父組件有插槽內容,否則會報錯
48           context.slots.footer(),
49           context.slots.specialSlot({ a: 1, b: 2, c: 3 }),
50         ]
51       );
52   },
53 };

2. 創建一個Father.vue的文件為父組件:

  1 <script>
  2 // Father.vue ===> 可以直接在js文件中創建(Father.js)
  3 import Child from './reder-components/Child';
  4 import { h, resolveComponent } from 'vue';
  5 
  6 export default {
  7   components: {
  8     Child,
  9   },
 10   data() {
 11     return {
 12       content: '字符串node',
 13       num: 1,
 14     };
 15   },
 16   render() {
 17     // 讀取組件
 18     const Child = resolveComponent('Child');
 19     return h(
 20       // {String | Object | Function} tag
 21       // 一個 HTML 標簽名、一個組件、一個異步組件、或一個函數式組件。
 22       // 必需的。
 23       'div',
 24       // {Object} props
 25       // 與 attribute、prop 和事件相對應的對象。我們會在模板中使用。
 26       // 可選的。
 27       {
 28         style: { width: '100%', height: '1000px' },
 29         class: {
 30           foo: true,
 31           bar: false,
 32         },
 33       },
 34       // {String | Array | Object} children
 35       // 子 VNodes, 使用 `h()` 構建,或使用字符串獲取 "文本 Vnode" 或者有插槽的對象。
 36       // 可選的。
 37       [
 38         h(
 39           Child,
 40           {
 41             // props
 42             book: '前端框架之學不動了也得學系列',
 43             version: this.num,
 44             user: 'Front-end Engineeer',
 45             onChildClick: () => {
 46               this.num += 1;
 47               console.log('this.num+++++', this.num);
 48               //
 49             }
 50           },
 51           // 在render函數中使用插槽的寫法,通過在對象中使用鍵值對的方式使用
 52           {
 53             header: (props) => {
 54               // 作用域插槽在渲染函數中的應用
 55               return h('div', `VERSION:${props.version}`);
 56             },
 57             main: ({ user }) => {
 58               // 作用域插槽解構賦值方式
 59               return h('div', `USER:${user}`);
 60             },
 61             default: () => {
 62               // 一般插槽在渲染函數中的應用
 63               return h(
 64                 'div',
 65                 {
 66                   class: 'default_css',
 67                 },
 68                 '應用於Child組件的默認插槽內容'
 69               );
 70             },
 71             // 插槽函數,引用這個組件時可以使用具名插槽的方式(#footer)插入內容
 72             footer: this.$slots.footer || '具名插槽占位符', // 這里最好使用函數形式
 73             // 如果我們需要以某種方式對插槽進行操作,那么我們需要用一個新的函數來包裹它
 74             specialSlot: (props) => {
 75               // 在作用域插槽內部加入插槽函數,當前組件的父組件通過(#default="props")的方式使用子組件中的數據
 76               const children = this.$slots.default
 77                 ? this.$slots.default(props)
 78                 : [];
 79               return children.concat(h('div', 'Extra child'));
 80             },
 81           }
 82         ),
 83         // 通過h()構建的子節點
 84         h('h1', 'A headline'),
 85         // 一般的字符串子節點
 86         this.content,
 87         // 在render函數中創建插槽,在數組中用this.$slots.插槽名(具名插槽對象,可選)的方式創建
 88         this.$slots.some? this.$slots.some() : h('div', '默認this.$slots.some()字符串'),
 89       ]
 90     );
 91   },
 92 };
 93 </script>
 94 
 95 <style lang="less">
 96 .default_css {
 97   background-color: red;
 98 }
 99 .foo {
100   background-color: skyblue !important;
101 }
102 </style>

3. 對於Father.vue組件的引用:

 1 <template>
 2   <div>
 3     <Father>
 4       <template #footer>
 5         <div>插槽footer++++++</div>
 6       </template>
 7       <template #default="{ a, b, c }">
 8         插槽default+++++
 9         <div>{{ a }} + {{ b }} + {{ c }} = {{ a + b + c }}</div>
10       </template>
11       <template #some>
12         <div>插槽some++++++</div>
13       </template>
14     </Father>
15   </div>
16 </template>

參考文檔:vue之渲染函數

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM