• Home
  • About
    • 知易行难 photo

      知易行难

      front-end developer

    • Learn More
    • Email
    • Github
    • Weibo
  • Posts
    • All Posts
    • All Tags
  • Projects

用vue搭建一个h5网站过程中遇到的问题

12 Dec 2017

Reading time ~1 minute

天空

我最近用vue完成了一个图像识别的h5项目,中间遇到一些坑,在此记录。

vue相关

  • 给img的src动态赋值时,有的时候图片显示不出来。例如这样的代码<img class="goods-img" :src="item.item_info.image.img0">,这里的item.item_info.image.img0是在beforeMount里面拿到的,就是这个原因导致有一些时候图片无法加载出来,要解决这个问题只需把加载数据的代码写到mounted里面就可以了,mounted的生命周期在beforeMount的后面
  • 怎么显示404页面。由于vue可以自己控制路由,路由写错了的话应该会跳到404页面才对,但是我刚开始怎么设置都出不来。在网上搜了下别人的解决方案搬过来。是这么写的{ path: "*", component: pageNotFound },在控制路由的那个js文件里面的routes数组的最底下添加上面的这个路径。这样只有路由找不到就会跳转到默认的pageNotFound页面了
  • 组件里面的css代码怎么才能只在组件内起作用。我是用的sass,只需加一个scoped属性<style lang="sass" scoped>......</style>
  • 由于vue对es6的支持是很友好的,用es6写代码感觉也很爽。但是h5页面在UC浏览器中会有无法识别js代码的问题,因此需要将es6代码转换成es5。当然要是不考虑支持UC的话直接无视这一条。微信和QQ浏览器还有其他浏览器都没有发现这个问题。

cropperjs相关

这个项目需要有选中局部图片并获取到局部坐标和截取局部图片的功能。因此我选择了cropperjs这个截图插件。这个插件功能很强大,看看它github上的api基本就可以上手了。只是在过程中我遇到两个不太好解决的问题。

1.无法成功截取局部图片,具体的问题是Canvas.toDataURL 图片跨域。要解决这个问题需要跟后端的同学商量,图片的url必须要支持跨域。然后在前端代码里加载图片的时候加一个支持跨域的属性img.setAttribute('crossOrigin', 'Anonymous'),具体代码如下:

return new Promise((resolve, reject) => {
	  let img = new Image()
  	  img.setAttribute('crossOrigin', 'Anonymous')
      img.src = url
    let canvas = document.createElement('canvas'),
  	  ctx = canvas.getContext('2d');  
    img.onload = () => {
    	canvas.width = img.width
      canvas.height = img.height
      ctx.drawImage( img, 0, 0 )
      this.image_url = canvas.toDataURL('image/png')
      resolve(true)
    }
})

上面代码把图片加载完成后再动态创建一个canvas,并且把加载完成的图片改成base64,并且把原来的图片地址改成这个base64的值,这样就解决了cropperjs插件无法截取局部图片的问题了。

2.用cropperjs按照{x:x,y:y,width:width,height:height}也就是按照坐标和宽高还有设置了aspectRatio宽高比画出来的框,不能最大化的移动框的位置,只能是移动到一小段距离,然后就无法移动了。我在插件源代码里打印了他的几个数据之后知道只有是设置了宽高比,框的最大值就被写死了,而且这个值不是画布宽高的最大值。知道原因之后,我搜遍了cropperjs的api也没有发现有一个方法可以解决这个问题,于是我只有在它的源代码里增加一个方法,在cropstart里面调用这个方法就可以了。关键代码如下: cropstart部分:

cropstart: function(e){
	_this.cropMoved = true
	if(_this.showOneCropper){
		let data = this.cropper.getCanvasData()
		this.cropper.canMoveRectToMax(data)
		_this.showOneCropper = false
	}
}

canMoveRectToMax部分:

/**
 * can move the rect to max width and height
 * @param {width, height} of CanvasData
 * @returns {Object} this
 */
canMoveRectToMax: function canMoveRectToMax(data) {
  var options = this.options;
  var cropBoxData = this.cropBoxData;

  options.aspectRatio = NaN;

  cropBoxData.maxHeight = data.height
  cropBoxData.maxWidth = data.width

  return this;
},

上面这部分直接写在cropper.js文件里面。也就是在cropper.js里面增加了一个可以使框调整到最大化的方法。

这里有一点小提示,其实只要在new cropper的时候不写宽高比aspectRatio这个参数的时候,画出来的框也是可以随意调整的,可以调整到最大化。但是我这里有一个特殊需求,在一张图片里面我有很多个坐标值,有一些很小值的坐标,假如不设置aspectRatio这个值的话画出来的框就不准了,会有偏移。因此我才会给它增加一个方法来解决。

项目部署相关

关于怎么部署vue项目。 我是用的pm2。 过程中遇到一个问题,每次运行了部署代码之后,页面加载的还是上一次build的前端代码。为了解决这个问题,可以在项目根目录下增加一个启动的脚本,用pm2启动这个脚本就行。脚本代码如下:

[{
 "name":"h5-jiatu",
 "script":"/***/server.js", //启动项目的脚本
 "cwd":"/***/h5",
 "watch":true,
 "watch_options": {
   "usePolling": true
 },
 "env":{
  "NODE_ENV":"production"
 }
}
]

可以用瓦力部署系统,发布代码。

项目线上地址

欢迎访问家图AI智能识图



vuecropperjs Share Tweet +1