Laravel Backpack 的多图上传及拖拽排序组件

文章目录

    功能

    • 多图上传
    • 拖拽图片排序
    • 删除图片
    • 点击放大预览
    • animated 特效

    代码实现

    <style type="text/css">
    input.el-upload__input {
      display: none;
    }
    </style>
    
    <div id="images_uploader_{{ $field['name'] }}"
         @include('crud::inc.field_wrapper_attributes') >
    
    	<input type="hidden" name="{{ $field['name'] }}" value="{{ old($field['name']) ? old($field['name']) : (isset($field['value']) ? json_encode($field['value']) : (isset($field['default']) ? $field['default'] : '[]' )) }}" ref="input_hidden">
    	<label>{!! $field['label'] !!}</label>
    
    	@include('crud::inc.field_translatable_icon')
    
    	<div>
            <div class="drag" style="float: left;">
                <ul class="el-upload-list el-upload-list--picture-card">
                  <draggable v-model="images" class="dragArea">
                    <li :tabindex="index" class="el-upload-list__item is-success animated" style=""
                        v-for="(element, index) in images"
                        v-bind:class="{flash: element.to_del}"
                        @click="preview(index)"
                        >
                        <img :src="element.url" alt="" class="el-upload-list__item-thumbnail ">
                        <a class="el-upload-list__item-name">
                            <i class="el-icon-document"></i>
                            @{{element.name}}
                        </a>
                        <label class="el-upload-list__item-status-label">
                            <i class="el-icon-upload-success el-icon-check"></i>
                        </label>
                        <i class="el-icon-close"></i>
                        <span class="el-upload-list__item-actions"><!---->
                            <span class="el-upload-list__item-delete">
                                <i class="el-icon-delete" @click.stop="remove(index)"></i>
                            </span>
                        </span>
                    </li>
                  </draggable>
                </ul>
            </div>
    
            <el-upload
                 class="upload-demo"
                 action="/api/upload_image_to_cdn"
                 :multiple="true"
                 @if (isset($field['limit']))
                    :limit="{{ $field['limit'] }}"
                 @else
                    :limit="20"
                 @endif
                 :on-success="handle_success"
                 list-type="picture-card"
                 :show-file-list="false"
                 >
                  <el-button size="small" type="primary">点击上传</el-button>
            </el-upload>
    
            <el-dialog :visible.sync="dialogVisible">
                <img style="max-width: 100%; margin: 0 auto; display: block;" :src="dialogImageUrl" alt="">
            </el-dialog>
    	</div>
    
        <br style="clear: both;"/>
    
    	{{-- HINT --}}
    	@if (isset($field['hint']))
    	<p class="help-block">{!! $field['hint'] !!}</p>
    	@endif
    </div>
    
    {{-- ########################################## --}}
    {{-- Extra CSS and JS for this particular field --}}
    {{-- If a field type is shown multiple times on a form, the CSS and JS will only be loaded once --}}
    @if ($crud->checkIfFieldIsFirstOfItsType($field, $fields))
    
    {{-- FIELD CSS - will be loaded in the after_styles section --}}
    @push('crud_fields_styles')
        <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.4.11/theme-chalk/index.css" />
        <link rel="stylesheet" href="https://cdn.staticfile.org/animate.css/3.7.0/animate.min.css" />
    @endpush
    
    {{-- FIELD JS - will be loaded in the after_scripts section --}}
    @push('crud_fields_scripts')
        <script type="text/javascript" src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
        <script type="text/javascript" src="https://cdn.staticfile.org/Sortable/1.8.1/Sortable.min.js"></script>
        <script type="text/javascript" src="https://cdn.staticfile.org/Vue.Draggable/2.17.0/vuedraggable.min.js"></script>
        <script type="text/javascript" src="https://cdn.staticfile.org/element-ui/2.4.11/index.js"></script>
    @endpush
    
    @endif
    
    @push('crud_fields_scripts')
    <script>
    new Vue({
    	el: "#images_uploader_{{ $field['name'] }}",
    
    	data: {
    		images: [],
            dialogVisible: false,
            dialogImageUrl: ''
    	},
    
    	mounted: function() {
            var value = this.$refs.input_hidden.value;
            var images = JSON.parse(value);
            var _images = [];
    
            for (var i = 0, len = images.length; i < len; i++) {
                _images.push({
                    name: images[i],
                    url: images[i],
                    to_del: false
                });
            }
    
            this.images = _images;
    	},
    
        watch: {
            images: function(nv, ov) {
                var images = [];
                for (var i = 0, len = nv.length; i < len; i++) {
                    images.push(nv[i].url);
                }
                this.$refs.input_hidden.value = JSON.stringify(images);
            }
        },
    
    	methods: {
            handle_success: function(response, file, fileList) {
                this.images.push({
                    name: response.data,
                    url: response.data,
                    to_del: false
                });
            },
    
            remove: function(index) {
                var that = this;
    			this.$confirm('确认删除?', '提示', {
    				confirmButtonText: '确定',
    				cancelButtonText: '取消',
    				type: 'warning'
    			}).then(function () {
    				that.$message({
    					type: 'success',
    					message: '删除成功!'
    				});
                    that.images[index].to_del = true;
                    setTimeout(function() {
                	    that.images.splice(index, 1);
                    }, 1000);
    			})
            },
    
            preview: function(index) {
                this.dialogImageUrl = this.images[index].url;
                this.dialogVisible = true;
            }
    	}
    });
    </script>
    @endpush
    {{-- End of Extra CSS and JS --}}
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式