vue中使用jsx开发组件
coderzhouyu2023-11-10 10:50:37
使用 jsx 开发组件
import { defineComponent } from "vue";
// 定义子组件
const ChildComponent = defineComponent({
name: "ChildComponent",
setup() {
return () => <div>ChildComponent</div>;
},
});
// 也可以使用 render 函数
const ChildComponent = defineComponent({
name: "ChildComponent",
render() {
return <div>ChildComponent</div>;
},
});
// 定义非受控组件(就是组件内部没有状态)
const UncontrolledComponent = defineComponent({
name: "UncontrolledComponent",
setup() {
return () => <input type="text" />;
},
});
// 定义组件函数并用闭包保存调用时的参数 这种方式可以用于创建组件库
function createComponent(name, props) {
return defineComponent({
name,
setup() {
{
props.name;
}
return () => <div>{name}</div>;
},
});
}
export default defineComponent({
name: "App",
// 定义 props
props: {
msg: String,
},
// 定义事件
emits: ["update:msg"],
setup(props, { slots, attrs, emit, expose }) {
// 对外暴露的方法
expose({
// ...
});
// 使用 createComponent
const ChildComponent = createComponent("ChildComponent", {
name: "ChildComponent",
});
// 返回 jsx
return () => (
<div>
<ChildComponent />
{h(ChildComponent)}
<h1>{props.msg}</h1>
<button onClick={() => emit("update:msg", "Hello Vite + Vue + JSX")}>
Change msg
</button>
{slots.default?.()}
</div>
);
},
});
v-slot 在 jsx 中的使用
export default defineComponent({
name: "App",
setup(props, { slots }) {
// 此处的 slots 是一个对象 可以通过解构获取到具名插槽
const { default: defaultSlot } = slots;
// 下面的方式可以将插槽传递给子组件
return () => (
<div>
<h1>{props.msg}</h1>
<button onClick={() => emit("update:msg", "Hello Vite + Vue + JSX")}>
Change msg
</button>
{slots.default?.()}
<ChildComponent v-slots={slots} />
</div>
);
},
});
inject 和 provide 在 jsx 中的使用
import { ref, provide } from 'vue'
const Child = ()=>{
return <GrandChild />
}
const GrandChild = defineComponent({
name: "App",
setup(props, { slots }) {
// 这里注入之后就完全是一个响应数据了,在孙组件修改这个状态其他组件中也会发生变化。也就是说这种行为同样破坏了单向数据流
const message = inject('message')
const add = ()=>{
message.value = message.value + "12"
}
return () => (
<>
<p>
Message to grand child: {{ message }}
<button @click="add" >+</button>
</p>
</>
);
},
})
export default defineComponent({
name: "App",
setup(props, { slots }) {
const message = ref('hello')
provide('message', message)
return () => (
<>
<input v-model="message">
<Child />
</>
);
},
})
参考资料: 依赖注入 | Vue.js (vuejs.org)
component 在 jsx 中的使用
component 在 jsx 中可以使用 resolveComponent 函数来获取组件
import { defineComponent, resolveComponent } from "vue";
export default defineComponent({
name: "App",
setup() {
const ChildComponent = resolveComponent("ChildComponent");
return () => (
<div>
<ChildComponent />
</div>
);
},
});
参考资料: https://juejin.cn/post/7291463601704255545
inheritAttrs
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
// 加入 inheritAttrs: false 后 attrs 就不会被渲染到组件的根元素上
inheritAttrs: false,
setup(props, { attrs }) {
return () => (
<div>
<h1>{props.msg}</h1>
<button onClick={() => emit("update:msg", "Hello Vite + Vue + JSX")}>
Change msg
</button>
{slots.default?.()}
</div>
);
},
});
参考资料: https://cn.vuejs.org/api/options-misc.html#inheritattrs
参考资料
https://cn.vuejs.org/guide/extras/render-function.html https://juejin.cn/post/6844903710229790734