将.js文件转成vue标签结构的样式


在vue项目中,有一个需求是:将原本的.js文件结构转成vue标签结构的样式。

例如:下图所示:

依次识别获取.js文件中的tagprops,简单来说,可以理解为字符串拼接,将整个vue的标签结构看作是一个字符串。

话不多说,先放上完整代码,思路看代码备注。(自己实现的时候,可以先把tag标签,即vue结构弄出来,后续再加上props属性,这样思路会更加清晰)

实现方法:
首先想到的是利用递归,一点一点的拼接字符串””,因为.js文件到底多大是不确定的。

字符串的拼接是一点点的拼凑在一起的。

data() {
    return {
      previewContent: '',
      suojinStr: ''// 获取缩进字符
    }
  },
 methods: {
    handlePreview() {
      var jsdata = require('../../../public/js/bbb.js') //获取文件
      this.obtainData(jsdata.default) //调用递归方法
      this.previewContent = '<template>' + this.previewContent + '\n' + '</template>'
    },
    obtainData(data) {
      var children = data.children
      if (children) {
        this.suojinStr += '\t'
        for (var i = 0; i < children.length; i++) {
          // 拼接字符串:换行符+缩进+开始标签
          this.previewContent += '\n' + this.suojinStr + '<' + children[i].tag + '>'

          // 获取props相关数据---放在开始标签的里面--比开始标签在往里缩进一格
          if (children[i].props !== undefined) {
            for (var key in children[i].props) {
              // 拼接字符串:换行符+缩进+(再一格缩进)+props的内容
              this.previewContent += '\n' + this.suojinStr + '\t' + key + '=' + '"' + children[i].props[key] + '"'
            }
          }

          // 调用自身,递归---挖掘孩子节点,一层一层拼接
          this.obtainData(children[i])

          // 拼接字符串:换行符+缩进+结束标签---当没有孩子时,闭合标签
          this.previewContent += '\n' + this.suojinStr + '</' + children[i].tag + '>'
        }
        // 结束标签的空格回退---父亲的结束标签和和父亲的开始标签对齐,所以等没有孩子时,回退一格缩进
        this.suojinStr = this.suojinStr.substr(1)
      }
    }
  }

后面,和 Sweny-blog讨论了一下,发现她的字符串是整个拼接起来的,不像我拼接的这么零碎。然后我也尝试了一下拼接完整版。

代码如下:
methods: {
    handlePreview() {
      var jsdata = require('../../../public/js/bbb.js')
      this.previewContent = this.obtainData1(jsdata.default)
      this.previewContent = '<template>' + this.previewContent + '\n' + '</template>'
    },
    obtainData1(data) {
      // 换行+缩进+首标签+递归(找孩子)+换行+缩进+尾标签
      var previewContent = ''
      var children = data.children
      if (children) {
        this.suojinStr += '\t'
        for (var i = 0; i < children.length; i++) {

          // 获取props属性的值---这块可以写成一个函数,后面完整拼接的时候,直接调用就行了
          var propsStr = ''
          if (children[i].props !== undefined) {
            for (var key in children[i].props) {
              propsStr += '\n' + this.suojinStr + '\t' + key + '=' + '"' + children[i].props[key] + '"'
            }
          }
          // 完整的拼接
          previewContent += '\n' + this.suojinStr + '<' + children[i].tag + '>' + propsStr + this.obtainData1(children[i]) + '\n' + this.suojinStr + '</' + children[i].tag + '>'
        }
        // 结束标签的空格回退
        this.suojinStr = this.suojinStr.substr(1)
      }
      return previewContent
    },
  }

这里面用到了previewContent这个局部变量进行拼接

为什么要使用局部变量?不像之前使用全局变量?

因为,拼接字符串中,调用了this.obtainData1(children[i])获取孩子拼接的字符串,若是全局变量,没有清空的过程,它会累加多余的字符。这里涉及到的知识点是变量作用域。

下面简单写个相似的递归:

function test1(num){
    var str = ''
    console.log('外面的str:'+ str)
    num++
    if(num<5){
        str+='a'+test1(num)
        console.log('if里面的str:'+ str)
    }
    return str;
}

test1(0);

依次输出:

递归的过程是一层一层调用函数,每调用一个函数,又重新声明赋值了:var str = ‘’,这就相当于子函数重新生成了一个同名变量,操作的是自己的变量。这个return str;是每次递归调用子函数,子函数返回的字符串。一层一层的累加。

其实相当于:先走到最内层,然后从最内层一层一层往外加str。

再看一个var变量作用域的示例,若是还不懂,之前发过一篇博客,专门讲作用域的,可以看看。

var a = 1
function test4(){
    var a= 2;
    console.log(a)
}

console.log(a) // 输出:1
test4();       // 输出:2
console.log(a) // 输出:1

子函数自己有那个变量就用自己的,操作的也是自己的变量,此时不会修改父类的变量。


文章作者: 木华
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 木华 !
评论