国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

手把手教你寫vue裁切預覽組件

FreeZinG / 663人閱讀

摘要:版本裁切工具,包含預覽功能最終效果源碼地址第一步先用安裝腳手架不會安裝的看官網初始化第二步創建文件新建里新建,在配置訪問路由具體看源碼最終生成的文件結構如下圖第三步注冊組件引用所有插件導入插件入口文件如果已安裝就跳過注冊插件全

vue版本裁切工具,包含預覽功能

最終效果: https://qiuyaofan.github.io/vue-crop-demo/

源碼地址: https://github.com/qiuyaofan/vue-crop

第一步:先用vue-cli安裝腳手架(不會安裝的看 vue-cli官網)
// 初始化vue-cli
vue init webpack my-plugin
第二步:創建文件
新建src/views/validSlideDemo.vue,

src/components里新建VueCrop/index.js,VueCrop.vue,

在routes/index.js配置訪問路由(具體看github源碼)

最終生成的文件結構如下圖:

第三步:注冊組件
1.引用所有插件:src/components/index.js
// 導入插件入口文件
import VueCrop from "./VueCrop/index.js"
const install = function (Vue, opts = {}) {
  /* 如果已安裝就跳過 */
  if (install.installed) return
  
  // 注冊插件
  Vue.component(VueCrop.name, VueCrop)
}

// 全局情況下注冊插件
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue)
}

export {
  install,
  // 此處是為了兼容在vue內多帶帶引入這個插件,如果是main.js全局引入就可以去掉
  VueCrop
}
2.全局調用插件:src/main.js ( vue plugins官方文檔解說install)
import Vue from "vue"
import App from "./App"
import router from "./router"

// 新加的:導入入口文件
import { install } from "src/components/index.js"

// 全局調用,相當于調用 `MyPlugin.install(Vue)`
Vue.use(install)

Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: "#app",
  router,
  components: { App },
  template: ""
})
3.VueCrop入口文件調用VueCrop.vue:src/components/VueCrop/index.js
// 導入vue
import VueCrop from "./VueCrop.vue"

// Vue.js 的插件應當有一個公開方法 install 。這個方法的第一個參數是 Vue 構造器
VueCrop.install = function (Vue) {
  // 注冊組件
  Vue.component(VueCrop.name, VueCrop)
}

export default VueCrop
小結:我一開始一直有個誤解,以為myPlugin.install是vue的一個方法,其實不是,他只是我們構造plugin識的一個公開方法,可以理解為原生js中的構造函數的方法:
function MyPlugin(){
  console.info("構造函數")
}
MyPlugin.prototype.install=function(vue,options){
    console.info("構造器vue:"+vue);
}

而真正注冊組件的是:Vue.component()

所以,vue插件注冊的過程是:

1.調用main.js中:
import { install } from "src/components/index.js"
vue.use(install)

2.index.js添加install方法,調用Vue.component注冊組件

3.組件內的index.js同所有組件的index.js一樣
第四步:設計開發自己的組件,構建組件結構
在此之前,可以先了解下組件的命名規范等,可參考文章 掘金:Vue前端開發規范,其中第2點有詳細講解

首先,確定自己的調用方式和需要暴露的參數


>

其中,@afterCrop="afterCrop"是裁切完成的回調函數,其他是屬性配置

在組件src/components/VueCrop/VueCrop.vue內,可以用this.$emit("afterCrop")觸發demo里的afterCrop事件

組件結構上,主要分為:裁切主體部分(VueCrop.vue),選框組件(VueCropTool.vue),裁切框寬度、位置坐標等計算(VueCropMove.js),拖拽事件注冊公共js(components/utils/draggable.js)

當前裁切插件的總體思路

裁切插件的裁切主體由圖片,選框,預覽結構組成

選框(VueCropTool.vue)負責拖拽改變其大小,坐標位置等并返回給VueCrop.vue

主體計算數值同步預覽顯示(c-crop--preview)

主體觸發調用頁面(VueCropDemo.vue)的afterCrop事件,從而傳遞參數返回裁切后的url,left,top,bottom,right,x,y,w,h等

備注:此組件不具備真實的裁切功能,最終的裁切是傳遞給后臺去裁,你如果想擴展可以在afterCrop函數里根據坐標等信息進行處理

接下來我們對各個組件和js進行講解

