Skip to content

自定义组件介绍

本页介绍如何自定义组件,涵盖以下内容:组件名称、组件入参 Props 定义、组件上下文、事件处理、数据缓存、右键菜单等。后续将通过静态文本组件动态数据组件两个完整示例进行详解。自定义组件需要依赖 hflvloader 中的函数。

组件名称

Vue 3.3+ 引入了编译时宏 defineOptions,可用于定义组件名称。组件名称强烈建议使用区分前缀,以避免与其他 Vue 组件名称冲突。

javascript
defineOptions({
  name: 'SVGWenBen'
});

组件入参Props

可通过defineProps定义组件的入参

javascript
const props = defineProps({
  propValue: {
    type: Object,
    required: true,
    default: () => {
    }
  },
  element: {
    type: Object,
    default: () => {
    }
  },
  designStatus: {
    type: Boolean,
    default: false
  }
})
参数说明
propValue组件的属性
element元素,包含propValue,events,style等信息
designStatus状态,区分设计时与运行时,默认为false,编辑器中加载时会传入true

组件上下文

compContext 为组件上下文,通过 CreateCompContext 函数构建,用于在事件处理中获取组件上下文并进行操作。其构建方式如下:

javascript
import {useEventHandler,useDataCacheStore,createSmartAccessor,CreateCompContext} from "hflvloader";

const router = useRouter();
const route = useRoute();
const compContext = CreateCompContext(propValue, element, router, route);
参数说明
propValue组件的属性
element组件元素
router路由实例
route路由信息

CreateCompContext函数介绍,提供一些方法,查询修改PropValue的值以及路由的跳转

javascript
export function CreateCompContext(propValue, element, router, route) {
    const compContext = {
        setPropValue: function (key, value) {
            propValue.value[key] = value;
        },
        getPropValue: function (key) {
            return propValue.value[key];
        },
        setStyleValue: function (key, value) {
            element.value.style[key] = value;
        },
        getStyleValue: function (key) {
            return element.value.style[key];
        },
        routerPush: function (name, params) {
            if (router) {
                router.push({
                    name: name,
                    params: params
                });
            }
        },
        routerPush2: function (path, params) {
            if (router) {
                router.push({
                    path: path,
                    query: params
                });
            }
        },
        routerReplace: function (path) {
            if (router) {
                router.replace({
                    path: path
                })
            }
        }
    };
    return compContext
}

TIP

CreateCompContext仅挂载组件基本操作的方法。若组件有扩展需求,可在获取返回的 compContext 后进行扩展。

TIP

CreateCompContextuseDataCacheStorecreateSmartAccessorCreateCompContext函数由hflvloader提供,此外还提供CommonUtils工具函数集合。

事件处理

eventHandler 为事件处理器,通过 useEventHandler 函数构建,封装了对组件配置事件的处理逻辑。组件中调用触发即可。

javascript
onBeforeMount(() => {
  eventHandler.value = useEventHandler(events.value, props.designStatus, compContext);
  eventHandler.value?.beforeMount();
})
参数说明
events组件事件配置
designStatus当前设计状态
compContext组件上下文

数据缓存

HFLVLoder的设计框架中,数据存储使用Pinia,为扁平结构的key/value模式,在组件中使用useDataCacheStore获取数据缓存Store,通过createSmartAccessor获得一个响应式的引用,再根据业务配置的数据 Key 获取对应业务数据即可。

javascript
const dataCache = useDataCacheStore();
const smartData = createSmartAccessor(dataCache);

const bsData = smartData[propValue.value.dataCK];

watch(() => bsData.value, (value) => {
   ...
})

右键菜单

某些组件的应用场景中可能需要右键菜单,可自行实现,也可使用第三方插件(如 @imengyu/vue3-context-menu)。

javascript
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
    })
  }
}

基于 VitePress 构建