1.问题
想做实时代码高亮、并能提交代码到后端,用了codemirror
现在在根组件Vue中能全局地定义指令并正常使用,但是觉得不够优雅希望在某个组件内定义局部的directive,效果不正常,代码区域和行号重叠在一起了:
2.代码
components/v-codemirror/alias.js
import CodeMirror from 'codemirror/lib/codemirror.js'
require('codemirror/lib/codemirror.css')
require('codemirror/addon/lint/lint.css')
require('codemirror/mode/javascript/javascript.js')
require('codemirror/mode/css/css.js')
// require('jsonlint')
require('codemirror/addon/lint/lint.js')
require('codemirror/addon/lint/javascript-lint.js')
// require('codemirror/addon/lint/json-lint.js')
require('codemirror/addon/selection/active-line.js')
export default CodeMirror
全局定义并使用directive:ok
先看效果:
main.js
import Vue from 'vue'
import CodeMirror from './components/v-codemirror/alias'
Vue.directive('banzi', {
twoWay: true,
bind: function () {
const editor = CodeMirror(this.el, {
mode: 'javascript',
lineNumbers: true
})
this.editor = editor
this.editor.on('change', function () {
this.set(this.editor.getValue())
}.bind(this))
},
update: function (value, oldValue) {
this.editor.setValue(value || '')
console.log(this.editor.getValue())
}
})
/* eslint-disable no-new */
new Vue({
el: 'body',
data: {
snippet: 'sss'
},
methods: {
runSnippet () {
console.log(this.snippet)
}
}
})
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<h1>banzi</h1>
<div v-banzi="snippet"></div>
<button v-on:click="runSnippet">运行</button>
</html>
局部定义并使用directive:not ok
main.js
import Vue from 'vue'
import App from './App'
/* eslint-disable no-new */
new Vue({
el: 'body',
components: { App }
})
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<h1>app</h1>
<app></app>
</html>
子组件App.vue(局部定义directive)
<template>
<div id="app">
<textarea v-snippet="msg"></textarea>
</div>
</template>
<script>
import CodeMirror from './components/v-codemirror/alias'
export default {
data () {
return {
'msg': 'function test() { console.log("This is for test")}'
}
},
directives: {
'snippet': {
twoWay: true,
bind: function () {
var self = this
self.editor = CodeMirror.fromTextArea(self.el, {
lineNumbers: true,
mode: 'javascript'
})
self.editor.on('change', function () {
self.set(self.editor.getValue())
this.msg = self.editor.getValue()
}.bind(this))
},
update: function (value, oldValue) {
this.editor.setValue(value || '')
console.log(this.editor.getMode())
}
}
}
}
</script>