Appearance
Vue 命令式组件实践
以往封装的命令式组件往往都是通过 h 和 render,临时渲染的组件,并且文件拆分成了几个(函数文件、组件文件、样式文件),非常零散。
这一次可以通过 jsx+css-in-js(@styils/vue)实现一个文件即可完成命令式组件的封装 @styils/vue: https://styils.github.io/styils/
tsx
import { Component, createApp } from "vue";
import "./index.css"; //这个只是真实DOM的样式,其实也可以不使用,将其封装成组件也可以。
// css-in-js的vue插件
import { styled } from "@styils/vue";
// 配置了样式的组件元素
// styled会创建一个组件,在传入参数时可以选择组件的tagName和对应样式,并且最终渲染时会通过class选择器给元素配置样式的。
// 消息容器
const BoxContainer = styled("div", {
backgroundColor: "#fff",
borderRadius: "5px",
height: "150px",
width: "80%",
maxWidth: "500px",
padding: "10px",
boxSizing: "border-box",
});
// 按钮
const ConfirmButton = styled("button", {
border: "none",
padding: "5px 10px",
backgroundColor: "skyblue",
color: "#fff",
cursor: "pointer",
});
// 组件配置项
const MessageBox: Component = {
// 自定义熟悉
props: {
title: {
type: String,
required: true,
},
},
// 定义的方法
methods: {
onHandleClick() {
this.$emit("toClose");
},
},
// 自定义事件
emits: ["toClose"],
// 组件的render函数
render(ctx: any) {
return (
<BoxContainer>
<div class="content">{ctx.title}</div>
<ConfirmButton onClick={ctx.onHandleClick}>确认</ConfirmButton>
</BoxContainer>
);
},
};
// 创建消息盒子的函数
export default function (title: string) {
const container = document.createElement("div");
container.classList.add("message_box_mask_container");
const app = createApp(MessageBox, {
title,
onToClose: () => {
app.unmount();
container.remove();
},
});
app.mount(container);
document.body.appendChild(container);
}
import { Component, createApp } from "vue";
import "./index.css"; //这个只是真实DOM的样式,其实也可以不使用,将其封装成组件也可以。
// css-in-js的vue插件
import { styled } from "@styils/vue";
// 配置了样式的组件元素
// styled会创建一个组件,在传入参数时可以选择组件的tagName和对应样式,并且最终渲染时会通过class选择器给元素配置样式的。
// 消息容器
const BoxContainer = styled("div", {
backgroundColor: "#fff",
borderRadius: "5px",
height: "150px",
width: "80%",
maxWidth: "500px",
padding: "10px",
boxSizing: "border-box",
});
// 按钮
const ConfirmButton = styled("button", {
border: "none",
padding: "5px 10px",
backgroundColor: "skyblue",
color: "#fff",
cursor: "pointer",
});
// 组件配置项
const MessageBox: Component = {
// 自定义熟悉
props: {
title: {
type: String,
required: true,
},
},
// 定义的方法
methods: {
onHandleClick() {
this.$emit("toClose");
},
},
// 自定义事件
emits: ["toClose"],
// 组件的render函数
render(ctx: any) {
return (
<BoxContainer>
<div class="content">{ctx.title}</div>
<ConfirmButton onClick={ctx.onHandleClick}>确认</ConfirmButton>
</BoxContainer>
);
},
};
// 创建消息盒子的函数
export default function (title: string) {
const container = document.createElement("div");
container.classList.add("message_box_mask_container");
const app = createApp(MessageBox, {
title,
onToClose: () => {
app.unmount();
container.remove();
},
});
app.mount(container);
document.body.appendChild(container);
}