vue3 TS 动态改变class的宽度?
GbSplitPanel组件
import { defineComponent, ref, unref, computed, PropType, watch } from "vue";import resizer from "./resizer";
import "./style/index.scss";
export interface ContextProps {
minPercent: number;
defaultPercent: number;
split: string;
}
export default defineComponent({
name: "splitPane",
components: { resizer },
props: {
splitSet: {
type: Object as PropType<ContextProps>,
require: true
}
},
emits: ["resize"],
setup(props, ctx) {
const active = ref(false);
const hasMoved = ref(false);
const percent = ref(props.splitSet?.defaultPercent);
const type = props.splitSet?.split === "vertical" ? "width" : "height";
const resizeType = props.splitSet?.split === "vertical" ? "left" : "top";
const leftClass = ref([
"splitter-pane splitter-paneL",
props.splitSet?.split
]);
const rightClass = ref([
"splitter-pane splitter-paneR",
props.splitSet?.split
]);
const userSelect = computed(() => {
return active.value ? "none" : "";
});
const cursor = computed(() => {
return active.value
? props.splitSet?.split === "vertical"
? "col-resize"
: "row-resize"
: "";
});
const onClick = (): void => {
if (!hasMoved.value) {
percent.value = 50;
ctx.emit("resize", percent.value);
}
};
const onMouseDown = (): void => {
active.value = true;
hasMoved.value = false;
};
const onMouseUp = (): void => {
active.value = false;
};
const onMouseMove = (e: any): void => {
if (e.buttons === 0 || e.which === 0) {
active.value = false;
}
if (active.value) {
let offset = 0;
let target = e.currentTarget;
if (props.splitSet?.split === "vertical") {
while (target) {
offset += target.offsetLeft;
target = target.offsetParent;
}
} else {
while (target) {
offset += target.offsetTop;
target = target.offsetParent;
}
}
const currentPage =
props.splitSet?.split === "vertical" ? e.pageX : e.pageY;
const targetOffset =
props.splitSet?.split === "vertical"
? e.currentTarget.offsetWidth
: e.currentTarget.offsetHeight;
const percents =
Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;
if (
percents > props.splitSet?.minPercent &&
percents < 100 - props.splitSet?.minPercent
) {
percent.value = percents;
}
ctx.emit("resize", percent.value);
hasMoved.value = true;
}
};
watch(props.splitSet, newVal => {
console.log("监听啊", newVal);
});
return () => (
<>
<div
class="vue-splitter-container clearfix"
style={(unref(cursor), unref(userSelect))}
onMouseup={() => onMouseUp()}
onMousemove={() => onMouseMove(event)}
>
<div
class={unref(leftClass)}
style={{ [unref(type)]: unref(percent) + "%" }}
>
{ctx.slots.paneL()}
</div>
<resizer
style={`${unref([resizeType])}:${unref(percent)}%`}
split={props.splitSet?.split}
onMousedown={() => onMouseDown()}
onClick={() => onClick()}
></resizer>
<div
class={unref(rightClass)}
style={{ [unref(type)]: 100 - unref(percent) + "%" }}
>
{ctx.slots.paneR()}
</div>
<div v-show={unref(active)} class="vue-splitter-container-mask"></div>
</div>
</>
);
}
});
引入GbSplitPanel组件
<splitpane :splitSet="settingLR"> <template #paneL>text</template>
<template #paneR>text1</template>
</splitpane>
const settingLR: ContextProps = reactive({
minPercent: 50,
defaultPercent: 50,
split: "vertical"
});
需要点击红色圈让这个列表的宽度改为100%; 默认为50%,点击可以展开,宽度到100。
我在点击事件上设置
minPercent: 100,defaultPercent: 100
打印出来如:
const settingLR: ContextProps = reactive({ minPercent: 100,
defaultPercent: 100,
split: "vertical"
});
但是视图宽度没有什么改变。宽度还是没有改变,望各位大佬帮忙看看?
GbSplitPanel组件里面的 props.splitSet 监听没有打印出来。
回答:
已解决这个问题
回答:
你在使用组件的时候没有传入 emit
方法吧,所以 settingLR
好像没有改变?这样不触发 watch
也是正常的。
以上是 vue3 TS 动态改变class的宽度? 的全部内容, 来源链接: utcz.com/p/933070.html