Appearance
静态文本组件
在构建页面中,通常需要一个文本组件来展示静态的文本信息,本例SVGWenBen组件便是一个静态的文本组件,从名称就可以看出它是一个以SVG来构建的文本展示组件。
代码如下
vue
<template>
<div class="svg-container"
:style="customStyle"
@click="handleClick" @dblclick="handleDblClick" @contextmenu="openContextMenu">
<svg xmlns="http://www.w3.org/2000/svg" :width="element.style.width" :height="element.style.height">
<rect v-if="propValue.hasBackground" :x="1" :y="1" :width="element.style.width-2" :height="element.style.height-2"
:rx="propValue.rx" :ry="propValue.ry"
:fill="propValue.fillColor?propValue.fillColor:'none'" :stroke="propValue.strokeColor"
:fill-opacity="propValue.fillOpacity" :stroke-opacity="propValue.strokeOpacity"
:stroke-width="propValue.strokeWidth"></rect>
<text :x="textX" :y="textY" :dx="propValue.dx"
:fill="propValue.fontColor?propValue.fontColor:'none'"
:dominant-baseline="textBaseLine"
:text-anchor="textAnchor"
:font-family="propValue.fontFamily"
:font-size="propValue.fontSize"
:font-weight="propValue.fontWeight"
>{{ propValue.text }}
</text>
</svg>
</div>
</template>
<script setup>
import {useEventHandler, useDataCacheStore, createSmartAccessor, CreateCompContext, CommonUtils} from "hflvloader";
import {
watch,
onMounted,
computed,
ref,
onBeforeMount,
onBeforeUnmount,
onUnmounted,
onActivated,
onDeactivated
} from "vue";
import {useRoute, useRouter} from "vue-router";
import ContextMenu from '@imengyu/vue3-context-menu'
import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'
import {useMenuHandler} from "@/common/useMenuHandler.js";
import {getCursorByEvents} from "@/common/useCursorManager.js";
defineOptions({
name: 'SVGWenBen'
});
const props = defineProps({
propValue: {
type: Object,
required: true,
default: () => {
}
},
element: {
type: Object,
default: () => {
}
},
designStatus: {
type: Boolean,
default: false
}
})
const eventHandler = ref(null);
const propValue = computed(() => {
return props.propValue || {};
})
const element = computed(() => {
return props.element || {};
})
const events = computed(() => {
return element.value.events || [];
})
const textX = ref(0);
const textY = ref(0);
const textBaseLine = ref('');
const textAnchor = ref('');
const handleClick = (event) => {
eventHandler.value?.handleClick(event);
}
const handleDblClick = (event)=>{
eventHandler.value?.handleDblClick(event);
}
watch(() => element.value.style.width, (value) => {
draw();
})
watch(() => element.value.style.height, (value) => {
draw();
})
watch(() => propValue.value.horizontalAlign, (value) => {
draw();
})
watch(() => propValue.value.offsetX, (value) => {
draw();
})
const draw = () => {
const {width, height} = props.element.style
drawChart(width, height)
}
const drawChart = (width, height) => {
let horizontalAlign = props.propValue.horizontalAlign || 'left';
let offsetX = props.propValue.offsetX || 0;
if ('center' == horizontalAlign) {
textAnchor.value = 'middle'
textX.value = width * 0.5
} else if ('right' == horizontalAlign) {
textX.value = width - offsetX
textAnchor.value = 'end'
} else {
textX.value = 0 + offsetX
textAnchor.value = 'start'
}
textBaseLine.value = 'central';
textY.value = height * 0.5
}
const router = useRouter();
const route = useRoute();
const compContext = CreateCompContext(propValue, element, router, route);
onBeforeMount(() => {
eventHandler.value = useEventHandler(events.value, props.designStatus, compContext);
eventHandler.value?.beforeMount();
})
onMounted(() => {
draw();
eventHandler.value?.mounted();
})
onBeforeUnmount(() => {
eventHandler.value?.beforeUnmount();
})
onUnmounted(() => {
eventHandler.value?.unmounted();
})
onActivated(() => {
eventHandler.value?.activated();
})
onDeactivated(() => {
eventHandler.value?.deactivated();
})
defineExpose({
handleClick
})
const {processMenus} = useMenuHandler();
const openContextMenu = (_event) => {
_event.preventDefault();
let _menuItems = propValue.value.menuItems || [];
if (CommonUtils.isArray(_menuItems) && _menuItems.length > 0) {
let _menuList = [];
_menuList = processMenus(_menuItems, function (item, event) {
eventHandler.value?.handleContextMenu(_event, item.value);
})
ContextMenu.showContextMenu({
x: _event.x,
y: _event.y,
items: _menuList
})
}
}
const customStyle = computed(() => {
let style = {}
style['cursor'] = getCursorByEvents(events.value);
return style;
})
</script>
<style lang="scss" scoped>
.svg-container {
width: 100%;
height: 100%;
svg {
width: 100%;
height: 100%;
}
}
</style>