vue+element加入签名效果(移动端)

栏目: Html5 · 发布时间: 5年前

内容简介:!------------------------------------------------------------------------------------------! 如有不太明白的地方,多看看代码注释。为细节地方原文地址是组件下载地址,并没有过多介绍

!------------------------------------------------------------------------------------------

下面介绍为了方便就把项目的文件叫作父组件,然后签名的那个组件叫作子组件

! 如有不太明白的地方,多看看代码注释。为细节地方

1. 首先根据element ui 在父组件中设置好diglog弹框,并且在全局样式下,自定义样式

<div class="canva" @click="centerDialogVisible = true">
// click绑定的方法是element提供的 centerDialogVisibe=true  是点击时弹框出现
            <img :src="imgsrc" alt=""/>  // src = base64 ,下面介绍到
</div>
// div是在父组件中,所以有了下面子传给父数据

// 然后设置dialog弹框基本样式
// title为弹框中头部出现的名字
// visible.sync 为click绑定的方法一样
// width为整个dialog的宽度
// <sign></sign>是签名组件,绑定的方法是自定义方法,子传父,后面会详细介绍
<el-dialog
            title="签名"
            :visible.sync="centerDialogVisible"
            width="85%"
            center>
            <sign @draw_save="getSignImg"></sign>
</el-dialog>

//然后在全局样式下自定义弹框中默认的内容高度

.el-dialog {
    .el-dialog__header{
        height: 20px;
    }
    
    .el-dialog__body{
        height: 400px;
        overflow: auto;  // 项目中其他dialog需要滚动条,所以加上就会出现滚动条。签名可忽略
    }
}
.el-dialog__wrapper .el-dialog__title{
    font-size: 21px;
}
复制代码

2. 然后在父组件data中定义centerDialogVisibe=false,imgsrc=''

data(){
    return{
        imgsrc: '', // base64编码,保存为图片用到
        centerDialogVisible: false //dialog弹框显示 fales不显示,true显示
    }
}
复制代码

3. 然后dialog弹框的样式写好之后,就该引入组件了,组件是在网上找的,原文地址如下

原文地址是组件下载地址,并没有过多介绍 download.csdn.net/download/we…

组件为单独组件,通过components引入即可使用,根据项目需求自行配置编写样式。当作子组件引入父组件中。

组件内容如下:

<template>
  <div class="sign">
    <canvas id="canvas" :width="width" :height="height"></canvas>
    <div>
      <button type="button" @click="clear" id="clear">清空</button>
      <button type="button" @click="save" id="save">保存</button>
    </div>
  </div>
</template>

<script>
/*
  * width   canvas 宽度
  * height  canvas 高度
  * strokeStyle  线条颜色
  * showUrl   是否显示预览图片
  * imgWidth  img 宽度
  * imgHeight img 高度
  * draw_clear   //监听清空事件
  * draw_save    //监听保存事件 返回base64 img 路径
  * */
var preHandler = function (e) { e.preventDefault() }
export default {
  name: 'drawSign',
  props: {
    width: {
      type: String,
      default: '565'
    },
    height: {
      type: String,
      default: '355'
    },
    strokeStyle: {
      type: String,
      default: '#000'
    },
    showUrl: {
      type: Boolean,
      default: true
    },
    imgWidth: {
      type: String,
      default: '240'
    },
    imgHeight: {
      type: String,
      default: '106'
    }
  },
  data () {
    return {
      canvas: null, // canvas
      ctx: null, // ctx canvas对象
      stroke_info: null, // 当前绘图的坐标
      url: '' // base64 图像
    }
  },
  methods: {
    init () {
      let that = this
      this.canvas = document.getElementById('canvas')
      this.ctx = this.canvas.getContext('2d')
      this.stroke_info = this.canvas.getBoundingClientRect()
      this.canvas.addEventListener('touchstart', function (event) {
        document.addEventListener('touchStart', preHandler, false)
        that.darwStart(event)
      })
      this.canvas.addEventListener('touchend', function (event) {
        document.addEventListener('touchend', preHandler, false)
        that.drawEnd()
      })
      this.clear()
    },
    darwStart (e) {
      let that = this
      let t = e.changedTouches[0]
      // console.log(t.clientX, t.clientY);
      this.ctx.strokeStyle = this.strokeStyle
      this.ctx.beginPath() // 清空所有绘画路径
      this.ctx.moveTo(t.clientX - this.stroke_info.left, t.clientY - this.stroke_info.top)
      this.canvas.addEventListener('touchmove', function (event) {
        that.darwMove(event)
      })
    },
    darwMove (e) {
      let t = e.changedTouches[0]
      this.ctx.lineTo(t.clientX - this.stroke_info.left, t.clientY - this.stroke_info.top)
      this.ctx.stroke()
    },
    drawEnd () {
      document.removeEventListener('touchstart', preHandler, false)
      document.removeEventListener('touchmove', preHandler, false)
      document.removeEventListener('touchend', preHandler, false)
    },
    clear () {
      this.ctx.clearRect(0, 0, this.width, this.height)
      this.url = ''
      this.$emit('draw_clear')
    },
    save () {
      console.log(this)
      let data = this.canvas.toDataURL()
      // let query = {url: data}
      this.$emit('draw_save', data)  
      // $emit 传data给父组件,当签名签完了之后,会保存图片的,data是base64编码,图片img src直接可识别
      // console.log(this.canvas);
    }
  },

  mounted () {
    this.$nextTick(_ => {
      this.init()
    })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  #clear,#save{
   width:270px;
   height:50px;
   line-height:50px;
   font-size:20px;
   position:absolute;
  }
  #clear{
   bottom:0;
  }
  #save{
   bottom:0;
   right:0;
  }
