vue渲染函数用法示例

一、插槽用法

1.使用渲染函数的写法,写一个带有插槽的组件SlotA,放在components文件夹下

export default {
  props: {
    user: {
      type: Object,
      required: true,
    },
  },
  render(createElement) {
    return createElement(
      "div",
      {
        attrs: { //传递到div标签上的属性
          id: "foo",
        },
      },
      [
        createElement("header", this.$slots.header),// 具名插槽header
        createElement(
          "main",
          this.$scopedSlots.default({ //默认作用域插槽
            user: this.user, // 将 props 传递给插槽
          })
        ),
        createElement( 
          "content",
          this.$scopedSlots.content({// 作用域插槽content
            content: { des: "内容" }, // 将 props 传递给插槽
          })
        ),
        createElement(
          "footer",
          this.$scopedSlots.footer({// 作用域插槽content
            message: "Footer Message",
          })
        ),
      ]
    );
  },
};
  1. 引用组件

    <template>
    <SlotA :user="{ name: 'LUCY' }"> <template v-slot:default="{ user }"> {{ user.name }} </template> <template v-slot:header> 这是头部 </template> <template v-slot:content="{ content }"> {{ content.des }} </template> <template #footer="{ message }">

    {{ message }}

    </template> </SlotA>
    </template> <script> import SlotA from "./components/SlotA.js"; export default { SlotA } </script>

3.展示结果

二、父子组件通信

import { VBtn } from 'vuetify/lib';
// 子组件
const ChildComponent = {
  props: ["parentMessage"],
  data() {
    return {
      childMessage: "Hello from Child!",
    };
  },
  methods: {
    sendMessageToParent() {
      this.$emit("childEvent", this.childMessage);
    },
  },
  render(h) {
    return h("div", [
      h("h2", "我是子组件"),
      h("p", `来自父组件的数据: ${this.parentMessage}`),
      h(
        VBtn,
        {
          props: {
            color: 'primary',
            depressed: true
          },
          on: {
            click: this.sendMessageToParent,
          },
        },
        "发送信息到父组件"
      ),
    ]);
  },
};
// 父组件
const ParentComponent = {
  data() {
    return {
      messageFromChild: "",
      parentMessage: "来自父组件的问候!",
    };
  },
  methods: {
    handleChildEvent(message) {
      this.messageFromChild = message;
    },
  },
  render(h) {
    return h("div", [
      h("h1", "我是父组件"),
      h(ChildComponent, {
        props: {
          parentMessage: this.parentMessage,
        },
        on: {
          childEvent: this.handleChildEvent,
        },
      }),
      h("p", `来自子组件的消息: ${this.messageFromChild}`),
    ]);
  },
};
export default ParentComponent;

运行结果:

三、attrs和listeners的使用

import { VBtn } from 'vuetify/lib';
// 父组件
const ParentComponent = {
    data() {
      return {
        messageFromChild: '',
        parentMessage: 'Hello from Parent!'
      };
    },
    methods: {
      handleChildEvent(message) {
        this.messageFromChild = message;
      },
      handleCustomEvent() {
        alert('Custom event triggered from child!');
      },
      handleClick() {
        alert('父组件的点击事件');
      }
    },
    render(h) {
      return h('div', [
        h('h1', 'Parent Component'),
        h('p', `Message from Child: ${this.messageFromChild}`),
        h(ChildComponent, {
          props: {
            parentMessage: this.parentMessage
          },
          attrs: {
            customAttribute: 'This is a custom attribute'
          },
          on: {
            childEvent: this.handleChildEvent,
            customEvent: this.handleCustomEvent,
            click: this.handleClick
          }
        })
      ]);
    }
  };

  // 子组件