1.draggable.js是參照element里的,修改了一部分,源碼如下
export default function (element, options) {
  const moveFn = function (event) {
    if (options.drag) {
      options.drag(event)
    }
  }
  // mousedown fn
  const downFn = function (event) {
    if (options.start) {
        // 調用參數中start函數
      options.start(event)
    }
  }
  // mouseup fn
  const upFn = function (event) {
    document.removeEventListener("mousemove", moveFn)
    document.removeEventListener("mouseup", upFn)
    document.onselectstart = null
    document.ondragstart = null

    if (options.end) {
        // 調用參數中end函數
      options.end(event)
    }
  }
  // 綁定事件
  element.addEventListener("mousedown", event => {
    if (options.stop && options.stop(event, element) === false) {
      return false
    }
    document.onselectstart = function () {
      return false
    }
    document.ondragstart = function () {
      return false
    }
    document.addEventListener("mousedown", downFn)
    document.addEventListener("mousemove", moveFn)
    document.addEventListener("mouseup", upFn)
  })
}
VueCropTool.vue使用如下
draggable(this.$el.querySelector(".c-crop--drap_screen"), {
    start: (event) => {
      this.startPos = [event.x, event.y]
    },
    drag: (event) => {
      this.handleDragLocation(event)
    },
    end: (event) => {
      this.handleDragLocation(event)
    }
})
2.裁切主體部分(VueCrop.vue全部源碼鏈接)
//script部分


3.裁切框部分(VueCropTool.vue全部源碼鏈接)
//script部分

4.計算裁切框的js(VueCropMove.js全部源碼鏈接)
// 12種形態,四條邊,邊的中點,邊的四個角。e:東,w:西,n:北,s:南,ne:東南以此類推
const movePos = {
  0: e,
  4: e,
  1: s,
  5: s,
  2: w,
  6: w,
  3: n,
  7: n,
  8: ne,
  9: se,
  10: sw,
  11: nw
}
let width, height, result, ratio

// 獲取某種形態類型的寬或高最大值
function getMaxSize (json, startJson, dire, type) {
  if (type === "w") {
    switch (dire) {
      case "e":
      case "s":
      case "n":
      case "ne":
      case "se":
        return json.screen.right - json.l
      case "w":
      case "nw":
      case "sw":
        return startJson.r - json.screen.left
    }
  } else if (type === "h") {
    switch (dire) {
      case "n":
      case "nw":
      case "ne":
        return startJson.b - json.screen.top
      case "s":
      case "w":
      case "e":
      case "sw":
      case "se":
        return json.screen.bottom - startJson.t
    }
  }
}
// 判斷是否有ratio,返回修改后的尺寸
function setRatioSize (type, json, startJson, ratio, width, height) {
  if (ratio) {
    if (width / ratio >= height) {
      var maxHeight = getMaxSize(json, startJson, type, "h")
      height = width / ratio
      if (height > maxHeight) {
        height = maxHeight
        width = height * ratio
      }
    } else {
      var maxWidth = getMaxSize(json, startJson, type, "w")
      width = height * ratio
      if (width > maxWidth) {
        width = maxWidth
        height = width / ratio
      }
    }
  }
  return {
    width: width,
    height: height
  }
}
// 拖拽東邊,高度是不變的,除非有比例拖拽時
function e (_this, json, startJson) {
  ratio = _this.cropJson.r
  width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "e", "w"))
  if (ratio) {
      // 有比例時,計算高度,并對比最大值是否超出
    height = range(width / ratio, getMaxSize(json, startJson, "e", "h"))
    result = setRatioSize("e", json, startJson, ratio, width, height)
    setSize(_this, result)
  } else {
    _this.width = width
  }
  return _this
}

// 拖拽南邊,寬度是不變的,除非有比例拖拽時
function s (_this, json, startJson) {
  ratio = _this.cropJson.r
  height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "s", "h"))
  if (ratio) {
    // 有比例時,計算寬度,并對比最大值是否超出
    width = range(height * ratio, getMaxSize(json, startJson, "s", "w"))
    result = setRatioSize("s", json, startJson, ratio, width, height)
    setSize(_this, result)
  } else {
    _this.height = height
  }

  return _this
}

