vue组件实践-开发图片预览

甲方需求

开发一个像微信朋友圈图片预览界面,可以左右滑动查看图片

需求分析

了解客户基本需求,从需求点上去获取功能需求与具体的代码实现,需求分析也是很重要滴~~
需求分析.png

功能分析

根据需求分析实际上代码要实现的需求,是否需要改善,或则选择合理的方案,不要客户的需求就全盘接受,需要适当权衡客户所需。所以继需求分析后就是功能分析,该功能具体实现有什么难点,是否需要调整方案等。
功能分析.png

版式设计

虽然对于许多开发人员而言认为并不需要会什么设计,但是作为新一代的开发人员会点相关的技能还是有必要的,至少自己脑海里得有一个图形知道自己要做什么,这样可以在设计师未设计前提前做好准备,先人一步。
版式设计

开始开发

开始开发是否也不要立马就拿起键盘就一波走,管他三七二十一就是干,万一卡带了怎么办,那么就理一理功能实现思路走走流程吧。
开发流程导图.png

HTML代码

<template>
    <div id="masking" class="masking" v-show="isshow" @click="commitExit">
        <div class="toast" v-show="isend">最后一张图</div>
        <!--显示图片-->
        <img class="masking-img" :src="showimg" />
        <div class="del_click" @click.stop="commitExit">
            删除
        </div>
        <div class="controler">
            <!--左移-->
            <img @click.stop="onLeft" class="controler_icon contro-left" src="../../assets/icon_left.png" />
            <!--右移-->
            <img @click.stop="onRight" class="controler_icon contro-right" src="../../assets/icon_right.png" />
        </div>
    </div>
</template>

CSS样式代码

<style scoped="scoped">
    .masking {
        z-index: 999;
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: #000000;
        display: inline-block;
        vertical-align: middle;
        padding: 0px;
    }
    
    .toast {
        border: solid 1px red;
        border-radius: 6px;
        position: absolute;
        bottom: 5rem;
        left: 5rem;
        right: 5rem;
        text-align: center;
        margin-left: 0;
        margin-right: 0;
        color: red;
        padding: 0.2rem;
    }
    
    .masking-img {
        width: 100%;
        height: auto;
        margin-bottom: auto;
        margin-top: auto;
        position: absolute;
        top: 0;
        bottom: 0;
        background-size: 100%;
        vertical-align: middle;
        display: inline-block;
    }
    
    .del_click {
        position: absolute;
        top: 3rem;
        right: 3rem;
        border: solid 1px #04BE02;
        color: #04BE02;
        padding: 2px 10px;
        border-radius: 6px;
        font-weight: bold;
    }
    
    .controler {
        position: absolute;
        top: 0;
        bottom: 0;
        vertical-align: middle;
        width: 100%;
        height: 40px;
        margin-bottom: auto;
        margin-top: auto;
        display: flex;
        padding: 10px;
    }
    
    .controler_icon {
        width: 1.5rem;
        height: 1.5rem;
        padding: 0.2rem;
        background-color: #CCCCCC;
    }
    
    .contro-right {
        position: absolute;
        right: 2rem;
    }
</style>

JS功能代码

<script>
    export default {
        name: 'masking',
        data() {
            return {
                showimg: "",
                showindex: 0,
                baseimgs: [],
                isend: false
            }
        },
        created() {
            //初始化显示状态
            this.isshow = false;
        },
        //接受父对象传递数据
        props: {
            imgs: Array,
            isshow: false
        },
        watch: {
            //监听图片数组
            imgs: {
                handler: function(val, oldval) {
                    if(val != oldval) {
                        this.$nextTick(() => {
                            if(this.isEmptry(this.imgs)) {
                                //更新数组
                                this.baseimgs = this.imgs[0];
                                //初始化下标
                                this.showindex = 0;
                                //初始化隐藏最后一张图提示
                                this.isend=false;
                                //更新设置图片
                                this.onUpdataImg();
                            }
                        })
                    }
                },
                immediate: true, //关键
                deep: true
            },
        },
        methods: {
            //通知父组件关闭
            commitExit() {
                //关闭方法为onmaskclose
                this.$emit('onmaskclose', false);
            }, //左移
            onLeft: function() {
                this.showindex--;
                if(this.showindex > 0) {
                    this.onUpdataImg();
                } else {
                    this.showindex = 0;
                    this.onUpdataImg();
                }
                //关闭最后一页提示
                if(this.isend) {
                    this.isend = false;
                }

            }, //右移
            onRight: function() {
                this.showindex++;
                if(this.showindex < this.baseimgs.length) {
                    this.onUpdataImg();
                } else {
                    //提示最后一张图
                    this.isend = true;
                    //设置当前下标为数组有效下标最大值
                    this.showindex = this.baseimgs.length - 1;
                    //设置为最后一张图
                    this.onUpdataImg();
                }

            }, //判断数组是否为空
            isEmptry: function(value) {
                if(value != undefined && value.length > 0) {
                    return true;
                } else {
                    return false;
                }
            },//更新设置图片
            onUpdataImg: function() {
                //判断数组
                if(this.isEmptry(this.baseimgs)) {
                    this.showimg = this.baseimgs[this.showindex];
                }else{
                    this.isshow = false;
                    this.commitExit();
                }
            }
        }
    }
