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