一、插槽用法
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",
})
),
]
);
},
};
-
引用组件
<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 }"></template> <script> import SlotA from "./components/SlotA.js"; export default { SlotA } </script>{{ message }}
</template> </SlotA>
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')
]);
}
};