Vue在线编译器
Posted 前端优选
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue在线编译器相关的知识,希望对你有一定的参考价值。
戳蓝字"
前端优选
"
关注我们哦
!
来源:CSDN 本文链接:https://blog.csdn.net/WangYangsea/article/details/95237722
现在网络上,有非常多的JS在线编译器,非常好用,特备是在调试某些片段代码的时候,比在本地重新新建文件来的方便快捷~ 非常流行的比如 JS.do、 jsfiddle、JSRUN 等等。
而对于Vue来说,在线编译器有时候会显得更加必要,因为初始化一个Vue项目还是需要花一点时间的~并且需要安卓很多的依赖,费时费力。现在也有很多JS在线编译器已经支持Vue代码了,另外流行的Vue框架)IView也有一个专门的在线编译器 IView Run,不止支持Vue,还支持IView 相关组件~。
接下来,我们两写一个功能相似的乞丐版Vue在线编译器 vue-running。
首先我们来看一下demo效果:
vue在线编译效果
extend 和 $mount
在开始之前,我们先来了解一下Vue的两个不是很常用的API extend 和 $mount。
我们在使用 vue-cli + webpack构建一个新的工程的时候, 入口JS文件main.js中最后 总会看到这么一段:
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
在创建一个Vue实例的时候,我们都有一个el属性,决定这个实例需要挂载在那个节点上(根节点),如果没有el属性,那么该实例处于未挂载状态。
-
Vue.extend()就是利用Vue的构造器功能,创建一个子类,但是属于未挂载状态; -
$mount 就是一个手动去挂载Vue实例的方法。
我们可以看官方文档给的实例:
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
结果如下:
<div id="mount-point">
<p>Walter White aka Heisenberg</p>
</div>
vm.$mount()相关说明
「今天所说的 vue-running小demo,就是基于这两个属性做的」
分析
通常,我们Vue项目中的.vue文件构成如下:
<template>
......
</template>
<script>
export default {
......
</script>
<style scoped>
......
</style>
❝❞
template 为html模板 script 为组件的数据、方法等 style css样式相关
我们回看上面extend方法,其实.vue文件中的 就代表 extend中 template,script中代表extend中的其他选项。style我们稍后再处理。
通过上面分析,首先我们得将.vue文件中的内容进行匹配分割,然后用Vue.extend()创建子类,最后挂载~。
首先我们在components文件夹下面新建:
❝❞
index.vue vue-running的显示页面 edit.vue 编辑Vue代码的组件 running.vue 最终编辑完的实例挂载之后显示的内容
首先我们看edit.vue:
<template>
<div class="edit-box">
<div class="btn-box">
<button @click="handleClick">运行代码</button>
<button class="edit" @click="edit">重新编辑</button>
</div>
<div class="style-box">
<textarea :disabled="disabled" name="code" placeholder="请在此编写.vue文件" @input="handleChange"></textarea>
</div>
</div>
</template>
<script>
export default {
name: 'edit',
props: {
value: {
type: String,
default: ''
}
},
data () {
return {
currentValue: this.value,
disabled: false
}
},
methods: {
handleChange (e) {
const val = e.target.value
this.$emit('input', val)
},
handleClick () {
this.$emit('running')
if (this.currentValue) {
this.disabled = true
}
},
edit () {
this.disabled = false
}
}
}
</script>
其实功能比较简单,就是一个双向数据绑定的textarea输入框。外加 运行 和重新编辑 两个按钮,并将事件向外”广播“。
接下来我们看running.vue:
<template>
<div class="hello">
<h3 class="title">运行结果</h3>
<div class="code-box" id="display"></div>
</div>
</template>
<script>
import Vue from 'vue'
export default {
name: 'running',
props: {
value: {
type: String,
default: ''
}
},
data () {
return {
code: this.value,
html: '',
js: '',
css: '',
program: null
}
},
watch: {
value (val) {
this.code = val
}
},
methods: {
getSource (source, type) {
const regex = new RegExp(`<${type}[^>]*>`)
let openingTag = source.match(regex)
if (!openingTag) return ''
else openingTag = openingTag[0]
return source.slice(
source.indexOf(openingTag) + openingTag.length,
source.lastIndexOf(`</${type}>`)
)
},
splitCode () {
const script = this.getSource(this.code, 'script').replace(
/export default/,
'return '
)
const style = this.getSource(this.code, 'style')
const template =
'<div id="code-running">' +
this.getSource(this.code, 'template') +
'</div>'
this.js = script
this.css = style
this.html = template
},
buildDom () {
this.splitCode()
if (this.html === '' || this.js === '') {
this.$toast({
msg: `请输入有效的Vue代码${Math.floor(Math.random() * 1000)}`
})
// eslint-disable-next-line semi
return;
}
// eslint-disable-next-line no-new-func
const common = new Function(this.js)()
common.template = this.html
const Template = Vue.extend(common)
this.program = new Template()
document.querySelector('#display').appendChild(this.program.$mount().$el)
if (this.css !== '') {
const styles = document.createElement('style')
styles.type = 'text/css'
styles.innerHTML = this.css
document.getElementsByTagName('head')[0].appendChild(styles)
}
},
reset () {
document.getElementById('display').innerHTML = ''
if (this.program) {
this.program.$destroy()
}
this.program = null
}
}
}
</script>
❝稍作分析:
❞
该组件props接受一个value,string类型的,就是我们在线编辑的.vue文件代码; data里面定义了 code: this.value ,另外定义了被分割好之后的代码片段js html css; methods里面定义的方法 getSource() 通过正则匹配分割代码并去除最外层的
点个在看,大家都看
以上是关于Vue在线编译器的主要内容,如果未能解决你的问题,请参考以下文章