vue 에서 code Mirror를 쓰는 방법과
더나아가 MaxLength를 설정하는 방법을 알아보좌!
1. Code mirror 설치
npm install vue-codemirror --save
그러면 package.json에 codemirror가 추가된걸 확인 할 수 있다.
2. main.js 에 선언
import Codemirror from 'vue-codemirror';
Vue.use(Codemirror);
3. code mirror 컴포넌트 사용
<codemirror v-model="query" :options="options" ref="codeMirror" />
v-model에는 codemirror에 입력되는 값을 변수 선언한 뒤 넣어주고
다양한 모드와 옵션이 있는데 그건 부모 컴포넌트에서 options 로 선언해주고 props로 내려주면된다.
나같은 경우에는 query를 입력하는 창이라 관련되어서 옵션을 data에 선언해 주었다.
예)
options: {
tabSize: 4,
styleActiveLine: true,
mode: 'text/x-sql',
lineNumbers: true,
line: true,
lineWrapping: true,
theme: 'default'
},
더 다양한 옵션은 다음을 참고해보자
https://github.com/surmon-china/vue-codemirror#readme
4. max Length 설정하기
options에 따로 max Length 관련 지원이 없어서 직접 구현하였다.
먼저 기존 options에 maxLength라고 선언해준다.
options: {
tabSize: 4,
styleActiveLine: true,
mode: 'text/x-sql',
lineNumbers: true,
line: true,
lineWrapping: true,
theme: 'default',
maxLength: 4000,
},
그 뒤 , 다음 링크를 참고하여 구현 하였다.
https://github.com/codemirror/CodeMirror/issues/821
codemirror 소스를 보니 모든 event가 발생하면 emit 해주고 있었다.
const allEvents = [
'scroll',
'changes',
'beforeChange',
'cursorActivity',
'keyHandled',
'inputRead',
'electricInput',
'beforeSelectionChange',
'viewportChange',
'swapDoc',
'gutterClick',
'gutterContextMenu',
'focus',
'blur',
'refresh',
'optionChange',
'scrollCursorIntoView',
'update'
]
.concat(this.events)
.concat(this.globalEvents)
.filter(e => (!tmpEvents[e] && (tmpEvents[e] = true)))
.forEach(event => {
// 循环事件,并兼容 run-time 事件命名
this.cminstance.on(event, (...args) => {
// console.log('当有事件触发了', event, args)
this.$emit(event, ...args) // EMIT !!!!
const lowerCaseEvent = event.replace(/([A-Z])/g, '-$1').toLowerCase()
if (lowerCaseEvent !== event) {
this.$emit(lowerCaseEvent, ...args)
}
})
})
그래서 부모 컴포넌트에서 codeMirror를 사용하는쪽에서 emit 하는 function을 받아주었다.
<codemirror v-model="query" :options="options" ref="codeMirror" @beforeChange="enforceMaxLength" />
그리고 다음과 같이 더이상 입력되지 않도록 function 을 선언해주었다.
enforceMaxLength(cm, change) {
let maxLength = cm.getOption('maxLength');
if (maxLength) {
let str = change.text.join('\n');
let delta = str.length - (cm.indexFromPos(change.to) - cm.indexFromPos(change.from));
this.cmLength = cm.getValue().length + delta;
if (this.cmLength > maxLength) {
this.cmLength = maxLength;
}
delta = cm.getValue().length + delta - maxLength;
if (delta >= 0) {
str = str.substr(0, str.length - delta);
change.update(change.from, change.to, str.split('\n'));
}
}
return true;
},
그리고 현재 length를 세어주기 위해 cmLength를 선언해주고 length를 넣어주었다.
'DEVELOP > Frontend' 카테고리의 다른 글
[Vuex] Vue의 상태 관리 및 Helper( mapState, mpaGetters, mapMutations, mapActions) (0) | 2024.01.29 |
---|---|
[Vue] Component Force Rerendering 하기 (강제로 rerender) (2) | 2021.10.26 |
[Vue] computed , watch 중에서 뭐써야하지??? 헷갈리네 (0) | 2020.10.30 |
[Vue] 컴포넌트를 특정부분만 수정해서 쓰고싶다면? Slot ( 컴포넌트 재사용하기) (0) | 2020.06.25 |
React : Functional component 와 Class component의 차이점 (0) | 2020.03.24 |