// 以下同上,以此類推
function w (_this, json, startJson) {
  ratio = _this.cropJson.r
  width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "w", "w"))
  if (ratio) {
    height = range(width / ratio, getMaxSize(json, startJson, "w", "h"))
    result = setRatioSize("w", json, startJson, ratio, width, height)
    setSize(_this, result)
    _this.left = getLeft(_this, json, startJson)
  } else {
    _this.width = width
    _this.left = rangeMax(json.x - json.screen.left, startJson.r)
  }
  return _this
}
function n (_this, json, startJson) {
  ratio = _this.cropJson.r
  height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "n", "h"))
  if (ratio) {
    width = range(height * ratio, getMaxSize(json, startJson, "n", "w"))
    result = setRatioSize("n", json, startJson, ratio, width, height)
    setSize(_this, result)
    _this.top = getTop(_this, json, startJson)
  } else {
    _this.height = height
    _this.top = rangeMax(json.y - json.screen.top, startJson.b)
  }
  return _this
}

function ne (_this, json, startJson) {
  height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "ne", "h"))
  width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "ne", "w"))
  result = setRatioSize("ne", json, startJson, _this.cropJson.r, width, height)
  setSize(_this, result)
  _this.top = getTop(_this, json, startJson)
  return _this
}
function se (_this, json, startJson) {
  height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "se", "h"))
  width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "se", "w"))
  result = setRatioSize("se", json, startJson, _this.cropJson.r, width, height)
  setSize(_this, result)
  return _this
}
function sw (_this, json, startJson) {
  width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "sw", "w"))
  height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "sw", "h"))
  result = setRatioSize("sw", json, startJson, _this.cropJson.r, width, height)
  setSize(_this, result)
  _this.left = getLeft(_this, json, startJson)
  return _this
}
function nw (_this, json, startJson) {
  width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "nw", "w"))
  height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "nw", "h"))
  result = setRatioSize("nw", json, startJson, _this.cropJson.r, width, height)
  setSize(_this, result)
  _this.left = getLeft(_this, json, startJson)
  _this.top = getTop(_this, json, startJson)
  return _this
}

// 匹配范圍
function range (value, max) {
  value = value > max ? max : value
  return value < 20 ? 20 : value
}
// 最大值
function rangeMax (value, max) {
  return value > max ? max : value
}
// top
function getTop (_this, json, startJson) {
  return rangeMax(startJson.b - _this.height - json.screen.top, startJson.b)
}
// left
function getLeft (_this, json, startJson) {
  return rangeMax(startJson.r - _this.width - json.screen.left, startJson.r)
}
// height:只存在于s||n類型
function getHeight (json, startJson, type) {
  return type === "n" ? startJson.b - json.y : json.y - startJson.t
}
// width:只存在于w||e類型
function getWidth (json, startJson, type) {
  return type === "w" ? startJson.r - json.x : json.x - startJson.l
}
// setSize
function setSize (_this, result) {
  _this.width = result.width
  _this.height = result.height
}

export default movePos

今天就分享到這里啦~喜歡這個插件可以去 github star~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94799.html

相關文章

  • 把手你寫 Vue UI 組件庫@vue2.0

    摘要:手把手教你寫組件庫最近在研究的實現,發現網上很少有關于插件具體實現的文章,官方的文檔也只是一筆帶過,對于新手來說并不算友好。 手把手教你寫 Vue UI 組件庫 最近在研究 muse-ui 的實現,發現網上很少有關于 vue 插件具體實現的文章,官方的文檔也只是一筆帶過,對于新手來說并不算友好。 筆者結合官方文檔,與自己的摸索總結,以最簡單的 FlexBox 組件為例子,帶大家入門 v...

    Keagan 評論0 收藏0
  • 把手教你用jsx封裝Vue中的復雜組件(網易云音樂實戰項目需求)

    摘要:終極解決方案所以我們要統一環境,直接使用渲染我們的組件,文檔可以參照音樂標題歌手專輯時長省去一些細節注意需要放在中,的透傳也不要忘了,這樣我們在外部想使用的一些屬性和事件才比較方便。 背景介紹 最近在做vue高仿網易云音樂的項目,在做的過程中發現音樂表格這個組件會被非常多的地方復用,而且需求比較復雜的和靈活。 預覽地址 源碼地址 圖片預覽 歌單詳情 showImg(https://se...

    HitenDev 評論0 收藏0
  • 把手教你擼個vue2.0彈窗組件

    摘要:組件結構同組件結構通過方法獲取元素的大小及其相對于視口的位置,之后對提示信息進行定位。可以用來進行一些復雜帶校驗的彈窗信息展示,也可以只用于簡單信息的展示。可以通過屬性來顯示任意標題,通過屬性來修改顯示區域的寬度。 手把手教你擼個vue2.0彈窗組件 在開始之前需要了解一下開發vue插件的前置知識,推薦先看一下vue官網的插件介紹 預覽地址 http://haogewudi.me/k...

    mrli2016 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<