</script>

测试调用

接下来开始在父类组建中使用组建:
1.引用组件,使用 import 名称 from 路径
2.在template中写入组建名称,注意以标签的方式,如果有下划线可以用大写单词首字母拼接。
3.需要在组件标签上写上对应的传参或则回调方法。

<template>
<maskbox :imgs="showimg" :isshow="isShowMask" @onmaskclose="onMaskClose"></maskbox>
</template>
<script>
import maskbox from "../element/maskingBox.vue"
export default {
    components: { maskbox },
        data() {return {
                  showimg:[],
                  isShowMask:false
                    }
        },methods: { 
      //获取预览图片回调
      onMaskClose:function(value){
          this.isShowMask=value;
      }
    }
}
</script>

知识点解析

1.scoped属性:
在style设置该属性,表示该样式只适用当前模板下;如果想要在该样式下使用预处理语言less,配置好less加载引擎后在style标签上添加lang="less"就可以使用。
2.父组建向子组建通信
需要使用props,它可以是一个json对象,也可以是一个数组,如:

props{value1:String,value2:Array},
props["value1","value2"]

*注意写好参数类型语法报错
3.子组件向父组建通信
需要使用emit(方法名,参数)调用,如:

this.$emit('onmaskclose', false);

*其中方法名使用全小写,不然可能会出问题。
4.watch的作用
用于监听data中值的变化,大概的使用方式:

export default {
    data: {
      valueName: 'abc'
    },
    watch: {
      valueName(newValue, oldValue) {
      // 值更新
    },
     immediate: true, //关键
     deep: true
    } 
}
  1. 加载延迟回调:
this.$nextTick(() => {
    //延时回调代码
})

nextTick是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。
6.在编写代码时要保持代码整洁:
*变量或者定义方法尽量保证命名规范,见名知意;
*代码中尽量不要出现重复功能代码块,能够封装的就封装起来;
*代码编写过程中写好注释,不要认为自己能够看懂或则都是英文会英文的都能看懂之类的想法。

甲方新增需求三连(甲方加钱¥2000)

需求1连:

需求内容:当图片大于一张时,顶部显示总张数与当前张数,底部根部添加滑动指引,可以点击具体指引跳转具体某一张图。
完成状态:待完成

需求2连:

需求内容:当图片大于一张时,添加手势滑动切换,手势滑动到最后一页后从头开始。
完成状态:待完成

需求3连:

需求内容:当图片大于一张时,图片可点击跳转打开对应图片链接。
完成状态:待完成

甲方更改需求三连(甲方加钱¥5000)

需求1连:

需求内容:查看当前图片时,支持图片放大缩小。
完成状态:待完成

需求2连:

需求内容:如果当前图片为全景图片时,可支持360度全景查看视角,并支持陀螺仪旋转查看。
完成状态:待完成

工具&环境

*思维导图工具:MindMaster
*原型图工具:Mockplus
*开发IDE:HBuilder
*编译环境:node+npm

结语

本篇文章也算自己在平时开发中的一些总结,并且对此进行记录,希望能够给看这篇文章的你们也能留下一点点收获。
最后提醒自己:
一切的焦虑不安都源自于自己不会总结与归零,还有让自己从零开始。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容