type
status
date
slug
summary
tags
category
icon
password
😀
总体功能:根据<template>里的class结构,在<style>里生成对应的样式结构。 可以有很多种唤起的方法,比如快捷键、ctrl点击对应的class,然后进行跳转等。

2023/9/15

这是写此开发日记的第一天,但不是开发的第一天。然而今天才算刚有所眉目。

项目结构

notion image
其中,extension.ts是插件的入口,parser包下,对使用到的两个库 @vue/compiler-core postcss-scss 下的node结构进行了封装(这个在“总体思路”里说)。

总体思路

具体来说,我想维护两个树。一个是 template 的html标签页里产生的class树,另一个是 style 下产生的的scss树。通过对比这两个树的节点的不同,来决定该在<style>的什么位置生成html树中已经写了的哪个class。
所以首先我需要对树节点进行一个定义。这里我提取了一个接口 ClassTreeNode
目前能想到的是至少得包含如下属性:
name就是节点的名字,children就是子节点(方便以后遍历)。相应地,遍历节点的方法就是 walkTree() 。其参数是一个方法,也就是遍历到节点node的时候,可以有一些附加操作behavior。
通过这样的接口,我已经成功地把两棵树解析出来了,并且可以获得树的每个节点class属性和name属性。
树结构——搞定!
可是接下来应该如何做呢……比对两棵树?没那么简单的。下次再想。
 

2023/9/17

难点

比对两棵树其实不难(?不难个p),更难的是想清楚怎么比
为了简化思考量,我认为得分如下几步去想:
  1. 先想清楚class,再想id和标签。
  1. 想清楚1之后,再想如何应对 > & 这种符号。
就比如,以下几个例子:
用户一步一步按规矩写的,固然是最好。但如果用户写出了这种代码,阁下应该如何应对呢?
至于Example 2,自然也不能算他错。那我应该如何生成呢?

思路(?)

经历了以下思维过程:
  1. 直接覆盖用户的样式(哒咩,肯定不行的)。
  1. 根据html生成scss。遍历html标签,一个一个去比对用户有没有对应的style。如果没有的话把他加上。
  1. 根据style回找html。如果html有对应的class,做个标记,然后走2的思路,把没标记的生成。我感觉没多大意义,但直觉告诉我最终需要有这么一个考量。
那么目前可行的就是2了。如果是这样的话,那么此拓展至少得有两种生成样式代码的方式。

方式一

此方式要与用户约定:
  1. style里的第一个标签必须是完全符合层级关系的总标签,就像example 1一样。如果没有这个总标签,插件给用户生成。如果有了,插件在这个总标签的基础上生成用户没有的样式标签。
  1. 插件不会动除了第一个标签之外的其他代码,用户可以在除第一个总标签之外的其他标签里任意添加别的样式。
其实这种方式不是很使用。万一用户@import了一个全局的样式表怎么办呢?这样的话,用户不一定需要这个总标签,可能只是在其他标签里,对样式进行缝缝补补的操作。
所以,我们还需要第二种生成代码的方式。

方式二

此方式要与用户约定:
  1. 可以没有总标签,不会按照html,完全将所有class生成出来
  1. 匹配规则是:遍历所有html标签,用户如果写了对应class的样式,则将其children里的所有东西生成到对应style位置。
  1. 这里的“生成到对应style位置”,指的是生成在用户写了的首个标签的位置。这似乎就要从scss代码回找html了。(不过今天的任务不是这个)
无论如何,得先实现一个功能:根据已有的html树,去生成对应的scss代码。
 

开发过程

根据已有的html树,去生成对应的scss代码。
还是使用postcss-scss库去生成比较好。我之前没有理清楚人家的数据结构就开写了,这不好,所以我得重新理一遍。

整理postcss-scss数据结构

最上层的用法是这样的:
进一步,可以找到 parse 的定义:
看来返回的是一个 RootNode = Document | Root 。这是什么呢?继续找:
大抵是不可能返回 Document 的,那就是返回 Root 了。经过测试,确实是这样的。
notion image
Root继承了Container。这个Container有点长,就不写了。container.d.ts 这个文件里。我感觉是比较重要的文件,里面有可以插入node的方法。
首先它定义了 nodes: Child[]
还有 append 方法:
分析差不多了,总体来说,就是操作 postcss 里的 Rule 类,每次调用 append 方法,完成规则代码的生成。大致而言如下:
 

2023/9/20

已经完成的工作:按照上次的开发思路,实现了生成代码的效果。
将要完成的工作:重构。目前代码完全按照面向过程来写,结构混乱不堪。拟封装成几个类。

重新架构思路

  1. 最上层是处理node的controller。因为我们的command分为很多种,所以要进行一个拆分。
  1. 中间层是将文本内容转化为各种数据结构的service层。这是最上层和数据结构层的连接。
  1. 数据结构层:node层。
    1. 一个是之前已经想了很久的 classTreeNode 接口。
    2. 目前还需要 location 数据结构,来被 controller 引用,用来在指定位置生成。
 

2023/9/23

已经完成的工作:完成了重构。并且完成了第一种模式:完全根据html结构,生成相应的代码。
将要完成的工作:实现第二种模式:比对移动模式。遍历所有html标签,用户在style里没写则生成空的,用户如果写了,则将其children里的所有东西生成到对应style位置。
记录一下现在的文件结构:
notion image
 

2023/9/24

已经完成的工作:完成了结构的重构,结构变得更加清晰了。
将要完成的工作:实现两棵树的结构、对应代码位置的生成。

思路(我不好说)

首先我们有两棵树。一个是html树,另一个是scss树(严格来讲这应该是一个森林)。目前想到的思路是:如果scss森林的某一棵树是html树的子树,则将其搬运到html树对应的位置。所以工作分成了两部分:
  1. 能够比对两棵树,判定某棵树是否是另一棵树的子树。
  1. 要记录第一棵树每个节点的对应位置,知道生成在哪里。难绷的是,这一点还完全没有做。
注意点:
  1. 这个规则下,我们的原则应该是:“有(相应的样式)则不改,无则添加”。
  1. 为了快速查找节点,我觉得应该给我们的 classTreeNode 的构造函数增加一个回调函数,可以用来建立索引。查找索引,可能会快一点。

🤗 总结归纳

没写完呢,不总结。

📎 参考文章

 
💡
有什么好思路的话,欢迎提出喵。
 
<a-button type="primary" :disabled="!companyStore.isAdmin()" @click="createTeam" >创建团队</a-button>
网络存储实验——Raid阵列手写Spring第二章:实现IoC容器
Niyuta
Niyuta
变分无限,孤心测度有同伦
公告
type
status
date
slug
summary
tags
category
icon
password
🎉热烈庆祝Niyuta拥有了个人网站!🎉
-- 感谢支持喵:) ---
👏网站正在建设中,有bug望不吝反馈赐教~👏
(迟早要重构掉