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