乐趣区

关于前端:Vue3自制UI框架的技术总结

罕用控件的实现 – 数据结构设计

参照 Element UI,笔者发现为了提供组件的自定义能力,咱们须要定义一套高可用的数据结构,这样能力实现因组件需要更变而带来的维护性的劣势。不同的组件都对应不同的组件属性. 咱们须要设计一套对立的规范的配置来约定它, 这样前期扩大十分不便, 只须要往组件增加属性即可。

以 Button 为例, 我依照上面的属性表实现组件,性能间互不影响。

罕用控件的实现 –vue3 的新个性

笔者制作框架中学习意识了 Vue3 的新个性。

  • 属性和事件继承

和 Vue2 相比 Vue3 默认为子组件继承了属性和事件,你能够抉择敞开它,而且 props 所申明的属性也不再帮你继承:

// 子组件
inheritAttr=false
  • v-model

    Vue3 摒弃了 .sycn 修饰符, 如果符合要求就应用v-model,否则就手动通信吧。

    v-model:

    // 父
    <Component v-model:value="xxx"/>
    // 子
    this.emit('update:xxx',yyy)

    手动:

    // 父
    <Component :value="xxx" v-on:update:xxx="(yyy)=>xxx=yyy"  />
    // 子
    this.emit('update:xxx',yyy)
  • 新的模板语法 –class 的绑定

    绑定对象

    <div :class="{active: isActive}"></div>

    下面的语法示意 active 是否存在取决于数据属性 isActive 的虚实值。

  • Teleport

Dialog 对话框组件当被关上是应该笼罩整个页面,应用 Teleport 就能够脱离以后的层叠上下文去你想去的中央。

<Teleport to="body"><Teleport>

component 元组件和 context

制作 Tabs 和 Tab 时,构想用户能够这样应用:

<Tabs v-model:selected="selected">
      <Tab title="三国演义">“汝死后,汝妻子我养之,汝勿虑也。”</Tab>
      <Tab title="西游记">“大师兄,徒弟被妖精抓走了。”</Tab>
      <Tab title="水浒传">“大郎,该吃药了。”</Tab>
      <Tab title="红楼梦">“这个妹妹我曾见过的。”</Tab>
</Tabs>

第一步:须要查看 Tabs 子组件的类型, 如果不是 tab 间接报错

setup(props,context){const defaults = context.slots.default()
        defaults.forEach((tag) => {if (tag.type !== Tab) {throw new Error('Tabs 子标签必须是 Tab')
    }
}

第二步:导航条遍历所有 Tab 的 title

const titles = defaults.map((tab) => {return tab.props.title})

第三步:展现选中的 Tab 组件

<component class="friday-tabs-content-item" :is="current" :key="selected"/>
const current =computed(()=>{return defaults.find(tab=>tab.props.title===props.selected)
})

能够发现深刻意识 context 和 component 元组件能够灵便的实现性能。

好用的 API–Element.getBoundingClientRect()

Element.getBoundingClientRect()返回一个 DOMRect 对象,是蕴含整个元素的最小矩形(包含 padding 和 border-width)。该对象应用 left、top、right、bottom、x、y、width 和 height 这几个以像素为单位的只读属性形容整个矩形的地位和大小。

其余插件 – 引入 marked 和 prismjs

  • marked 转换.md 的文件
  1. 引入
$ npm add marked
  1. 配置 vite.config.ts,倡议独自放到一个 md.ts 文件中调用
// vite.config.ts
// @ts-nocheck
import path from 'path'
import fs from 'fs'
import marked from 'marked'

const mdToJs = str => {const content = JSON.stringify(marked(str))
  return `export default ${content}`
}

export default {
  plugins: [
      {
        configureServer: [ // 用于开发
          async ({app}) => {app.use(async (ctx, next) => { // koa
              if (ctx.path.endsWith('.md')) {
                ctx.type = 'js'
                const filePath = path.join(process.cwd(), ctx.path)
                ctx.body = mdToJs(fs.readFileSync(filePath).toString())
              } else {await next()
              }
            })
          },
        ],
        transforms: [{  // 用于 rollup // 插件
          test: context => context.path.endsWith('.md'),
          transform: ({code}) => mdToJs(code) 
        }]
      }
  ],
};
  • prismjs

造成一个代码块并且带有语法高亮

  1. 引入
$ npm install prismjs
  1. 应用

prismjs 默认提供了多个主题,能够去 node_modules\prismjs\themes 下找一下

<template>
<pre class="language-html" v-html="html" />
</template>

<script>
const Prism = require('prismjs');
import 'prismjs/themes/prism-okaidia.css'
export default{setup(){
    const code = '<p>hello World</p>';
    const html = Prism.highlight(code,'html');
    return {html}
    }
}
<script>

利用 Custom Block(自定义块)和 vite 实现代码渲染器

待实现。。。

最初贴上源码链接 和 我的项目预览。

退出移动版