精华内容
下载资源
问答
  • vue上传图片组件

    千次阅读 2019-08-21 15:03:34
    上传图片组件也是后台管理系统的最重要的基础组件之一,这里功能支持图片文件类型检验,图片大小检验,图片分辨率校验以及图片比列校验等功能。 主要依赖说明 { "element-ui": "2.11.1", "vue": "^2.6.10", ...

    上传图片组件

    简介

    上传图片组件也是后台管理系统的最重要的基础组件之一,这里功能支持图片文件类型检验,图片大小检验,图片分辨率校验以及图片比列校验等功能。

    主要依赖说明 (先安装,步骤略)

     {
        "element-ui": "2.11.1",  
        "vue": "^2.6.10",
        "vue-router": "^3.0.1"
     }
    

    正文

    1.组件

    src/components/Upload.vue

    <template>
      <div class="custom-upload">
        <input
          :id="id"
          type="file"
          style="display: none"
          name="single"
          accept="image/*"
          @change="onChange"
        />
        <el-button size="small" type="primary" :loading="loading" @click="handleOpenFile">
          <i class="fa fa-upload" />
          添加图片
        </el-button>
        <div v-if="tips" class="tips clear-margin-top">{{ tips }}</div>
      </div>
    </template>
    
    <script>
    // 上传文件组件
    import {
      isAppropriateResolution,
      isAppRatio,
      isImageFile,
      isMaxFileSize
    } from '@/utils/upload'    // upload.js 文件见下文
    
    // 定义的接口根据自己项目更换
    import { uploadImage } from '@/api/upload'  
    
    import { Message } from 'element-ui'
    
    export default {
      name:'Upload',
      props: {
        // 最大上传文件的大小 单位(MB)
        maxFileSize: {
          type: Number,
          default: 2
        },
        // 提示内容
        tips: {
          type: String
        },
        // 图片文件分辨率的宽度
        width: {
          type: Number,
          width: 460
        },
        // 图片文件分辨率的高度
        height: {
          type: Number,
          default: 300
        },
        // 是否限制分辨率
        isResolution: {
          type: Boolean,
          default: false
        },
        // 是否限制比列
        isRatio: {
          type: Boolean,
          default: false
        },
        // 比列 ag: 1:1 时给 [1,1]
        ratio: {
          type: Array
        }
      },
      data() {
        return {
          id: 'upload-input-' + +new Date(),
          loading: false
        }
      },
    
      methods: {
        // 打开文件
        handleOpenFile() {
          const input = document.getElementById(this.id)
          // 解决同一个文件不能监听的问题
          input.addEventListener(
            'click',
            function() {
              this.value = ''
            },
            false
          )
          // 点击input
          input.click()
        },
    
        // 选择好文件
        async onChange($event) {
          this.loading = true
          const file = $event.target.files[0]
          if (!file) {
            this.loading = false
            return Message.error('选择图片失败')
          }
    
          // 限制为图片文件
          if (!isImageFile(file)) {
            this.loading = false
            return
          }
    
          // 限制文件上传大小
          if (!isMaxFileSize(file, this.maxFileSize)) {
            this.loading = false
            return
          }
    
          try {
            // 限制分辨率
            if (this.width !== 0 && this.height !== 0 && this.isResolution) {
              await isAppropriateResolution(file, {
                width: this.width,
                height: this.height
              })
            }
    
            // 限制比列
            if (this.isRatio && this.ratio && this.ratio.length === 2) {
              await isAppRatio(file, this.ratio)
            }
            // 开始上传
            this.upload(file)
          } catch (error) {
            Message.error(error.message || '上传失败')
            console.log(error)
            this.loading = false
          }
        },
    
        // 自定义上传
        async upload(file) {
          try {
            const res = await uploadImage(file)
            this.$emit('subUploadSucceed', res)
            Message.success('上传成功')
            this.loading = false
          } catch (error) {
            this.loading = false
            console.log(error)
            Message.error(error.message || '上传失败')
          }
        }
      }
    }
    </script>
    
    <style lang="scss"  scoped >
    .custom-upload {
      .tips {
        margin-top: 10px;
        color: red;
        font-size: 12px;
      }
      .clear-margin-top {
        margin-top: 0;
      }
    }
    </style>
    
    

    2.使用

    <template>
      <div>
        <app-upload
          tips="请上传720*294的图片"
          :is-resolution="true"
          :width="720"
          :height="294"
          @subUploadSucceed="handleUploadSucceed"
        />
        <img v-if="url" :src="url" class="image-size" />
      </div>
    </template>
    
    <script>
    import AppUpload from '@/components/Upload'
    export default {
      name: 'Banner',
      components: {
        AppUpload
      },
      data() {
        return {
          url: ''
        }
      },
      methods: {
        // 海报上传成功
        handleUploadSucceed(url) {
          this.url = url
        }
      }
    }
    </script>
    
    <style rel="stylesheet/scss" lang="scss" scoped>
    .image-size {
      margin-top: 10px;
      width: 150px;
      height: 92px;
      cursor: pointer;
    }
    </style>
    

    3.补充src/utils/upload.js 文件

    import { Message } from 'element-ui'
    
    /**
     *
     * @param {file} file 源文件
     * @desc 限制为图片文件
     * @retutn 是图片文件返回true否则返回false
     */
    export const isImageFile = (file,fileTypes) => {
      const types =fileTypes|| [
        'image/png',
        'image/gif',
        'image/jpeg',
        'image/jpg',
        'image/bmp',
        'image/x-icon'
      ]
      const isImage = types.includes(file.type)
      if (!isImage) {
        Message.error('上传文件非图片格式!')
        return false
      }
    
      return true
    }
    
    /**
     *
     * @param {file} file 源文件
     * @param {number} fileMaxSize  图片限制大小单位(MB)
     * @desc 限制为文件上传大小
     * @retutn 在限制内返回true否则返回false
     */
    export const isMaxFileSize = (file, fileMaxSize = 2) => {
      const isMaxSize = file.size / 1024 / 1024 < fileMaxSize
      if (!isMaxSize) {
        Message.error('上传头像图片大小不能超过 ' + fileMaxSize + 'MB!')
        return false
      }
      return true
    }
    
    /**
     *
     * @param {file} file 源文件
     * @desc 读取图片文件为base64文件格式
     * @retutn 返回base64文件
     */
    export const readFile = file => {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = e => {
          const data = e.target.result
          resolve(data)
        }
        reader.onerror = () => {
          const err = new Error('读取图片失败')
          reject(err.message)
        }
    
        reader.readAsDataURL(file)
      })
    }
    
    /**
     *
     * @param {string} src  图片地址
     * @desc 加载真实图片
     * @return 读取成功返回图片真实宽高对象 ag: {width:100,height:100}
     */
    export const loadImage = src => {
      return new Promise((resolve, reject) => {
        const image = new Image()
        image.src = src
        image.onload = () => {
          const data = {
            width: image.width,
            height: image.height
          }
          resolve(data)
        }
        image.onerror = () => {
          const err = new Error('加载图片失败')
          reject(err)
        }
      })
    }
    
    /**
     *
     * @param {file} file 源文件
     * @param {object} props   文件分辨率的宽和高   ag: props={width:100, height :100}
     * @desc  判断图片文件的分辨率是否在限定范围之内
     * @throw  分辨率不在限定范围之内则抛出异常
     *
     */
    export const isAppropriateResolution = async(file, props) => {
      try {
        const { width, height } = props
        const base64 = await readFile(file)
        const image = await loadImage(base64)
        if (image.width !== width || image.height !== height) {
          throw new Error('上传图片的分辨率必须为' + width + '*' + height)
        }
      } catch (error) {
        throw error
      }
    }
    
    /**
     *
     * @param {file} file 源文件
     * @param {array} ratio   限制的文件比例 ag:  ratio= [1,1]
     * @desc 判断图片文件的比列是否在限定范围
     * @throw  比例不在限定范围之内则抛出异常
     */
    export const isAppRatio = async(file, ratio) => {
      try {
        const [w, h] = ratio
        if (h === 0 || w === 0) {
          const err = '上传图片的比例不能出现0'
          Message.error(err)
          throw new Error(err)
        }
        const base64 = await readFile(file)
        const image = await loadImage(base64)
        if (image.width / image.height !== w / h) {
          throw new Error('上传图片的宽高比例必须为 ' + w + ' : ' + h)
        }
      } catch (error) {
        throw error
      }
    }
    
    
    展开全文
  • 加上后台要求要传递小于2M的图片,因此封装了一个upload.vue组件作为上传页面的子组件,它用于管理图片上传逻辑。 upload.vue解析 upload主要用于实现表单上传图片的需求,主要由input +img 构成当没有图片的时候...
  • 首先实现递归checkbox的组件假定,我们要实现的权限组件效果是这样的:要实现点击系统,下面的都全选,点击基础功能,用户管理半选,系统半选。点击新增组织,如果基础功能没有选中,则基础功能改为选中。0":class=...

    首先实现递归checkbox的组件

    假定,我们要实现的权限组件效果是这样的:

    要实现点击系统,下面的都全选,点击基础功能,用户管理半选,系统半选。点击新增组织,如果基础功能没有选中,则基础功能改为选中。

    0" :class="{'top_check':datas.parentId==0}">

    {{datas.title}}

    {{datas.title}}

    0">

    基础功能

    0" @pchange="permitCheck" :key="d.id">

    {{d.title}}

    export default{

    name:"permitnode",

    props:{

    datas:{

    type:Object,

    default:{}

    }

    },

    data(){

    return {

    isIndeterminate:false,

    childClick:true,

    based:true

    };

    },

    mounted(){

    this.based=this.datas.checkState;

    let count=0;

    //初始化时判断自身时全选还是半选

    this.datas.childResoList.forEach(it=>{

    if(it.checkState){

    count++;

    }

    });

    if(count>0&&count

    this.isIndeterminate=true;

    this.datas.indeter=true;

    }

    if(count==0){

    this.isIndeterminate=false;

    this.datas.indeter=false;

    }

    if(count==this.datas.childResoList.length){

    this.isIndeterminate=false;

    this.datas.indeter=false;

    }

    },

    //watch是监听数据的变化,所以change引起树的下级变化,

    //下级变化调用leafcheck方法改变上层数据时,上层数据的值没有变,所以不会死循环

    watch:{

    "datas.checkState":function(val){

    //如果是半选状态,则表明是由子组件引起的变化,不进行全选操作

    if(this.datas.indeter==true){

    return ;

    }

    //递归watch过来时,取消本身的半选状态。

    this.isIndeterminate=false;

    this.based=val;

    //遍历全选子组件数据,子组件watch到变化全选算子组件

    for(let i=0;i

    let tmp=this.datas.childResoList[i];

    tmp.checkState=this.datas.checkState?true:false;

    if(tmp.childResoList&&tmp.childResoList.length>0){

    tmp.indeter=false;

    //全选时改变半选状态

    }

    this.datas.childResoList.splice(i,1,tmp);

    }

    }

    },

    methods:{

    handleCheckAllChange(val){

    //点击上面的全选按钮时,改变全选状态,出发watch变化

    this.isIndeterminate=false;//取消自身的半选状态

    this.datas.indeter=false;

    //向上触发事件,改变上层checkbox的变化

    this.$emit("pchange");

    },

    //子组件变化时触发的pchange事件

    permitCheck(){

    this.leafcheck();

    },

    //基础权限选中,则父权限选中,基础权限取消,则全部取消选中。

    basecheck(){

    if(this.based==false){

    this.datas.checkState=false;

    this.isIndeterminate=false;

    this.datas.indeter=false;

    }else{

    this.datas.checkState=true;

    this.isIndeterminate=true;

    this.datas.indeter=true;

    }

    this.$emit("pchange");

    },

    //叶子checkebox变化时,包括子组件变化

    leafcheck(val){

    let count=0;

    let hasIndeter=false;

    //计算选中的数值,是不是达成了全选的状态

    this.datas.childResoList.forEach(it=>{

    if(it.checkState){

    //判断其中是否有半选的

    if(it.indeter!=undefined){

    if(it.indeter==true){

    hasIndeter=true;

    }

    }

    count++;

    }

    });

    //parentId!=0不是第一级权限

    if(this.datas.parentId!=0){

    if(val&&this.based==false){

    this.based=true;

    this.datas.checkState=true;

    }

    //当checkbox选中时,这时候based必为true

    if(count

    //this.datas.checkState=true;

    //indeter用来表示数据是否是显示为半选状态

    this.datas.indeter=true;

    this.isIndeterminate=true;

    }else{

    if(hasIndeter){

    this.datas.indeter=true;

    this.isIndeterminate=true;

    }else{

    this.datas.indeter=false;

    this.isIndeterminate=false;

    }

    }

    }else{

    console.log("count:"+count);

    if(count>0&&count

    this.datas.indeter=true;

    this.isIndeterminate=true;

    this.datas.checkState=true;

    //indeter用来表示数据是否是显示为半选状态

    }

    //基础权限也没选中时

    if(count==0){

    this.datas.indeter=false;

    this.isIndeterminate=false;

    this.datas.checkState=false;

    }

    //因为选中和半选都是选中状态,所以要做一下半选显示状态的区分

    //全部选中,且没有半选显示状态的。

    if(count==this.datas.childResoList.length&&hasIndeter==false){

    this.datas.indeter=false;

    this.isIndeterminate=false;

    this.datas.checkState=true;

    }

    //全部选中,但是有是半选显示状态的

    if(count==this.datas.childResoList.length&&hasIndeter==true){

    this.datas.indeter=true;

    this.isIndeterminate=true;

    this.datas.checkState=true;

    }

    }

    //向上层反馈变化

    this.$emit("pchange");

    }

    }

    }

    .permit_cont{color:#fff;font-size:12px;line-height: 2;}

    .permit_hr{border-bottom: 1px solid #2F3B52;margin:10px 0;}

    .top_check{margin-bottom:20px;}

    之后需要在这个组件外面套一层组件,提供一个方法来获取选中的checkbox

    import permitNode from '@/components/public/permit_node'

    export default{

    props:{

    chess:{

    type:Array,

    default:[]

    },

    rootId:{

    type:Number,

    defualt:0

    }

    },

    components:{

    permitNode

    },

    data(){

    return {

    };

    },

    methods:{

    //遍历获取树型数据中选中的checkbox的id

    getCheckedKey(){

    let arr=[];

    let keyarr=this.getCheckedByCircle(this.chess,arr);

    return keyarr;

    },

    getCheckedByCircle(keys,arr){

    for(let i=0;i

    let tmp=keys[i];

    if(tmp.checkState){

    arr.push(tmp.id);

    }

    if(tmp.childResoList.length>0){

    this.getCheckedByCircle(tmp.childResoList,arr);

    }

    }

    return arr;

    }

    }

    }

    第二个组件上面的v-for是因为权限要像tab页签一样分多个模块,根据模块的选中状态展现不同的权限选项。

    展开全文
  • vue+elementUi做的图片上传组件

    千次阅读 2019-01-07 19:15:19
    加上后台要求要传递小于2M的图片,因此封装了一个upload.vue组件作为上传页面的子组件,它用于管理图片上传逻辑。 upload.vue解析 upload主要用于实现表单上传图片的需求,主要由input +img 构成当没有图片的时候...

    上传组件封装需求分析

    在基于elementUI库做的商城后台管理中,需求最大的是商品管理表单这块,因为需要录入各种各样的商品图片信息。加上后台要求要传递小于2M的图片,因此封装了一个upload.vue组件作为上传页面的子组件,它用于管理图片上传逻辑。

    upload.vue解析

    upload主要用于实现表单上传图片的需求,主要由input +img 构成当没有图片的时候显示默认图片,有图片则显示上传图片,因为input样式不太符合需求所以只是将起设置为不可见,不能将其设置为display:none。否则将将无法触发input的change事件

    upload.vue代码如下:

    <template>
    	<div>
    		<div class="upload-box" :style="imgStyle">
    			 <!-- 用户改变图片按钮的点击 触发上传图片事件  -->
    			<input type="file" :ref="imgType$1"   @change="upload(formVal$1,imgType$1)" class="upload-input" />
    			<!-- img 的 src 用于渲染一个 图片路径  传入图片路径 渲染出图片  -->
    			<img :src="formVal$1[imgType$1]?formVal$1[imgType$1]:'static/img/upload.jpg'" />
    		</div>
    	</div>
    </template>
    <script>
    /* 
      该组件因为要上传多个属性的图片  主图(mainImg) 详细图(detailImg)  规格图 (plusImg)  
    	该组件基于压缩插件lrz,所以下方打入该组件
    	npm install lrz --save 即可
    */
    import lrz from 'lrz';
    export default {
        name: 'uploadImg', //组件名字
        props: {
            formVal: {
                type: Object, //props接受对象类型数据(表单对象也可以是纯对象类型)
                required: true,
                default: {}
            },
            imgType: {                //表单对象中的图片属性 example:mainImg
                type: String,
                required: true,
                default: ''
            },
            imgStyle: {
                type: Object,        //  用于显示的图片的样式 
                required: true //必须传递
            }
        },
        created: function() {
            //生命周期函数 
        },
        data: function() {
          /*
             因为该组件需要改变父组件传递过来的值,
             所以将起拷贝一份
          */
            let formVal$1 = this.formVal;
            let imgType$1 = this.imgType;
            return {
                formVal$1,
                imgType$1,
                uploadUrl: url,//你的服务器url地址
            };
        },
        methods: {
            upload: function(formVal, imgType) {
                var self = this;
                //图片上传加载我们在这里加入提示,下方需要主动关闭,防止页面卡死
                var loadingInstance = this.$loading({
                    text: '上传中'
                });
                var that = this.$refs[imgType].files[0]; //文件压缩file
                //图片上传路径
                var testUrl = this.uploadUrl; //图片上传路径
                try {
                    //lrz用法和上一个一样也是一个压缩插件来的
                    lrz(that)
                        .then(function(message) {
                            var formData = message.formData; //压缩之后我们拿到相应的formData上传
                            self.$axios
                                .post(testUrl, formData)
                                .then(function(res) {
                                    console.log(res);
                                    if (res && res.data.iRet == 0) {
                                        formVal[imgType] = res.data.objData.sUrl;
                                        //上传成功之后清掉数据防止下次传相同图片的时候不触发change事件 
                                        self.$refs[imgType].value = '';
                                        /*
    	                                    这里因为使用elementUI中的表单验证,
    	                                    当上传图片完成之后还会提示没有上传图片
    	                                    所以需要通知父组件清除该验证标记 
                                         */
                                        self.$emit('clearValidate', imgType);
                                        self.$nextTick(() => {
                                            // 以服务的方式调用的 Loading 需要异步关闭
                                            loadingInstance.close();
                                        });
                                    } else {
                                        throw res.data.sMsg;
                                    }
                                })
                                .catch(function(err) {
                                    self.$nextTick(() => {
                                        // 以服务的方式调用的 Loading 需要异步关闭
                                        loadingInstance.close();
                                    });
                                    //接口报错弹出提示
                                    alert(err);
                                });
                        })
                        .catch(function(err) {
                            self.$nextTick(() => {
                                loadingInstance.close();
                            });
                        });
                } catch (e) {
                    //关闭加载动画实例
                    self.$nextTick(() => {
                        loadingInstance.close();
                    });
                }
            }
        },
        mounted: function() {},
        watch: {
           /*
            这里需要注意当父组件上传一个图片然后通过重置按钮重置的时候.
             我们需要监听一下,防止上传同一张图片上传失败
            */
            formVal: {
                handle: function(newVal, oldVal) {
                    var imgType = this.imgType;
                    if (newVal[imgType] == '') {
                       //这里使用了原生js写法当然也可以通过ref引用找到,后者更好
                        document.getElementsByClassName('upload-input')[0].value = '';
                    }
                }
            }
        }
    };
    </script>
    <style scoped>
    /*
     这里是默认的设置图片的尺寸。可以通过父组件传值将其覆盖
    */
    .upload-box {
        position: relative;
        height: 100px;
        width: 100px;
        overflow: hidden;
    }
    
    .upload-box img {
        width: 100%;
        height: 100%;
    }
    
    .upload-box .upload-input {
        position: absolute;
        left: 0;
        opacity: 0;
        width: 100%;
        height: 100%;
    }
    </style>
    
    

    商品页中使用upload组件

    good.vue中我们引入upload组件。并且传递相应表单对象,需上传的图片类型的属性,以及图片显示样式给子组件

    good.vue核心代码:

    <template>
       <el-form ref="form" :model="form" label-width="80px" label-position="top" :rules="rules">
       	<!-- 无关代码略 -->
       	<el-form-item label="详情图" prop="sDetailImg" ref="sDetailImg">
       		<uploadImg :form-val="form" :img-type="'sDetailImg'" :img-style="detailImgStl" @clearValidate="clearValidate"></uploadImg>
       	</el-form-item>
       	<el-form-item>
       		<el-row style="text-align:center;">
       			<el-button type="primary" size="medium" @click.stop="submit('form')" v-if="!form.ID">保存</el-button>
       			<el-button type="primary" size="medium" @click.stop="submit('form')" v-else-if="form.ID">修改</el-button>
       			<el-button size="medium" @click.stop="resetForm('form')">重置</el-button>
       		</el-row>
       	</el-form-item>
       </el-form>
       <!--  略 -->
    </template>
    <script>
       import uploadImg from "../common/uploadImg"; //图片上传
       export default {
       	name: "good", //组件名字用户缓存 
       	data: function() {
       		return {
       			form: {
       				ID: NULL,
       				//其他字段略
       				sDetailImg: "" //商品详细图
       			},
       			detailImgStl: {
       				width: "350px",
       				height: "150px"
       			},
       			rules: {
       				sDetailImg: [{
       					required: true,
       					message: "请填写详细图信息",
       					trigger: "change"
       				}],
       			}
       		}
       	},
       	methods: {
       		//这里监听子组件回写的信息,用户清除上传成功之后还显示图片未上传的bug
       		clearValidate: function(imgName) {
       			//清空图片上传成功提示图片没有上传的验证字段
       			this.$refs[imgName].clearValidate();
       		},
       		//重置表单
       		resetForm: function(formName) {
       			this.confirm("确认重置表单", function(self) {
       				self.$refs[formName].resetFields();
       			})
    
       		}
       	},
       }
    </script>
    
    

    写在最后

    关于图片上传之前我也写过一个小程序版本,总体看来pc端的图片上传相对于小程序 要复杂一点,这个封装只能满足当下单图上传的需求也有他的不足之处。当然也可以扩展为多图上传,关于多图上传的网上也有很多例子。这里不再一一赘述。

    展开全文
  • 进入 OSS 管理控制台 界面。 在左侧存储空间列表中,单击目标存储空间名称,打开该存储空间概览页面。 单击 基础设置 页签,找到 跨域设置 区域,然后单击 设置。 单击 创建规则,打开 设定跨域规则 对话框。 设置...

    1.配置阿里云oss服务器允许跨域

    1. 进入 OSS 管理控制台 界面。
    2. 在左侧存储空间列表中,单击目标存储空间名称,打开该存储空间概览页面。
    3. 单击 基础设置 页签,找到 跨域设置 区域,然后单击 设置。
    4. 单击 创建规则,打开 设定跨域规则 对话框。
    5. 设置跨域规则。
    来源:指定允许的跨域请求的来源。允许多条匹配规则,以回车为间隔。每个匹配规则允许使用最多一个“*”通配符。
    允许 Methods:指定允许的跨域请求方法。
    允许 Headers:指定允许的跨域请求 header。允许多条匹配规则,以回车为间隔。每个匹配规则使用最多一个“*”通配符。
    暴露 Headers:指定允许用户从应用程序中访问的响应头(例如一个 Javascript 的 XMLHttpRequest 对象)。
    缓存时间:指定浏览器对特定资源的预取(OPTIONS)请求返回结果的缓存时间。
    说明: 每个存储空间最多可以配置 10 条规则。
    
    1. 单击 确定。
    说明: 您也可以对已有的规则进行编辑和删除操作。
    

    在这里插入图片描述

    2.解决方法

    组件

              <vue-cropper
                ref="cropper"
                :img="options.img"
                :info="true"
                :autoCrop="options.autoCrop"
                :autoCropWidth="options.autoCropWidth"
                :autoCropHeight="options.autoCropHeight"
                :fixedBox="options.fixedBox"
                @realTime="realTime"
                v-if="visible"
              />
    

    数据属性

          options: {
            img: store.getters.avatar, //裁剪图片的地址
            autoCrop: true, // 是否默认生成截图框
            autoCropWidth: 200, // 默认生成截图框宽度
            autoCropHeight: 200, // 默认生成截图框高度
            fixedBox: true // 固定截图框大小 不允许改变
          },
    

    转换

        // 编辑头像
        editCropper() {
          this.open = true;
          let _this = this;
          // 设置头像base64
          // 其中this.avatar为当前头像
          this.setAvatarBase64(store.getters.avatar, base64 => {
            _this.options.img = base64;
          });
        },
        // 设置头像base64
        setAvatarBase64(src, callback) {
          let _this = this;
          let image = new Image();
          // 处理缓存
          image.src = src + "?v=" + Math.random();
          // 支持跨域图片
          image.crossOrigin = "*";
          image.onload = function() {
            let base64 = _this.transBase64FromImage(image);
            callback && callback(base64);
          };
        },
        // 将网络图片转换成base64格式
        transBase64FromImage(image) {
          let canvas = document.createElement("canvas");
          canvas.width = image.width;
          canvas.height = image.height;
          let ctx = canvas.getContext("2d");
          ctx.drawImage(image, 0, 0, image.width, image.height);
          // 可选其他值 image/jpeg
          return canvas.toDataURL("image/png");
        },
    
    展开全文
  • Home.vue组件 这个组件的用户登录成功后所有页面(除404页面外),所有页面的公共部分组件 layui布局 官网布局: http://element-cn.eleme.io/#/zh-CN/component/layout 此页面的代码布局结构: 图片和昵称...
  • 分享一个适用于后台管理系统、网站等的图片查看器。 demo在线链接: duo-image-viewer 支持以下功能: 1.缩放: 2.旋转 3.拖拽 4.全屏 技术栈:vue 如何使用: 1.安装依赖 npm i duo-image-viewer --save // cnpm ...
  • 本文解决,upload组件 file-list的动态绑定list1,list2 …,实现动态添加,相信很多电商后台管理系统都会遇到这个需求,例子如下 本例,我是使用的upload默认的上传地址(很多图片不能上传,你可以在本地截几张图片...
  • 本文解决,upload组件 file-list的动态绑定list1,list2 ...,实现动态添加,相信很多电商后台管理系统都会遇到这个需求,例子如下 本例,我是使用的upload默认的上传地址(很多图片不能上传,你可以在本地截几张...
  • 近来在尝试使用antd做后台管理系统的开发,其中一个场景需要上传单张图片,antd的上传组件默认大多都是多张上传的,当然可以按示例的方法,使用代码控制上传列表的数量handleChange(info) {let fileList = [...info....
  • 推荐一个适用于后台管理系统、网站等的图片查看器。demo在线链接: duo-image-viewer支持以下功能:1.缩放:2.旋转3.拖拽4.全屏技术栈:vue如何使用:1.安装依赖npm i duo-image-viewer --save // cnpm i duo-image-...
  • 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • Vue后台管理

    2018-10-11 10:51:40
    - 权限管理 - 列表过滤 - 权限切换 - 多语言切换 - 组件 - 富文本编辑器 - Markdown编辑器 - 城市级联 - 图片预览编辑 - 可拖拽列表 - 文件上传 - 数字渐变 - split-pane - 表单编辑 - 文章发布 - 工作...
  • 所谓组件化,就是把页面拆分成多个组件,每个组件自己管理所依赖的 CSS、JS、模板、图片等资源 ②. 组件组件之间通过特定的规则进行数据传递、就会行成树状结构 ②. 全局注册 ①. Vue.component(‘组件...
  • 最近做后台管理,需要用到图片裁剪,这个组件很好用,记录一下。 工作太忙,就不总结了。 链接分享:https://github.com/xyxiao001/vue-cropper 转载于:https://www.cnblogs.com/LChenglong/p/10291440.html...
  • 所谓组件化,就是把页面拆分成多个组件,每个组件自己管理所依赖的 CSS、JS、模板、图片等资源、 组件组件之间通过特定的规则进行数据传递、就会行成树状结构 组件注册 全局组件 Vue.component(‘组件名称’, {...
  • vue 图片剪裁插件

    千次阅读 2019-02-01 16:31:37
    最近在用Vue做后台管理系统,需要用到图片剪裁的插件。之前用的element-ui的upload组件,但是这个不支持剪裁,在网上找了几个插件,最后决定用vue-image-crop-upload这个插件。还挺好用的,但是有一个问题,就是他不...
  • 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • 前言 在开发中总会遇到一些全局组件,如果通过...而这其中频繁使用到图片上传,每个模块都得使用,无论是cv大法还是import都显得不太方便,这就显现出触发式全局注册组件的优势 不废话直接开始吧 正文 1、文件结构 其
  • Vue组件化的思想

    千次阅读 2020-02-25 08:59:42
    组件化的思想 将一个页面中的处理逻辑放在一起,处理起来...[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KliQpjaO-1582592295825)(DF3D10A014534D8690E6CE3717EEAE29)] 注册组件的基本...
  • Vue学习笔记一、什么是组件、为什么使用组件?二、组件基础1.注册并使用组件2.读入数据总结 一、什么是组件、为什么使用组件? 把整个页面划分为一个个小的模块,这些模块共同完成整个页面的功能,这些小模块就是...
  • 嵌套的JavaScript评论 Widget Models ... 交互插件: Real time comments: Adapts your site's lokk and feel,可以...Rich media commenting读者可以增加图片和视频。 Works everywhere.支持各种设备,语言。 ...
  • 安装:cnpm install --save-picture-preview使用:首先在项目的入口文件中引入, 调用 Vue.use 安装。...Vue.use(vuePicturePreview)在根组件添加 lg-preview 组件的位置App.vue:&lt;template&...
  • 项目中需要做一个内容的封面图片,后台有上传管理的功能。 这里我用的 这个,复制组件代码,因为我只需要上传一个图片,所以将长度改为 1 重点说一下图片上传的请求方式 原生组件代码是用的action属性+url上传...
  • 组件 index.vue 详情 <template> <div class="component-upload-image"> <el-upload :action="uploadImgUrl" list-type="picture-card" :on-success="handleUploadSuccess" :before-upload=...
  • Ant Design Vue 后台管理项目总结父组件调用子组件(Modal为例)接口调用插槽的使用ES6中规范写法ES6箭头函数修改数据之后的refresh数据重置时间格式 (moment文档)在一个界面打开另一个界面(路由)上传图片的功能...
  • 插件:vue-preview (vue图片预览组件 ) vue点击图片预览放大(可旋转、翻转、缩放、上下切换、键盘操作) 插件viewerjs GitHub地址:https://github.com/fengyuanchen/viewerjs 加入全局方式的loading: ...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 335
精华内容 134
关键字:

vue图片管理组件

vue 订阅