web架构师编辑器内容-改进字体下拉菜单

前面说到我们可以通过面板配置来更新画布上面的一些属性,如果我们有这样一个需求:在右侧面板配置里面需要查看字体的样式效果我们应该怎么做呢?

我们一开始字体的渲染:

js 复制代码
const fontFamilyArr = [
  {
    value: '"SimSun","STSong',
    text: '宋体'
  },
  {
    value: '"SimHei","STHeiti',
    text: '黑体'
  },
  {
    value: '"KaiTi","STKaiti',
    text: '楷体'
  },
  {
    value: '"FangSong","STFangsong',
    text: '仿宋'
  }
]
fontFamily: {
  component: 'a-select',
  subComponent: 'a-select-option',
  text: '字体',
  options: [
    {
      value: '',
      text: '无'
    },
    ...fontFamilyArr
  ],
  afterTransform: (e: any) => e
},

后面改成:

js 复制代码
const fontFamilyOptions = fontFamilyArr.map((font) => {
  return {
    value: font.value,
    // 第一种写法生成vnode
    text: h('span', { style: { fontFamily: font.value } }, font.text)
    // 使用:tsx写法,需要把文件后缀名改成tsx
    text: <span style={{ fontFamily: font.value}}>{font.text }</span> as VNode
  }
})
options: [
  {
    value: '',
    text: '无'
  },
  ...fontFamilyOptions
],

渲染的时候有两种方案:方案一使用tsx进行渲染,方案二:借助render函数桥梁,将vnode转换成真实dom

方案一:使用jsx重写组件sfc写法 Single File Component写法,jsx文件天生就是转换vnode

jsx动态组件名称

在jsx中对于动态组件名称,我们必须要拿到其实例,然后把一个变量赋值给组件实例

jsx 复制代码
import { Button } from 'button'

const Name = Button
<Name />
展开属性
jsx 复制代码
<Component {...props} />
事件写法
jsx 复制代码
v-on:click => onClick

第一种使用tsx渲染:将PropTable.vue文件改成PropTable.tsx文件,返回的是dom,

js 复制代码
import { Input, InputNumber, Slider, Radio, Select} from 'ant-design-vue'
// jsx对于动态组件,我们必须要拿到其实例,再把一个变量赋值给组件实例,所以我们要解构出组件实例。
const mapToComponent = {
  'a-input': Input,
  'a-textarea': Input.TextArea,
  'a-input-number': InputNumber,
  'a-slider': Slider,
  'a-radio-group': Radio,
  'a-radio-button': Radio.Button,
  'a-select': Select,
  'a-select-option': Select.Option
} as any
return () => (<div class="props-table">
    {
      Object.keys(finalProps.value).map(key => {
        const value = finalProps.value[key]
        const ComponentName = mapToComponent[value.component]
        const SubComponent = value.subComponent ? mapToComponent[value.subComponent] : null
        const props = { 
          [value.valueProp]: value.value,
          ...value.extraProps,
          ...value.events
        }
        return (
          <div key={key} class="prop-item">
            { value.text && <span class="label">{value.text}</span>}
            <div class="prop-component">
              {/* 渲染动态组件名 */}
              <ComponentName {...props}>
                {value.options && value.options.map(option => {
                  return (
                    <SubComponent value={option.value}>{option.text}</SubComponent>
                  )
                })}
              </ComponentName>
            </div>
          </div>
        )
      })
    }
</div>)

finalProps:

方案二:使用render函数实现桥梁

ts 复制代码
// RenderVnode.ts
import { defineComponent } from 'vue'

const RenderVnode = defineComponent({
  props: {
    vNode: {
      type: [Object, String],
      required: true
    }
  },
  render() {
    return this.vNode;
  }
})

export default RenderVnode

在propsTable中使用

js 复制代码
<template v-if="value.options">
  <component
    :is="value.subComponent"
    v-for="(option, k) in value.options"
    :key="key"
    :value="value.value"
  >
    <!-- {{ option.text }} -->
    <render-vnode :vNode="option.text"></render-vnode>
  </component>
</template>
相关推荐
福兮说7 分钟前
纯前端把图片压缩到指定体积:canvas.toBlob 配合二分查找
前端·javascript·canvas·图片处理
是立不是利12 分钟前
CSS 入门与进阶:从选择器到响应式布局的完整指南
前端·css
镭立智能制造18 分钟前
电线电缆换线频繁?MES系统如何缩短换线时间40%
前端·制造
志尊宝20 分钟前
Vue3 零基础每日笔记(018):按键与鼠标修饰符——回车搜索、Ctrl+S 保存这样写
javascript·vue.js·笔记
Amos_Web1 小时前
Rspack 源码解析(五):CodeGenerationPass 与模块代码生成
前端·前端框架·源码阅读
八荒启·交互动画1 小时前
Web特效06——WebGL深挖:顶点着色器和片元着色器到底在干什么
前端·网页特效·八荒启-交互动画·八荒启
这锅我不背哈1 小时前
前端权限控制实践:基于 RBAC 的完整落地方案
前端
星空1 小时前
Map<String, String>`Map`是接口,不能直接 new
java·前端·算法
开开心心就好2 小时前
低年级识字练笔顺工具,电脑和安卓端都能用
前端·javascript·网络·安全·scala·erlang·语音识别
杨利杰YJlio2 小时前
ITSK PE 26U5 测试版解读:组件完善、VMD 修复与服务器支持边界
前端·javascript·后端