const ChildComponent = {
    props: ['parentMessage'],
    data() {
      return {
        childMessage: 'Hello from Child!'
      };
    },
    methods: {
      sendMessageToParent() {
        this.$emit('childEvent', this.childMessage);
      },
      triggerCustomEvent() {
        this.$emit('customEvent');
      }
    },
    render(h) {
      return h('div', [
        h('h2', 'Child Component'),
        h('p', `Message from Parent: ${this.parentMessage}`),
        h('p', `Custom Attribute: ${this.$attrs.customAttribute}`), // 使用 $attrs
        h(VBtn, {
          on: {
            click: this.sendMessageToParent
          }
        }, 'Send Message to Parent'),
        h(VBtn, {
          on: {
            click: this.triggerCustomEvent
          }
        }, 'Trigger Custom Event'),
        h(VBtn, {
          on: {
            click: this.$listeners.click
          }
        }, '父组件的点击事件'),
        // 将 $attrs 和 $listeners 传递给更深层次的组件
        h(GrandChildComponent, {
          attrs: this.$attrs,
          on: this.$listeners
        })
      ]);
    }
  };
  
  // 更深层次的子组件
  const GrandChildComponent = {
    render(h) {
      return h('div', [
        h('h3', 'GrandChild Component'),
        h('p', `Custom Attribute from Parent: ${this.$attrs.customAttribute}`), // 使用 $attrs
        h(VBtn, {
          on: {
            click: () => this.$emit('customEvent') // 使用 $listeners
          }
        }, 'Trigger Custom Event from GrandChild')
      ]);
    }
  };
  export default ParentComponent;

四、指令的用法

1.定义一个指令,该指令的含义是,在一个按钮上应用v-ajax指令,当点击该按钮时,会发送一个ajax请求。该指令接收两个参数,url和name,同时还具有arg及modifiers两个属性的使用示例。如果使用模板语法来示意,如下:

<button v-ajax:GET.log.alert="{name:'访问',url:'http://xxxx.com/api'}">点击发送</button>

Vue.directive('ajax', {
  bind(el, binding) {
    const { url, name } = binding.value; // 解构出 url 和 name
    const method = binding.arg || 'GET'; // 使用 arg 指定请求方法,默认为 GET
    const { log, alert } = binding.modifiers; // 使用 modifiers 判断是否需要日志或弹窗

    el.addEventListener('click', async () => {
      try {
        if (log) {
          console.log(`[${name}] Sending ${method} request to ${url}`);
        }

        const response = await fetch(url, {
          method: method // 使用 arg 指定的请求方法
        });

        const data = await response.json();

        if (log) {
          console.log(`[${name}] Request successful! Response:`, data);
        }

        if (alert) {
          alert(`${name}: Request successful! Response: ${JSON.stringify(data)}`);
        }
      } catch (error) {
        if (log) {
          console.error(`[${name}] Request failed! Error:`, error);
        }

        if (alert) {
          alert(`${name}: Request failed! Error: ${error.message}`);
        }
      }
    });
  },
  unbind(el) {
    // 清理事件监听器
    el.removeEventListener('click');
  }
});

2.使用指令

const App = {
  render(h) {
    return h('div', [
      h('h1', 'Custom Directive Example'),
      h('button', {
        directives: [
          {
            name: 'ajax',
            value: {
              url: 'https://jsonplaceholder.typicode.com/todos/1', // 请求的 URL
              name: 'Fetch Todo' // 请求的名称
            },
            arg: 'GET', // 指定请求方法
            modifiers: {
              log: true, // 启用日志
              alert: true // 启用弹窗
            }
          }
        ]
      }, 'Fetch Data')
    ]);
  }
};
相关推荐
anyup_前端梦工厂2 小时前
了解几个 HTML 标签属性,实现优化页面加载性能
前端·html
前端御书房2 小时前
前端PDF转图片技术调研实战指南:从踩坑到高可用方案的深度解析
前端·javascript
2301_789169542 小时前
angular中使用animation.css实现翻转展示卡片正反两面效果
前端·css·angular.js
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
程序员黄同学3 小时前
请谈谈 Vue 中的响应式原理,如何实现?
前端·javascript·vue.js
爱编程的小庄4 小时前
web网络安全:SQL 注入攻击
前端·sql·web安全
宁波阿成4 小时前
vue3里组件的v-model:value与v-model的区别
前端·javascript·vue.js
柯腾啊5 小时前
VSCode 中使用 Snippets 设置常用代码块
开发语言·前端·javascript·ide·vscode·编辑器·代码片段
Jay丶萧邦5 小时前
el-select:有关多选,options选项值不包含绑定值的回显问题
javascript·vue.js·elementui
weixin_535854225 小时前
oppo,汤臣倍健,康冠科技,高途教育25届春招内推
c语言·前端·嵌入式硬件·硬件工程·求职招聘