实现文字(标准、分段)换行

换行文字的保存和输出

在使用textarea文本域时可通过添加换行如下

当我们重新后台拿到保存的数据后发现数据格式如下。

看到数据中的箭头感觉怪怪的,怎么还会有这个玩意,不管怎么样将数据打印出来看看

  created() {
    console.log(
      'start' + '-'.repeat(15),
      this.growthData.teacherComment,
      '-'.repeat(15) + 'end'
    )
  }
复制代码

原来箭头的地方就是换行,而且在打印出来的数据中已经实现了换行的效果。

实现换行

结合上面的结果,我直接将数据丢到标签里

{{growthData.teacherComment}}
复制代码

发现并没有实现换行。 那看到打印台中的数据为什么会有换行的效果,我试了如下代码

/\n/.test(growthData.teacherComment) //true
/\r/.test(growthData.teacherComment) //false
复制代码

原因是在textarea中输入回车换行再存入数据库时,这些回车换行符是以/r/n的形式存入数据库的,取出来也同样,但是到页面时html是无法将/r/n当换行处理的。


换行

在后台从数据库取出数据的时候将/r/n转换成

/**
 * 函数的功能是将 \n,\r用 
替代 * @param {String} str 传入的字符串 * @returns {String} 返回替换后的字符串 */ function replaceWithBr(str) { return str ? str.replace(/\n|\r/g, '
'
) : '' } 复制代码
  • 将字符串中的\n,\r都替换成了'
    '本质上还是字符串,{{}}文本插值插值的方式是无法识别出'
    '是字符串还是换行符。
  • 需要使用v-html按普通 HTML插入
  "replaceWithBr(growthData.teacherComment)">
复制代码

这个 span 的内容将会被替换成为属性值 replaceWithBr(growthData.teacherComment)的返回值

换行和段落效果

文字正常换行和段落换行的间隙是不相同的,来看下图效果。1处表示正常的文字换行,2处表示段落之间的换行。我们需要将两者的差别体现出来。

想法

  • 1处的换行实现有两种方式
    • 文字外部标签如span设置好宽度,当文字宽度超过设置的宽度自动会换行
    • 手动设置一行需要显示字数,超过字数后在后面拼接一个
  • 2处的换行可以在需要换行的文字外部添加

    标签包裹实现段落间距

实现及效果

/**
 * 函数的功能是将 \n 用 p 标签替代
 * @param {String} str  传入的字符串
 * @returns {String} 返回替换后的字符串
*/
export function replaceBreakWithPTag(str, style) {
  if (!str) {
    return ''
  } else {
    style = style || 'style="text-indent: 2em; margin: 10px 0;"'
    str = `

${style}>` + str return str.replace(/\n|\r/g, `

${style}>`) } } 复制代码

需要注意的是如果需要给 p标签添加样式需要在往函数中传入style样式对象,这里我也设置了默认的样式对象。有人会向使用class定义样式可以吗,答案是否定的,原因引用官网的话如下:

在单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局