From 3af52f6a984c5fe6671640dbfb1c40540416ea7d Mon Sep 17 00:00:00 2001 From: yangfeng <wanwan926_4@163.com> Date: 星期三, 08 十一月 2023 16:40:51 +0800 Subject: [PATCH] 新建产品增加上传图片功能,增加vue-cropper插件 --- src/main.js | 3 package.json | 1 src/views/productManage/product/IconCropper.vue | 288 +++++++++++++++++++++++++++++++++++++++++ src/views/productManage/product/AddProductDialog.vue | 70 +++------ 4 files changed, 314 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 69f1fc5..5b40fc3 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "element-ui": "^2.15.13", "js-cookie": "^3.0.5", "vue": "^2.6.14", + "vue-cropper": "^0.6.4", "vue-router": "^3.5.1", "vuex": "^3.6.2" }, diff --git a/src/main.js b/src/main.js index 8acc4e8..fdfe8f5 100644 --- a/src/main.js +++ b/src/main.js @@ -15,6 +15,9 @@ ElementUI.Dialog.props.closeOnClickModal.default = false Vue.config.productionTip = false +// 鍥剧墖瑁佸壀 +import VueCropper from "vue-cropper" +Vue.use(VueCropper) new Vue({ router, diff --git a/src/views/productManage/product/AddProductDialog.vue b/src/views/productManage/product/AddProductDialog.vue index 5c63af6..28db941 100644 --- a/src/views/productManage/product/AddProductDialog.vue +++ b/src/views/productManage/product/AddProductDialog.vue @@ -122,6 +122,14 @@ :disabled="!showFooter" ></el-input> </el-form-item> + <el-form-item label="鍥剧墖涓婁紶锛�" prop="imageUrl"> + <IconCropper + :isView="isView" + :image-url="editConfig.infomation.imageSrc" + @getImageData="getImageData" + style="width: 85%" + /> + </el-form-item> </div> <div class="right"> <el-form-item label="閿�鍞环鏍�" prop="salePrice"> @@ -462,11 +470,10 @@ </template> <script> -// import CommonFormTableView from "@/components/makepager/CommonFormTableView" +import IconCropper from "./IconCropper" import { getProductCategoryList } from "@/api/product/productCategory" import { getProductList, addProduct, updateProduct } from "@/api/product/product" -let inputElement = null export default { name: "AddProductDialog", props: { @@ -482,7 +489,7 @@ } } }, - components: {}, + components: { IconCropper }, computed: { modalTitle() { if (this.editConfig.title === "缂栬緫" && this.editConfig.autoEdit) { @@ -542,10 +549,19 @@ ], statisticsMap: { inLibrary: 0 // 鍦ㄥ簱 - } + }, + isView: false } }, created() { + if (this.editConfig.title === "缂栬緫" && !this.editConfig.autoEdit) { + this.isView = true + } + // if (this.editConfig.title === "鏂板缓") { + // this.editConfig.infomation.imageSrc = "" + // } else { + // this.editConfig.infomation.imageSrc = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" + // } this.getProductCategoryList() this.getProductList() this.setTableForm() @@ -712,50 +728,8 @@ this.tableData.splice(scope.$index, 1) }, // 涓婁紶鍥剧墖 - toGetImg() { - if (this.showFooter) { - if (inputElement === null) { - // 鐢熸垚鏂囦欢涓婁紶鐨勬帶浠� - inputElement = document.createElement("input") - inputElement.setAttribute("type", "file") - inputElement.style.display = "none" - if (window.addEventListener) { - inputElement.addEventListener("change", this.uploadFile, false) - } else { - inputElement.attachEvent("onchange", this.uploadFile) - } - document.body.appendChild(inputElement) - } - inputElement.click() - } - }, - uploadFile(el) { - if (el && el.target && el.target.files && el.target.files.length > 0) { - console.log(el) - const files = el.target.files[0] - const isLt2M = files.size / 1024 / 1024 < 2 - const size = files.size / 1024 / 1024 - console.log(size) - // 鍒ゆ柇涓婁紶鏂囦欢鐨勫ぇ灏� - if (!isLt2M) { - this.$message.error("涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 2MB!") - } else if (files.type.indexOf("image") === -1) { - //濡傛灉涓嶆槸鍥剧墖鏍煎紡 - this.$message.error("璇烽�夋嫨鍥剧墖鏂囦欢") - } else { - const that = this - const reader = new FileReader() // 鍒涘缓璇诲彇鏂囦欢瀵硅薄 - reader.readAsDataURL(el.target.files[0]) // 鍙戣捣寮傛璇锋眰锛岃鍙栨枃浠� - reader.onload = function () { - // 璇诲彇瀹屾垚鍚庯紝灏嗙粨鏋滆祴鍊肩粰img鐨剆rc - that.imageSrc = this.result - console.log(this.result) - // 鏁版嵁浼犲埌鍚庡彴 - //const formData = new FormData() - //formData.append('file', files); // 鍙互浼犲埌鍚庡彴鐨勬暟鎹� - } - } - } + getImageData(data) { + console.log(data, "鍥剧墖鏁版嵁") }, // 杩涘嚭鐐瑰嚮 inOutBoundClick() { diff --git a/src/views/productManage/product/IconCropper.vue b/src/views/productManage/product/IconCropper.vue new file mode 100644 index 0000000..4a2cf7c --- /dev/null +++ b/src/views/productManage/product/IconCropper.vue @@ -0,0 +1,288 @@ +<template> + <div class="cropper-wrapper"> + <div v-if="isView"> + <el-image :src="imageUrl" class="view-image"> + <div slot="error" class="image-slot"> + <i class="el-icon-picture-outline"></i> + </div> + </el-image> + </div> + <div v-else> + <template v-if="!isPreview"> + <!-- element 涓婁紶鍥剧墖鎸夐挳 --> + <el-upload + class="avatar-uploader" + action="" + drag + :auto-upload="false" + :show-file-list="false" + :on-change="handleChangeUpload" + > + <i class="el-icon-plus avatar-uploader-icon"></i> + </el-upload> + </template> + <div class="pre-box" v-else> + <el-image :src="previewImg" alt="" class="view-image" /> + <el-upload + class="upload-demo" + action="" + :auto-upload="false" + :show-file-list="false" + :on-change="handleChangeUpload" + > + <el-button v-if="!isView" type="primary" plain>鏇存崲鍥剧墖</el-button> + </el-upload> + </div> + </div> + <!-- vueCropper 鍓鍥剧墖瀹炵幇--> + <el-dialog title="鍥剧墖鍓" :visible.sync="dialogVisible" class="crop-dialog" append-to-body> + <div class="cropper-content"> + <div class="cropper" style="text-align: center"> + <vueCropper + ref="cropper" + :img="option.img" + :outputSize="option.size" + :outputType="option.outputType" + :info="true" + :full="option.full" + :canMove="option.canMove" + :canMoveBox="option.canMoveBox" + :original="option.original" + :autoCrop="option.autoCrop" + :fixed="option.fixed" + :fixedNumber="option.fixedNumber" + :centerBox="option.centerBox" + :infoTrue="option.infoTrue" + :fixedBox="option.fixedBox" + :autoCropWidth="option.autoCropWidth" + :autoCropHeight="option.autoCropHeight" + @cropMoving="cropMoving" + /> + </div> + </div> + <div class="action-box"> + <el-upload + class="upload-demo" + action="" + :auto-upload="false" + :show-file-list="false" + :on-change="handleChangeUpload" + > + <el-button type="primary" plain>鏇存崲鍥剧墖</el-button> + </el-upload> + <el-button type="primary" plain @click="clearImgHandle">娓呴櫎鍥剧墖</el-button> + <el-button type="primary" plain @click="rotateLeftHandle">宸︽棆杞�</el-button> + <el-button type="primary" plain @click="rotateRightHandle">鍙虫棆杞�</el-button> + <el-button type="primary" plain @click="changeScaleHandle(1)">鏀惧ぇ</el-button> + <el-button type="primary" plain @click="changeScaleHandle(-1)">缂╁皬</el-button> + <el-button type="primary" plain @click="downloadHandle('blob')">涓嬭浇</el-button> + </div> + <div slot="footer" class="dialog-footer"> + <el-button @click="dialogVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="finish" :loading="loading">纭</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +export default { + name: "CropperV", + props: { + isView: { + type: Boolean, + default: false + }, + imageUrl: { + type: String, + default: "" + } + }, + data() { + return { + isPreview: false, + dialogVisible: false, + previewImg: "", // 棰勮鍥剧墖鍦板潃 + // 瑁佸壀缁勪欢鐨勫熀纭�閰嶇疆option + option: { + img: "https://pic1.zhimg.com/80/v2-366c0aeae2b4050fa2fcbfc09c74aad4_720w.jpg", // 瑁佸壀鍥剧墖鐨勫湴鍧� + info: true, // 瑁佸壀妗嗙殑澶у皬淇℃伅 + outputSize: 1, // 瑁佸壀鐢熸垚鍥剧墖鐨勮川閲� + outputType: "png", // 瑁佸壀鐢熸垚鍥剧墖鐨勬牸寮� + canScale: true, // 鍥剧墖鏄惁鍏佽婊氳疆缂╂斁 + autoCrop: true, // 鏄惁榛樿鐢熸垚鎴浘妗� + canMoveBox: true, // 鎴浘妗嗚兘鍚︽嫋鍔� + autoCropWidth: 200, // 榛樿鐢熸垚鎴浘妗嗗搴� + autoCropHeight: 200, // 榛樿鐢熸垚鎴浘妗嗛珮搴� + fixedBox: false, // 鍥哄畾鎴浘妗嗗ぇ灏� 涓嶅厑璁告敼鍙� + fixed: true, // 鏄惁寮�鍚埅鍥炬瀹介珮鍥哄畾姣斾緥 + fixedNumber: [1, 1], // 鎴浘妗嗙殑瀹介珮姣斾緥 + full: false, // 鏄惁杈撳嚭鍘熷浘姣斾緥鐨勬埅鍥� + original: false, // 涓婁紶鍥剧墖鎸夌収鍘熷姣斾緥娓叉煋 + centerBox: false, // 鎴浘妗嗘槸鍚﹁闄愬埗鍦ㄥ浘鐗囬噷闈� + infoTrue: true // true 涓哄睍绀虹湡瀹炶緭鍑哄浘鐗囧楂� false 灞曠ず鐪嬪埌鐨勬埅鍥炬瀹介珮 + }, + // 闃叉閲嶅鎻愪氦 + loading: false + } + }, + mounted() { + console.log(this.imageUrl) + if (!this.isView && this.imageUrl?.length > 0) { + this.isPreview = true + this.previewImg = this.imageUrl + } else { + this.isPreview = false + } + }, + methods: { + // 涓婁紶鎸夐挳 闄愬埗鍥剧墖澶у皬鍜岀被鍨� + handleChangeUpload(file, fileList) { + const isJPG = file.raw.type === "image/jpeg" || file.raw.type === "image/png" + const isLt2M = file.size / 1024 / 1024 < 2 + if (!isJPG) { + this.$message.error("涓婁紶澶村儚鍥剧墖鍙兘鏄� JPG/PNG 鏍煎紡!") + return false + } + if (!isLt2M) { + this.$message.error("涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 2MB!") + return false + } + console.log(file, fileList) + // 涓婁紶鎴愬姛鍚庡皢鍥剧墖鍦板潃璧嬪�肩粰瑁佸壀妗嗘樉绀哄浘鐗� + this.$nextTick(async () => { + // base64鏂瑰紡 + // this.option.img = await fileByBase64(file.raw) + this.option.img = URL.createObjectURL(file.raw) + this.loading = false + this.dialogVisible = true + }) + }, + // 鏀惧ぇ/缂╁皬 + changeScaleHandle(num) { + num = num || 1 + this.$refs.cropper.changeScale(num) + }, + // 宸︽棆杞� + rotateLeftHandle() { + this.$refs.cropper.rotateLeft() + }, + // 鍙虫棆杞� + rotateRightHandle() { + this.$refs.cropper.rotateRight() + }, + // 涓嬭浇 + downloadHandle(type) { + let aLink = document.createElement("a") + aLink.download = "author-img" + if (type === "blob") { + this.$refs.cropper.getCropBlob((data) => { + aLink.href = URL.createObjectURL(data) + aLink.click() + }) + } else { + this.$refs.cropper.getCropData((data) => { + aLink.href = data + aLink.click() + }) + } + }, + // 娓呯悊鍥剧墖 + clearImgHandle() { + this.option.img = "" + }, + // 鎴浘妗嗙Щ鍔ㄥ洖璋冨嚱鏁� + cropMoving(data) { + console.log(data) + // 鎴浘妗嗙殑宸︿笂瑙� x锛寉鍜屽彸涓嬭鍧愭爣x锛寉 + // let cropAxis = [data.axis.x1, data.axis.y1, data.axis.x2, data.axis.y2] + // console.log(cropAxis) + }, + finish() { + // 鑾峰彇鎴浘鐨� blob 鏁版嵁 + this.$refs.cropper.getCropBlob((blob) => { + this.loading = true + this.dialogVisible = false + this.previewImg = URL.createObjectURL(blob) + this.isPreview = true + console.log(blob) + this.$emit("getImageData", blob) + }) + // 鑾峰彇鎴浘鐨� base64 鏁版嵁 + // this.$refs.cropper.getCropData(data => { + // console.log(data) + // }) + } + } +} +</script> + +<style lang="scss" scoped> +.cropper-wrapper { + .avatar-uploader .el-upload:hover { + border-color: #409eff; + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 178px; + height: 178px; + line-height: 178px; + text-align: center; + } + .avatar { + width: 178px; + height: 178px; + display: block; + } + .view-image { + width: 180px; + height: 180px; + background: #f5f7fa; + font-size: 30px; + text-align: center; + line-height: 180px; + } + .image-slot { + color: #909399; + text-align: center; + } +} +::v-deep { + .el-upload-dragger { + width: 180px; + height: 180px; + } +} +.avatar-uploader .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + overflow: hidden; + width: 178px; + height: 178px; +} + +.crop-dialog { + .cropper-content { + padding: 0 40px; + + .cropper { + width: auto; + height: 350px; + } + } + + .action-box { + padding: 25px 40px 10px; + display: flex; + justify-content: center; + + button { + width: 80px; + margin-right: 15px; + } + } +} +</style> -- Gitblit v1.8.0