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')
    ]);
  }
};
相关推荐
爱泡脚的鸡腿1 分钟前
HTML CSS 第二次笔记
前端·css
灯火不休ᝰ16 分钟前
前端处理pdf文件流,展示pdf
前端·pdf
智践行18 分钟前
Trae开发实战之转盘小程序
前端·trae
最新资讯动态24 分钟前
DialogHub上线OpenHarmony开源社区,高效开发鸿蒙应用弹窗
前端
lvbb6634 分钟前
框架修改思路
前端·javascript·vue.js
qq_4560016535 分钟前
43、接口请求需要时间,导致页面初始加载时会出现空白,影响用户体验
javascript·vue.js·ux
工业互联网专业36 分钟前
基于springboot+vue的动漫交流与推荐平台
java·vue.js·spring boot·毕业设计·源码·课程设计·动漫交流与推荐平台
树上有只程序猿36 分钟前
Java程序员需要掌握的技术
前端
从零开始学安卓39 分钟前
Kotlin(三) 协程
前端