</style>

复制代码

4. 然后在父组件methods中写方法接收子组件传来的data

// 如上标签中加入的自定义方法
getSignImg (val) {
     //val 是接收子组件的data的
      this.imgsrc = val  // 让签的名变成图片
      this.centerDialogVisible = false 
    }
复制代码

子组件有中带有两个按钮,一个是清除,一个是确定,点击确定时,图片保存到原来需要的位置后,dialog应该关闭,所以加上了element ui 提供的

this.centerDialogVisible = false 
复制代码

就可以点击确定,关闭dialog弹框了

总结:

  1. elemnet ui dailog弹框不要写入 标签内,要写在根元素中,不要被包裹,如下结构可参考
</el-col>
          </el-row>
            <el-dialog
            title="签名"
            :visible.sync="centerDialogVisible"
            width="85%"
            center>
            <sign @draw_save="getSignImg"></sign>
          </el-dialog>
        </div>
复制代码
  1. 想要点击某个元素出现dialog弹框时,就给某个元素加上element提供的点击事件(),然后dialog中的定义(:visible.sync)也必须一致

  2. 在没有引入组件之前,是在父组件中写js代码,因为dialog弹框出现时,弹框里面的dom才会加载,js会立即执行,用了其提供的open方法也不是很理想,js代码总会比dom先执行一步,我也放在定时器中让js缓慢执行,然后清除定时器又成了问题,所以就放弃了这种写法,改为组件引入。

  3. 如果某个元素绑定了element提供的点击事件之后,想又得绑定一个点击事件,那么把提供的方法写在自己的方法中

<div class="canva" @click="isShow">

methods:{
    isShow(){
        this.centerDialogVisible = true
        //...
    }
}
复制代码
  1. 想要改变canvas宽高,画线粗细,画线颜色,画线背景,一定在子组件内props中更改,自定义改会出问题,canvas描线会模糊,有锯齿

  2. 父组件想要子组件中的data,就利用子传父,$emit ,父组件得用子组件的data,保存为图片,子组件就得传出去

然后以上就总结完毕,搜了好多文章,并没有详细的介绍签名效果,有的是需要引入插件,有的是需要写js,有的更是要充某币购买,很是麻烦,然后再这里写上这篇文章,是为了帮助更多的人,也许公司项目刚好也做这个效果呢,这些都有可能。不过还好下载的组件没花钱,花钱买了,怪怪的,免费最好。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Perl入门经典

Perl入门经典

[美]Curtis "Ovid" Poe / 朱允刚、韩雷、叶斌 / 清华大学出版社 / 2013-9-20 / 78.00

作为最有影响力的编程语言之一,Perl被广泛用在Web开发、数据处理和系统管理中。无论是Perl新手,还是想要加强自己实战技能的Perl程序员,《Perl入门经典》都提供了处理日常情况所需的各种技术。凭借十多年的Perl经验,作者Curtis“Ovid”Poe一开始先简单回顾了Perl的基础知识,然后以此为出发点,举例说明了Perl在工作场所中的各种真实用法。此外,书中还包含了一些动手练习、宝贵建......一起来看看 《Perl入门经典》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具