vue的使用,vue实现聊天功能

  vue的使用,vue实现聊天功能

  这篇文章主要介绍了如何通过某视频剪辑软件实现微博中常见的@人的功能,同时增加鼠标点击事件和一些页面小优化。感兴趣的小伙伴可以跟随小编一起学习一下

  本文采用vue,同时增加鼠标点击事件和一些页面小优化

  基本结构

  新建一个sandBox.vue文件编写功能的基本结构

  div class=内容

  !-文本框-

  差异

  编辑器

  ref=divRef

  内容可编辑

  @keyup=handkeKeyUp

  @keydown=handleKeyDown

  /div

  !-选项-

  AtDialog

  v-if=showDialog

  :visible=showDialog

  :位置=位置

  :queryString=queryString

  @onPickUser=handlePickUser

  @onHide=handleHide

  @onShow=handleShow

  /AtDialog

  /div

  脚本

  从对话框导入./components/AtDialog

  导出默认值{

  名称:"沙箱",

  组件:{ AtDialog },

  data () {

  返回{

  节点: ,//获取到节点

  用户: ,//选中项的内容

  endIndex: ,//光标最后停留位置

  查询字符串: ,//搜索值

  showDialog: false,//是否显示弹窗

  职位:{

  x: 0,

  y: 0

  }//弹窗显示位置

  }

  },

  方法:{

  //获取光标位置

  getCursorIndex () {

  常量选择=窗口。获取选择()

  return selection.focusOffset //选择开始处焦点节点的偏移量

  },

  //获取节点

  getRangeNode () {

  常量选择=窗口。获取选择()

  return selection.focusNode //选择的结束节点

  },

  //弹窗出现的位置

  getRangeRect () {

  常量选择=窗口。获取选择()

  常量范围=选择。getrangeat(0)//是用于管理选择范围的通用对象

  const rect=范围。getclientrects()[0]//择一些文本并将获得所选文本的范围

  const LINE_HEIGHT=30

  返回{

  x: rect.x,

  y:矩形线条高度

  }

  },

  //是否展示@

  showAt () {

  const node=this.getRangeNode()

  如果(!节点 node.nodeType!==节点. TEXT_NODE)返回错误的

  常量内容=节点。文本内容

  const regx=/@([^@\s]*)$/

  常量匹配=regx。执行(内容。slice(0,this.getCursorIndex()))

  返回匹配match.length===2

  },

  //获取@用户

  getAtUser () {

  const content=this.getRangeNode().textContent

  const regx=/@([^@\s]*)$/

  常量匹配=regx。执行(内容。slice(0,this.getCursorIndex()))

  if (match match.length===2) {

  返回匹配[1]

  }

  返回未定义

  },

  //创建标签

  createAtButton(用户){

  常量BTN=文档。createelement(“span”)

  BTN。风格。display= inline-block

  BTN。数据集。用户=JSON。字符串(用户)

  BTN。类名=at-button

  btn.contentEditable=false

  btn.textContent=`@${user.name} `

  const wrapper=文档。createelement(“span”)

  包装纸。风格。display= inline-block

  wrapper.contentEditable=false

  const space elem=文档。createelement(“span”)

  太空元素。风格。空白= pre

  spaceElem.textContent=\u200b

  太空元素。内容可编辑= false

  const clonedSpaceElem=spaceelem。克隆节点(真)

  wrapper.appendChild(spaceElem)

  wrapper.appendChild(btn)

  包装纸。appendchild(克隆空间元素)

  返回包装

  },

  replaceString (raw,replacer) {

  返回raw.replace(/@([^@\s]*)$/,替换者)

  },

  //插入@标签

  替换用户(用户){

  常量节点=this .节点

  如果(节点用户){

  常量内容=节点。文本内容

  const endIndex=this.endIndex

  const pres切片=this。替换字符串(内容。slice(0,endIndex),)

  const rest slice=内容。切片(结束索引)

  const父节点=节点。亲代交点

  const nextNode=node.nextSibling

  const previousTextNode=新文本(前切片)

  const nextTextNode=新文本( \u200b restSlice) //添加0 宽字符

  const at button=this。createatbutton(用户)

  parentNode.removeChild(node)

  //插在文本框中

  if (nextNode) {

  父节点。在前面插入(上一个文本节点,下一个节点)

  父节点。在之前插入(在按钮处,下一个节点)

  父节点。在前面插入(下一个文本节点,下一个节点)

  }否则{

  父节点。appendchild(上一个文本节点)

  父节点。appendchild(在按钮上)

  父节点。appendchild(下一个文本节点)

  }

  //重置光标的位置

  常量范围=新范围()

  常量选择=窗口。获取选择()

  range.setStart(nextTextNode,0)

  range.setEnd(nextTextNode,0)

  selection.removeAllRanges()

  selection.addRange(范围)

  }

  },

  //键盘抬起事件

  handkeKeyUp () {

  if (this.showAt()) {

  const node=this.getRangeNode()

  常数结束索引=this。getcursorindex()

  this.node=节点

  this.endIndex=endIndex

  这个。位置=这个。getrangerect()

  这个。查询字符串=this。getatuser()

  this.showDialog=true

  }否则{

  this.showDialog=false

  }

  },

  //键盘按下事件

  手柄向下键(e) {

  if (this.showDialog) {

  if (e.code===ArrowUp

  e.code===向下箭头

  e.code===Enter) {

  预防默认()

  }

  }

  },

  //插入标签后隐藏选择框

  handlePickUser(用户){

  this.replaceAtUser(用户)

  this.user=用户

  this.showDialog=false

  },

  //隐藏选择框

  handleHide () {

  this.showDialog=false

  },

  //显示选择框

  handleShow () {

  this.showDialog=true

  }

  }

  }

  /脚本

  样式范围的语言=scss 。内容{

  字体系列:无衬线字体;

  h1{

  文本对齐:居中;

  }

  }。编辑{

  边距:0自动;

  宽度:600像素

  高度:150像素

  背景:# fff

  边框:1px纯蓝;

  边框半径:5px

  文本对齐:左对齐;

  填充:10px

  溢出:自动;

  行高:30px

  :焦点{

  大纲:无;

  }

  }

  /风格

  如果添加了点击事件,节点和光标位置获取,需要在【键盘抬起事件】中获取,并保存到数据

  //键盘抬起事件

  handkeKeyUp () {

  if (this.showAt()) {

  常量节点=this。getrangenode()//获取节点

  常数结束索引=this。getcursorindex()//获取光标位置

  this.node=节点

  this.endIndex=endIndex

  这个。位置=这个。getrangerect()

  这个。查询字符串=this。getatuser()

  this.showDialog=true

  }否则{

  this.showDialog=false

  }

  },

  新建一个组件,编辑弹窗选项

  模板

  差异

   class=包装器

  :style={position:fixed ,top:position.y px ,left:position.x px}

  div v-if=! mockList.length class=empty 无搜索结果/div

  差异

  v-for=(item,i) in mockList

  :key=item.id

  class=item

  :class={active: i===index}

  ref=usersRef

  @click=clickAt($event,item)

  @mouseenter=hoverAt(i)

  div class= name"{ item。name } }/div

  /div

  /div

  /模板

  脚本

  const mockData=[

  {名称: HTML ,id: HTML },

  {名称: CSS ,id: CSS },

  {名称: Java ,id: Java },

  {名称: JavaScript ,id: JavaScript }

  ]

  导出默认值{

  名称: AtDialog ,

  道具:{

  可见:布尔型,

  位置:对象,

  查询字符串:字符串

  },

  data () {

  返回{

  用户:[],

  索引:-1,

  模拟列表:模拟数据

  }

  },

  观察:{

  查询字符串(瓦尔){

  瓦尔这个。模拟列表=模拟数据。筛选器(({ name })=名称。以(val))开头:这个。模拟列表=模拟数据。切片(0)

  }

  },

  已安装(){

  文档。addevent侦听器( keyup ,this.keyDownHandler)

  },

  销毁(){

  文档。移除事件侦听器( keyup ,this.keyDownHandler)

  },

  方法:{

  keyDownHandler (e) {

  if (e.code===Escape) {

  这个emit(onHide )

  返回

  }

  //键盘按下=

  if (e.code===ArrowDown) {

  如果(这个。指数=这个。模拟列表。长度-1){

  this.index=0

  }否则{

  this.index=this。索引一

  }

  }

  //键盘按下=

  if (e.code===ArrowUp) {

  if (this.index=0) {

  这个。指数=这个。模拟列表。长度-1

  }否则{

  this.index=this.index - 1

  }

  }

  //键盘按下=回车

  if (e.code===Enter) {

  if (this.mockList.length) {

  const user={

  名称当前位置.姓名,

  id: this.mockList[this.index].编号

  }

  这个发出( onPickUser ,用户)

  这个。索引=-1

  }

  }

  },

  单击(e,项目){

  const user={

  名称:项目名称,

  id:项目。编号

  }

  这个发出( onPickUser ,用户)

  这个。索引=-1

  },

  hoverAt(索引){

  this.index=index

  }

  }

  }

  /脚本

  样式范围的语言=scss 。包装{

  宽度:238像素

  边框:1px实心# e4e 7版;

  边框-半径:4px

  背景色:# fff

  box-shadow:0 2px 12px 0 RGB(0 0 0/10%);

  框大小:边框-框;

  填充:6px 0;

  }。空的

  字体大小:14px

  填充:0 20像素

  颜色:# 999;

  }。项目{

  字体大小:14px

  填充:0 20像素

  行高:34px

  光标:指针;

  颜色:# 606266;活动{

  背景:# f5f 7 fa

  颜色:蓝色;id {

  颜色:蓝色;

  }

  }

  :第一个孩子{

  border-radius:5px 5px 0 0;

  }

  :最后一个孩子{

  边框半径:0 0 5px 5px

  }。id {

  字体大小:12px

  颜色:rgb(83,81,81);

  }

  }

  /风格

  以上就是如何通过某视频剪辑软件实现@人的功能的详细内容,更多关于Vue @人功能的资料请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: