实现自定义组件的 v-model数据绑定
This commit is contained in:
parent
9ac3606f83
commit
fcd4673279
13
src/App.vue
13
src/App.vue
@ -4,7 +4,13 @@
|
||||
<h1>vue-markdown编辑器组件</h1>
|
||||
<a target="_blank" href="https://github.com/zhaoxuhui1122/vue-markdown">使用文档</a>
|
||||
<div class="content">
|
||||
<mark-down @on-paste-image="handlePasteImage" @on-save="save" :theme="theme" :initialValue="initialValue" :markedOptions="{baseUrl:'http://smalleyes.oss-cn-shanghai.aliyuncs.com/'}"></mark-down>
|
||||
<mark-down @on-paste-image="handlePasteImage"
|
||||
@on-save="save"
|
||||
v-model="value"
|
||||
:theme="theme"
|
||||
:interval="5000"
|
||||
:initialValue="initialValue"
|
||||
:markedOptions="{baseUrl:'http://smalleyes.oss-cn-shanghai.aliyuncs.com/'}"></mark-down>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -12,10 +18,9 @@
|
||||
|
||||
<script>
|
||||
import MarkDown from './markdown/index' // 开发文件
|
||||
// import MarkDown from "../build"; // 引入打包好的文件
|
||||
// import MarkDown from 'vue-meditor';
|
||||
|
||||
import doc from './doc';
|
||||
|
||||
export default {
|
||||
name: "app",
|
||||
components: {
|
||||
@ -23,6 +28,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
initialValue: "",
|
||||
theme: 'OneDark'
|
||||
};
|
||||
@ -30,6 +36,7 @@
|
||||
methods: {
|
||||
save(res) {
|
||||
console.log(res);
|
||||
this.value = 'edit ...'
|
||||
},
|
||||
handlePasteImage(res) {
|
||||
console.log(res);
|
||||
|
@ -116,7 +116,8 @@
|
||||
<li v-for="(item,index) in indexLenth">{{index+1}}</li>
|
||||
</ul>
|
||||
<textarea
|
||||
v-model="value"
|
||||
:value="values"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
@keydown.tab="tab"
|
||||
@keyup.enter="enter"
|
||||
@keyup.delete="onDelete"
|
||||
|
@ -23,8 +23,21 @@ marked.setOptions({
|
||||
|
||||
export default {
|
||||
name: 'markdown',
|
||||
model: {
|
||||
/**
|
||||
* 自定义组件的 v-model
|
||||
*/
|
||||
prop: 'value',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
initialValue: String, // 初始化内容
|
||||
value: {
|
||||
type: String,
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
}, // 自定义组件的 v-model
|
||||
theme: { // 默认主题
|
||||
type: String,
|
||||
default: 'Light'
|
||||
@ -39,7 +52,7 @@ export default {
|
||||
}, // 宽度
|
||||
toolbars: { // 工具栏
|
||||
type: Object,
|
||||
default () {
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
@ -57,14 +70,14 @@ export default {
|
||||
},
|
||||
markedOptions: {
|
||||
type: Object,
|
||||
default () {
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: '', // 输入框内容
|
||||
values: '', // 输入框内容
|
||||
timeoutId: null,
|
||||
indexLenth: 100,
|
||||
html: '',
|
||||
@ -119,7 +132,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.value = this.initialValue;
|
||||
this.values = this.initialValue;
|
||||
this.themeName = this.theme;
|
||||
this.editorHeight = this.height;
|
||||
this.editorWidth = this.width;
|
||||
@ -190,9 +203,9 @@ export default {
|
||||
}
|
||||
this.lastInsert = initStr;
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastFourCharts = this.value.substring(point - 4, point);
|
||||
if (lastChart !== '\n' && this.value !== '' && lastFourCharts !== ' ') {
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
const lastFourCharts = this.values.substring(point - 4, point);
|
||||
if (lastChart !== '\n' && this.values !== '' && lastFourCharts !== ' ') {
|
||||
const str = '\n' + initStr;
|
||||
this.insertAfterText(str);
|
||||
} else {
|
||||
@ -205,7 +218,7 @@ export default {
|
||||
if (document.selection) {
|
||||
textDom.focus();
|
||||
let selectRange = document.selection.createRange();
|
||||
selectRange.moveStart('character', -this.value.length);
|
||||
selectRange.moveStart('character', -this.values.length);
|
||||
cursorPos = selectRange.text.length;
|
||||
} else if (textDom.selectionStart || parseInt(textDom.selectionStart, 0) === 0) {
|
||||
cursorPos = textDom.selectionStart;
|
||||
@ -233,7 +246,7 @@ export default {
|
||||
textDom.value += value;
|
||||
textDom.focus();
|
||||
}
|
||||
this.$set(this, 'value', textDom.value);
|
||||
this.$set(this, 'values', textDom.value);
|
||||
},
|
||||
setCaretPosition(position) { // 设置光标位置
|
||||
const textDom = this.$refs.textarea;
|
||||
@ -274,9 +287,9 @@ export default {
|
||||
},
|
||||
insertCode() { // 插入code
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('\n```\n\n```');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 5);
|
||||
} else {
|
||||
this.setCaretPosition(point + 5);
|
||||
@ -284,9 +297,9 @@ export default {
|
||||
},
|
||||
insertStrong() { // 粗体
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('****');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 2);
|
||||
} else {
|
||||
this.setCaretPosition(point + 2);
|
||||
@ -294,9 +307,9 @@ export default {
|
||||
},
|
||||
insertItalic() { // 斜体
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('**');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 1);
|
||||
} else {
|
||||
this.setCaretPosition(point + 1);
|
||||
@ -304,9 +317,9 @@ export default {
|
||||
},
|
||||
insertBg() { // 背景色
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('====');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 5);
|
||||
} else {
|
||||
this.setCaretPosition(point + 5);
|
||||
@ -314,9 +327,9 @@ export default {
|
||||
},
|
||||
insertUnderline() { // 下划线
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('<u></u>');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 3);
|
||||
} else {
|
||||
this.setCaretPosition(point + 5);
|
||||
@ -324,9 +337,9 @@ export default {
|
||||
},
|
||||
insertOverline() { // overline
|
||||
const point = this.getCursortPosition();
|
||||
const lastChart = this.value.substring(point - 1, point);
|
||||
const lastChart = this.values.substring(point - 1, point);
|
||||
this.insertContent('~~~~');
|
||||
if (lastChart !== '\n' && this.value !== '') {
|
||||
if (lastChart !== '\n' && this.values !== '') {
|
||||
this.setCaretPosition(point + 2);
|
||||
} else {
|
||||
this.setCaretPosition(point + 2);
|
||||
@ -383,13 +396,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onDelete() { // 删除时,以回车为界分割,如果数组最后一个元素为''时,将行一次插入的共嗯那个置为空,避免回车时再次插入
|
||||
const lines = this.value.split('\n');
|
||||
const lines = this.values.split('\n');
|
||||
if (lines[lines.length - 1] === '') {
|
||||
this.lastInsert = '';
|
||||
}
|
||||
},
|
||||
exportMd() { // 导出为.md格式
|
||||
saveFile(this.value, this.exportFileName + '.md');
|
||||
saveFile(this.values, this.exportFileName + '.md');
|
||||
},
|
||||
importFile(e) { // 导入本地文件
|
||||
const file = e.target.files[0];
|
||||
@ -408,7 +421,7 @@ export default {
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
reader.onload = () => {
|
||||
this.value = reader.result;
|
||||
this.values = reader.result;
|
||||
e.target.value = '';
|
||||
}
|
||||
},
|
||||
@ -445,21 +458,27 @@ export default {
|
||||
this.previewImgSrc = src;
|
||||
this.previewImgModal = true;
|
||||
}
|
||||
},
|
||||
getValue() {
|
||||
return this.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
initialValue() {
|
||||
this.value = this.initialValue;
|
||||
this.values = this.initialValue;
|
||||
},
|
||||
value() {
|
||||
this.values = this.value
|
||||
},
|
||||
values() {
|
||||
clearTimeout(this.timeoutId);
|
||||
this.timeoutId = setTimeout(() => {
|
||||
this.html = marked(this.value, {
|
||||
this.html = marked(this.values, {
|
||||
sanitize: false,
|
||||
...this.markedOptions
|
||||
});
|
||||
}, 30)
|
||||
this.indexLenth = this.value.split('\n').length;
|
||||
this.indexLenth = this.values.split('\n').length;
|
||||
const height1 = this.indexLenth * 22;
|
||||
const height2 = this.$refs.textarea.scrollHeight;
|
||||
const height3 = this.$refs.preview.scrollHeight;
|
||||
|
Loading…
Reference in New Issue
Block a user