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')
    ]);
  }
};
相关推荐
鹧鸪yy7 分钟前
认识Node.js及其与 Nginx 前端项目区别
前端·nginx·node.js
跟橙姐学代码7 分钟前
学Python必须迈过的一道坎:类和对象到底是什么鬼?
前端·python
汪子熙9 分钟前
浏览器里出现 .angular/cache/19.2.6/abap_test/vite/deps 路径究竟说明了什么
前端·javascript·面试
Benzenene!11 分钟前
让Chrome信任自签名证书
前端·chrome
yangholmes888811 分钟前
如何在 web 应用中使用 GDAL (二)
前端·webassembly
jacy13 分钟前
图片大图预览就该这样做
前端
林太白15 分钟前
Nuxt3 功能篇
前端·javascript·后端
YuJie16 分钟前
webSocket Manager
前端·javascript
Mapmost32 分钟前
Mapmost SDK for UE5 内核升级,三维场景渲染效果飙升!
前端
Mapmost34 分钟前
重磅升级丨Mapmost全面兼容3DTiles 1.1,3DGS量测精度跃升至亚米级!
前端·vue.js·three.js