您现在的位置是:亿华云 > IT科技

手把手教你实现一个简易的Vue组件在线编辑器

亿华云2025-10-04 00:59:21【IT科技】0人已围观

简介vue-cli使用过vue的我想大家都知道,那么xxx.vue组件是怎么运行的呢?怎么把template,script,style渲染到页面上的呢?今天我们手动写了个简易的Vue组件在线编辑器玩一玩。

 

vue-cli使用过vue的手把手教实现我想大家都知道,那么xxx.vue组件是个简怎么运行的呢?怎么把template,script,style渲染到页面上的呢?今天我们手动写了个简易的Vue组件在线编辑器玩一玩。

话不多说先看一下效果

准备工作

安装vuejs 新建xxx.html 新建xxx.css

编写页面

<div id="app">        <textarea name="" id="" cols="30" rows="30" v-model="content" autofocus placeholder="请输入vue模板"></textarea>        <div class="btn-center">            <button @click="run">运行代码</button>            <button @click="reset">清除</button>        </div>    </div>    <div id="result"></div>    <script src="./node_modules/vue/dist/vue.js"></script>  textarea 元素为vue组件代码的编辑编写部分,button为按钮区域 textarea {              display: block;             width: 100%;             min-height: 100px;             max-height: 500px;             padding: 8px;             resize: auto;  }  button {              margin-top: 8px;             display: inline-block;             padding: 5px 16px;             font-size: 14px;             font-weight: 500;             line-height: 20px;             white-space: nowrap;             vertical-align: middle;             cursor: pointer;             -webkit-user-select: none;             -moz-user-select: none;             -ms-user-select: none;             user-select: none;             border: 1px solid;             border-radius: 6px;             -webkit-appearance: none;             -moz-appearance: none;             appearance: none; }  .btn-center{             text-align: center;  } 

思路分解

在xxx.vue中,我们写组件通常遵循一下模板

<template> </template> <script> export default {  } </script> <style> </style> 

我们想到的手把手教实现是在拿到输入的内容之后,我们希望获取都tempalte,个简script,style中的内容,网站模板然后通过Vue.extend( options )方法挂载到页面的编辑元素上即可。

解析标签

我们需要拿到内容包括下图红圈外的手把手教实现部分

可以利用字符串的match方法获取到每一段的开始标签的下标,开始标签的个简长度以及结束标签的下标,然后通过slice方法截取获取到想要的编辑内容。

getSource(type){      const reg = new RegExp(`<${ type}[^>]*>`);     let content = this.content;     let matches = content.match(reg);     if(matches){        let start = content.indexOf(matches[0])+matches[0].length;       let end = content.lastIndexOf(`</${ type}`);       return content.slice(start,手把手教实现end)     }   }, 

截取之后获取到的结果

转化函数

在vue官网中,data必须是服务器托管一个函数,我们拿到的是一个字符串

export default {      data(){          return {              msg:hello world         }     },     methods:{          run(){              console.log("你好")         }     } } 

如何把一个字符串转化为可执行函数,可以参考如何让一个字符串执行?个简

我们可以用new Function方法将字符串转化为可执行函数,我们需要的编辑是

data(){          return {              msg:hello world         }     },     methods:{          run(){              console.log("你好")         }     } 

利用字符串的replace方法将export default 替换成return得到

完成代码

run:function(){   let template = this.getSource("template");  if(!template) return  let script = this.getSource("script");  if(script){     script = script.replace(/export default/,"return");  }  let obj = new Function(script)();  obj.template = template;  let Profile = Vue.extend(obj);  new Profile().$mount("#result") }, 

处理样式

通过正则解析拿到style样式之后,添加到head中即可

let styleCss = this.getSource("style"); let style = document.createElement("style"); style.innerHTML = styleCss; document.head.appendChild(style); 

总结

以上就是手把手教实现本文的全部内容了,只是个简简单地借助Vue.extend()方法实现的一个简单的源码下载Vue组件在线编辑器

<div id="app">     <textarea name="" id="" cols="30" rows="30" v-model="content" autofocus placeholder="请输入vue模板"></textarea>     <div class="btn-center">         <button @click="run">运行代码</button>         <button @click="reset">清除</button>     </div> </div> <div id="result"></div> <script src="./node_modules/vue/dist/vue.js"></script> <script>     new Vue({          el: "#app",         data() {              return {                  content: ""             }         },         methods: {              getSource(type) {                  const reg = new RegExp(`<${ type}[^>]*>`);                 let content = this.content;                 let matches = content.match(reg);                 if (matches) {                      let start = content.indexOf(matches[0]) + matches[0].length;                     let end = content.lastIndexOf(`</${ type}`);                     console.log(content.slice(start, end));                     return content.slice(start, end)                 }             },             run: function () {                  let template = this.getSource("template");                 if (!template) return                 let script = this.getSource("script");                 if (script) {                      script = script.replace(/export default/, "return");                 }                 let styleCss = this.getSource("style");                 let style = document.createElement("style");                 style.innerHTML = styleCss;                 document.head.appendChild(style);                 let obj = new Function(script)();                 obj.template = template;                 let Profile = Vue.extend(obj);                 new Profile().$mount("#result")             },             reset() {                  this.content =              }         }     }) </script> 

很赞哦!(46)