• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

更新vue使用 wangeditor4 富文本 + 富文本回显带标签+wangEditor4 加字数,光标会跑到最后 问题 已解决

武飞扬头像
Daisy_ls
帮助1

背景:业务需求,要实现一个富文本框,好方便用户插入图片

问题:百度了一整天,看了n多文章包括官方文档,又花了半天时间实现需求,对于小白来说,真的是大难题,又着急,又害怕,结果就是,越急越搞不定……此处省略我的吐槽

来吧,上步骤:

一、安装富文本 wangEditor(参考官方文档)wangEditor

npm install wangeditor --save

我这里装的是版本4 (因为我折腾了半天的版本5 没搞出来)

二、在components文件夹下新建一个Vue文件,名字随便。参考:wangEditor.vue

把下面代码复制粘贴进去(图片上传部分还没完善好)

  1.  
    <template>
  2.  
    <div>
  3.  
    <div id="websiteEditorElem" style="height:300px;background: #ffffff;"></div>
  4.  
    </div>
  5.  
    </template>
  6.  
     
  7.  
    <script>
  8.  
    import E from 'wangeditor'
  9.  
    export default {
  10.  
    name: "wangEditor",
  11.  
    props: {
  12.  
    content: "" //获取从父组件中传过来的值,主要用于修改的时候获取值,并加入到富文本框中
  13.  
    },
  14.  
    data() {
  15.  
    return {
  16.  
    phoneEditor: '',
  17.  
    name: '',
  18.  
    }
  19.  
    },
  20.  
    methods: {
  21.  
     
  22.  
    },
  23.  
    mounted() {
  24.  
    this.phoneEditor = new E('#websiteEditorElem')
  25.  
    // 上传图片到服务器,base64形式
  26.  
    this.phoneEditor.config.uploadImgShowBase64 = true
  27.  
    // // 隐藏网络图片
  28.  
    this.phoneEditor.config.showLinkImg = false;
  29.  
     
  30.  
    this.phoneEditor.config.debug = true;
  31.  
    //图片上传接口
  32.  
    this.phoneEditor.config.uploadImgServer = '' // 上传图片的接口地址
  33.  
    this.phoneEditor.config.uploadFileName = 'image' // formdata中的name属性,比如现在是将图片image加入到formdate,后台从image中接收到图片数据
  34.  
    this.phoneEditor.config.uploadImgHeaders = {
  35.  
    token: sessionStorage.getItem("token") // 设置请求头
  36.  
    }
  37.  
    this.phoneEditor.config.uploadImgHooks = {
  38.  
    customInsert: function (insertImg, result, editor) {
  39.  
    console.log("成功", result);
  40.  
    // before: function (xhr, editor, files) {
  41.  
    // // 图片上传之前触发
  42.  
    // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
  43.  
     
  44.  
    // // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
  45.  
    // // return {
  46.  
    // // prevent: true,
  47.  
    // // msg: '放弃上传'
  48.  
    // // }
  49.  
    // },
  50.  
    // success: function (xhr, editor, result) {
  51.  
    // // 图片上传并返回结果,图片插入成功之后触发
  52.  
    // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
  53.  
    // },
  54.  
    // fail: function (xhr, editor, result) {
  55.  
    // // 图片上传并返回结果,但图片插入错误时触发
  56.  
    // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
  57.  
    // },
  58.  
    // error: function (xhr, editor) {
  59.  
    // // 图片上传出错时触发
  60.  
    // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
  61.  
    // },
  62.  
    // timeout: function (xhr, editor) {
  63.  
    // // 图片上传超时时触发
  64.  
    // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
  65.  
    // },
  66.  
     
  67.  
    // // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
  68.  
    // // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
  69.  
    // customInsert: function (insertImg, result, editor) {
  70.  
    // // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
  71.  
    // // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
  72.  
     
  73.  
    // // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
  74.  
    // var url = result.url
  75.  
    // insertImg(url)
  76.  
     
  77.  
    // // result 必须是一个 JSON 格式字符串!!!否则报错
  78.  
    // }
  79.  
    }
  80.  
    }
  81.  
    // 创建一个富文本编辑器
  82.  
    this.phoneEditor.create()
  83.  
    // 修改的时候,需要富文本内容回显,则需要加入以下代码
  84.  
    this.phoneEditor.txt.html(this.content)
  85.  
     
  86.  
    this.phoneEditor.config.onchange = (html) => {
  87.  
    this.info_ = html // 绑定当前逐渐地值
  88.  
    this.$emit('change', this.info_) // 将内容同步到父组件中
  89.  
    }
  90.  
    },
  91.  
    }
  92.  
    </script>

步骤分解:

将内容同步到父组件中:

  1.  
    this.phoneEditor.config.onchange = (html) => {
  2.  
    this.info_ = html // 绑定当前逐渐地值
  3.  
    this.$emit('change', this.info_) // 将内容同步到父组件中
  4.  
    }

父组件中的获取方法是

<WangEdit @change="grtUrl" :content="editForm.content"></WangEdit>

@change="getUrl1"获取子组件中的数据,具体方法如下:

  1.  
    grtUrl(path){
  2.  
    this.editForm.content = path;
  3.  
    },

将子组件的数据加入到this.editForm.content中

修改内容时

需要富文本框中的数据回显,在子组件中加入

  1.  
    props:{
  2.  
    content:"" //获取从父组件中传过来的值,主要用于修改的时候获取值,并加入到富文本框中
  3.  
    },

三、从父组件中调用子组件时

完整代码:

  1.  
    <el-dialog title="修改培训信息" v-model="editWinVisible" width="45%" :before-close="handleClose" :center="false">
  2.  
    <el-row class="dialog-detail">
  3.  
    <el-col :span="5" class="dialog-detail-title">培训编号:</el-col>
  4.  
    <el-col :span="19" class="dialog-detail-content">{{editForm.code}}</el-col>
  5.  
    <el-col :span="5" class="dialog-detail-title">培训标题:</el-col>
  6.  
    <el-col :span="19" class="dialog-detail-content">
  7.  
    <el-input v-model="editForm.title" placeholder="请输入培训标题"></el-input>
  8.  
    </el-col>
  9.  
    <el-col :span="5" class="dialog-detail-title">培训内容:</el-col>
  10.  
    <el-col :span="19" class="dialog-detail-content" >
  11.  
    <WangEdit @change="grtUrl" :content="editForm.content"></WangEdit>
  12.  
    </el-col>
  13.  
    <el-col :span="5" class="dialog-detail-title">创建时间:</el-col>
  14.  
    <el-col :span="19" class="dialog-detail-content">
  15.  
    {{editForm.createDate}}
  16.  
    </el-col>
  17.  
    </el-row>
  18.  
    <span slot="footer" class="dialog-footer">
  19.  
    <el-button @click="CloseWin()">关闭</el-button>
  20.  
    <el-button type="primary" @click="SaveEditData()">保存</el-button>
  21.  
    </span>
  22.  
    </el-dialog>
  1.  
    <script>
  2.  
    import WangEdit from '@/components/wangEditor.vue' //WangEditor在项目中的地址
  3.  
    import Req from '@/utils/ApiRequest'
  4.  
    export default{
  5.  
    components:{ WangEdit },
  6.  
    data(){
  7.  
    return{
  8.  
    editForm:{content:''},
  9.  
    editWinVisible:false,
  10.  
    }
  11.  
    },
  12.  
    methods:{
  13.  
    grtUrl(path){
  14.  
    this.editForm.content = path;
  15.  
    },
  16.  
    SaveEditData(){
  17.  
    console.log('send',this.editForm)
  18.  
    //下面这行代码就是控制页面显示是否带<p>标签的
  19.  
    //this.editForm.content=this.editForm.content.replace(/<[^>] >/g,"")
  20.  
    Req.UpdateNews(this.editForm).then((res)=>{
  21.  
    if(res.status==200)
  22.  
    {
  23.  
    this.$message({type: 'success', message: '保存成功!'});
  24.  
    this.CloseWin();
  25.  
    this.GetTabData();
  26.  
    }
  27.  
    else{
  28.  
    this.$message({type: 'error', message: '保存失败!'});
  29.  
    }
  30.  
    })
  31.  
    },
  32.  
    }
  33.  
    }

 富文本框就好了,数据也绑上了

学新通

 注意:接下来,出现了一个bug,我在文本框里编辑后,页面绑定的数据神奇的带上了标签:

学新通

 学新通

 好了,接下来又是一顿百度,还好让我找到了

使用富文本quill-editor发送后台数据有标签问题<p>

学新通

在点击确认提交的时候将富文本数据双向绑定的时候,添加  .replace(/<[^>] >/g,"")

我是保存时,那么我的代码要做如下更改,加一行this.editForm.content=this.editForm.content.replace(/<[^>] >/g,"")

  1.  
  2.  
    SaveEditData(){
  3.  
     
  4.  
     
  5.  
    this.editForm.content=this.editForm.content.replace(/<[^>] >/g,"")
  6.  
     
  7.  
     
  8.  
    Req.UpdateNews(this.editForm).then((res)=>{
  9.  
    if(res.status==200)
  10.  
    {
  11.  
    this.$message({type: 'success', message: '保存成功!'});
  12.  
    this.CloseWin();
  13.  
    this.GetTabData();
  14.  
    }
  15.  
    else{
  16.  
    this.$message({type: 'error', message: '保存失败!'});
  17.  
    }
  18.  
    })
  19.  
    },
  20.  
     
  21.  

然后在标签中就可以直接展示了:

  1.  
    <el-table-column prop="contentShow" label="培训内容" show-overflow-tooltip>
  2.  
    </el-table-column>

学新通

这里补充一下,还可以直接使用 v-html 具体方法,但是使用这个方法时,需要在如下场景使用里使用,直接在标签上绑定是不可以的,如:

  1.  
    <el-col :span="6" class="dialog-detail-title">新闻标题:</el-col>
  2.  
    <el-col :span="18" class="dialog-detail-content">{{ detailForm.title }}</el-col>
  3.  
    <el-col :span="6" class="dialog-detail-title">新闻内容:</el-col>
  4.  
    <el-col :span="18" class="dialog-detail-content">
  5.  
    <div v-html="detailForm.content"></div>
  6.  
    </el-col>
  7.  
    </el-col>

 学新通

wangEditor4 加字数、空格,光标会跑到最后

问题复现:

学新通

wangEditor在默认情况下,父组件给其设置内容后光标会处于首端,不符合需求。网上找的直接通过js操作的方法经过尝试没有作用(也可能是没写对),官方文档也没找到合适的方法。最终经过一番尝试后成功解决,特此记录,希望能帮到有类似需求的人。

解决:

在父组件与wangEditor通信的双向绑定数据value的watch方法中,增加一句:

this.editor.selection.moveCursor(this.editor.$textElem.elems[0],false);

 本来按照常见思路应该是放在聚焦监听函数onfocus中的,但是放在里面会报错:TypeError: Cannot read property ‘editor’ of undefined。如果放在onchange函数中倒是可以实现,不过会出现,光标先在前段显示,后跳到末尾的情况,总之放到value的watch方法中好。

  1.  
    watch: {
  2.  
    value: function (value) {
  3.  
    if (value !== this.phoneEditor.txt.html()) {
  4.  
    this.phoneEditor.txt.html(this.value) //根据父组件传来的值设置html值
  5.  
    } this.phoneEditor.selection.moveCursor(this.phoneEditor.$textElem.elems[0], false);
  6.  
    }, //value为编辑框输入的内容,这里我监听了一下值,当父组件调用得时候,如果给value赋值了,子组件将会显示父组件赋给的值},
  7.  
    },

 我是直接把上面watch里面的方法改写成如上

学新通

 学新通

本文借鉴:Vue使用富文本quill-editor发送后台数据有标签问题: <p> - 简书 (jianshu.com)

wangEditor中使得光标处于文本末端的方法记录

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfjakik
系列文章
更多 icon
同类精品
更多 icon
继续加载