最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 小白PC端vue项目+JS定制器经验总结

    正文概述 掘金(前端贰货道士)   2021-03-19   462

    写在前面

      本人从事前端4个月以来参与了一个PC端vue项目和JS定制器练习,本博文是对PC端项目经验的总结,方便后续查找和翻阅。同时也希望自己的项目经验能够帮助到大家,不足之处,烦请大家批评指正,谢谢大家的支持。

    PC端项目经验总结(排名不分先后,随心随性)

    1.尽量少使用绝对定位,多使用万能的flex布局

      如果一个页面使用很多绝对定位来布局,后期维护网页需要增添和删除内容修改样式时,会极为不便。使用父盒子包裹需要布局的内容,并给父盒子一个flex布局,可以很轻松地将不同的div和span放在一行显示。

    2.网页请求优化

    • 对同步模块框中不经常变化的接口,使用axios的config参数进行缓存。
        /**
         * 获取产品目录列表
         * @param {object} catalog_id 请求参数
         * @returns {Promise<Object|AxiosError>} 请求结果
         */
        getProductsCatalogs(catalog_id) {
            return this._get(`${catalog_id}/products/catalogs`, {
                cache: true,
                cache_seconds: 600
            })
        }
    
    • 请求接口时去掉多余的参数。
    • 可以使用web.dev对网站的性能进行测评。

    3. 不能连写if条件中的判断条件

    • 错误示范:
       /**
             * 获取分销商申请信息
             */
            getDropshipApplyInfo() {
                this.$storeDispatch('me/getDropshipperInfo', { skip_cache: true })
                    .onSuccess(({data}) => {
                        if(data.dropshipper.status === 'success' || 'pending') {
                            this.setMessagePromptBox(this.success_message, 'success')
                            this.$router.push(this.localePath({ name: 'dashboard' }))
                        } else {
                            this.setMessagePromptBox(this.$t('b_register.account_review'), 'error')
                        }
                    })
            },
    

       if(data.dropshipper.status === 'success' || 'pending')是先判断data.dropshipper.status === 'success' 的值。如果值为真,就不会执行后面的判断条件,结果就为真;如果值为假,就会和 'pending'做或运算,得到 'pending'的结果,最后if会将这个字符串强制转换为布尔值true,所以最终结果也是真。即不管data.dropshipper.status === 'success' 的值是什么,最后的结果都为真,都会执行if条件语句中的内容。因此,不能连写if条件中的判断条件,不然会产生不同的判断语义。

    • 正确示范:

         if(['success', 'pending'].includes(data.dropshipper.status))
      或者 if (['success', 'pending'].indexOf(data.dropshipper.status) !== -1)

    • 特别注意:

         此处请求不常用的接口(设置的缓存时间为120s )获取分销商申请信息, 使用到{ skip_cache: true }。因为这个接口在C端用户进入B端发起申请分销商的请求后,如果返回的状态为成功,就会继续请求获取分销商申请信息的接口。如果此时不清除缓存,则不会发起获取分销商申请信息的请求,也就无法获取接口返回的状态了,因此需要清除缓存。所以区别于2.网页请求优化的第一点,给接口加缓存和清除缓存是要看情况的。

    4 . 可以使用富文本编辑器(如vue-quill-editor)解析后端传入的html代码

    5. 使用overflow-x:hidden来隐藏网页底部出现的滚动条

    6.自定义组件如果要定义点击事件,需要使用@click.native

    7.字符串模板``中使用${变量名}来获取变量

       字符串模板只能在JS中引用,不能在html中使用。

    8.当产品路由id发生变化时,轮播的当前索引并未重置

      watch: {
        '$route.params.id'() {
          this.current_index = 0
        }
      }
    

    9.根据路由地址判断是否为shopify页面

            /**
             * @returns {boolean} 是否是shopify页面
             */
            is_shopify_page() {
                return this.$route.path.indexOf('/shopify') === 0
            }
    

       shopify-app项目是基于B端代码进行兼容开发,网页大部分逻辑和样式都与B端相同。因此,对不同于B端的逻辑和样式需要使用is_shopify_page()方法进行判断,从而达到兼容开发互不影响的效果。

    10.使用git和arcanist工具进行开发

    arc branch fix  //新建fix分支进行开发,需要安装和配置arcanist
    git checkout develop  //切换到develop分支
    git pull  //拉取最新代码
    git add .  //暂存代码
    git commit -m 'fix(登录模块): 修正...的问题'  //添加评论
    arc 4d //提交代码审核申请
    arc 4l //代码审核通过,拉取合并代码,并解决冲突后,将代码提交到仓库
    

    11.使用vue 内置组件component切换不同模态框的显示与隐藏

    <template>
        <el-dialog
            class="shopify-modal-wrapper"
            :close-on-click-modal="false"
            center
            :visible.sync="is_show_sync_product_modal"
            width="980px"
            @close="closeModal"
        >
            <div slot="title">
                <p>{{ current_title }}</p>
                <p
                    v-if="product.shopify_product"
                    class="red synced-message"
                >
                    {{ $t('shopify_app.the_product_has_been_synced') }}
                </p>
            </div>
            <component
                :is="current_component"
                v-loading.fullscreen.lock="is_sync_product_modal_loading"
                :product="product"
                @close-modal="closeModal"
            />
        </el-dialog>
    </template>
    

       给整个页面加loading可以结合v-loading.fullscreen.lockvuex数据控制页面的加载状态。当点击Next按钮,则会切换为step2组件;当点击Back按钮,则会切换为step1组件;当关闭模态框时,会切换为默认的step1组件。

    12.模态框的数据流问题(出错的原因纯属自己猜想,如有错误之处,麻烦评论区纠正,感谢)

    • 公共产品模块

    小白PC端vue项目+JS定制器经验总结

    • step1模态框

    小白PC端vue项目+JS定制器经验总结

    • step2模态框

    小白PC端vue项目+JS定制器经验总结

    • 问题1: 在第一个模态框修改数据后,点击进入第二个模态框。当切回第一个模态框时,发现第一个模态框修改的数据并未更新。

      原因: 使用vue内置组件component控制的模态框相互独立,模态框切换的过程中,其余的模态框组件被销毁,而里面的数据并没有更新并保存下来,数据自然会丢失。如果要使模态框的切换成为一个连续的过程,可以在第一个模态框下一步按钮触发的next方法中,控制模态框的显示与隐藏。

      做法:在step1组件下一步按钮触发的next方法中,使用vueX保存第一个模态框需要保存的数据。并在step1组件的created生命周期函数(只有在第一次点击同步按钮,显示第一个模态框和来回切换step1和step2组件的时候才触发生命周期函数)中,触发created生命周期函数中的第二个赋值函数,先判断vueX中存储的数据是否为空。如果为空,就直接return。同时会触发created生命周期函数中的第一个赋值函数,获取产品的默认信息,将接口返回的产品信息展示到模态框上;如果不为空,就将vueX中存储的数据赋值给step1模态框需要使用的属性。

      总结:所以step1组件中的created生命周期函数存在两个赋值函数

      第一个赋值函数(用于每次重新打开step1模态框,初始化产品数据):当vueX数据为空(vueX的数据不存在或者每次在关闭模态框后被清空,问题2中会解释),说明是第一次打开step1组件或者关闭了模态框。此时step1模态框处于打开状态或者在打开step1模态框的状态,会将默认的产品信息展示到模态框上。这个赋值函数不论vueX数据是否为空都会被调用

      第二个赋值函数(用于从step2组件切换到step1组件,不会丢失修改的产品数据信息): 当vueX数据为空时,直接return,触发第一个赋值函数;当vueX中存在数据,说明已经进入过step2组件,此时切换到第一个模态框,会将vueX的数据赋值到step1组件中。此处需要特别注意,因为切换组件的过程会触发created生命周期函数,会同时调用两个赋值方法,此时将第二个赋值函数放在第二个,覆盖掉第一个的赋值即可。

      vueX数据为空,则只会触发第一个赋值函数;vueX数据不为空,则会同时触发两个赋值函数,且第二个赋值函数由于在后面,会覆盖掉第一个赋值函数的值。

    • 问题2:如果修改step1组件中的数据,切换到step2组件。然后关闭step1模态框,数据发生更新。此时再点击其他产品进行同步,step1组件默认都会展示相同的修改后的数据;如果修改step1组件中的数据,但不切换到step2组件,然后关闭step1模态框,数据不会发生更新;

      原因:出现问题的原因在于step1组件中的数据是由vueX来控制,而vueX数据的保存是在点击Next按钮进入step2组件之后才触发。触发之后,会同时调用生命周期函数的两个赋值函数,此时模态框的初始值都被第二个赋值函数给覆盖掉了,所以每次打开模态框都会默认展示修改后的数据信息。因此需要在每次关闭模态框时,清空vueX中保存的step1组件的数据。

      做法:监听is_show_sync_product_modal(用于控制模态框是否显示的变量,在10中可以看到)的值。如果值为假,说明模态框处于关闭状态,就将保存在vueX中的step1数据清空。这样每次在step1组件被初始化时,就会调用created生命周期函数中的第一个赋值函数,展示默认的产品信息;如果值为真,说明模态框处于打开状态,则会同时调用created生命周期函数的两个赋值方法(这里也需要同时调用两个赋值方法的原因在于,created只有在第一次打开step1组件和切换组件的时候才会触发,is_show_sync_product_modal的值只要在第一个或者第二个模态框处于打开的状态就为真。

    JS定制器练习经验总结(电商私人定制)

    1. 给canvas上的图片增加翻转功能,需要点击翻转按钮和画布才能完成图片翻转

       需要使用canvas.renderAll()更新画布,此时点击翻转按钮就能完成图片的翻转功能。

    2. svg转换为base64,可以解决跨域问题

    3. 网页效果图请求优化

    • 个人JS定制器demo展示(界面很丑,但不要在意这些细节)

    上传对应刀版的定制图片:

    小白PC端vue项目+JS定制器经验总结 效果图预览:

    小白PC端vue项目+JS定制器经验总结

    • 当前canvas上的定制图未发生变化,不发起请求
    • 对应刀版未上传定制图,不发起请求

    4. 颜色选择器的颜色发生变更时,需要点击颜色选择器外部才能更新颜色

     <!--错误的写法-->
    <input type="color" id="color"  onchange="changeFontColor()" />
    <!--正确的写法,将onchange事件改为oninput事件,此时点击不同的颜色就能更新-->
    <input type="color" id="color"  oninput="changeFontColor()" />
    

    5. 原型挂载

    // 避免图片上的操作图标被overlayImage覆盖
    fabric.Canvas.prototype.controlsAboveOverlay = true;
    //canvas的scaleX可能会出问题,需要修改精确度,确保canvas能够正常导出为json数据
    fabric.Object.NUM_FRACTION_DIGITS = 20
    

    6. 使用变换矩阵调整缩放比例的值

    //加载背景图
    function setBackgroundAttribute(file) {
    	fabric.util.loadImage(file, (img) => {
    		var rect = this.__rect = new fabric.Rect({
    			hasControls: false,
    			fill: new fabric.Pattern({
    				source: img,
                                    //使用相同图案进行填充
    				repeat: 'repeat',
    				//变换矩阵(第1个和第4个是缩放比例)
    				patternTransform: [1, 0, 0, 1, 0, 0]
    			}),
    			left: 0,
    			top: 0,
    			type: 'Background',
    			width: canvas.width,
    			height: canvas.height,
    			// 不缓存,避免图片发生变化时,因为已经缓存导致图片无法更新
    			objectCaching: false,
    			selectable: false
    		})
    		canvas.add(rect);
    		canvas.moveTo(rect, 0);
    		_getElement('BackgroundResize').value = 100;
    		canvas.renderAll();
    		backgroundObject = rect;
    	}, null, 'anonymous')
    }
    
    //获得变换矩阵
    function _getBackgroundImagePatternTransform() {
    	return this.__rect.fill.patternTransform;
    }
    
    //处理背景图片的转换方法
    function _handleBackgroundImageTransformAction(type, transform, value = null) {
    	const actionMap = {
    		toggleFlipX: (_transform) => {使用```event.target.va"```,可以在上传多张图片的业务情形时,上传相同图片
    			_transform[0] = _transform[0] * (-1);
    		},
    		toggleFlipY: (_transform) => {
    			_transform[3] = _transform[3] * (-1);
    		},
    		scale: (_transform) => {
    			_transform[0] = value;
    			_transform[3] = value;
    		}
    	}
    
    	if (!Object.keys(actionMap).includes(type)) return;
    	return actionMap[type](transform, value);
    }
    
    // 缩放/方法
    function resizeBackgroundImage(value) {
    	if (!this.__rect) return;
    	const factor = value / 100;
    	_handleBackgroundImageTransformAction('scale', _getBackgroundImagePatternTransform(), factor);
    	_getElement('BackgroundResize').title = `${value}%`;
    	canvas.requestRenderAll();
    }
    

    7. 上传本地图片

    • 使用label for input type = "file"组合形成上传组件,将 label for 改造成按钮的样式,同时隐藏input type = "file"的样式;
    <label class="bold btn add-background" for="background">
      Add Background
    </label>
    <input type="file" onchange="addBackground(event)" id="background" accept="image/*" class="file-ipt">
    
    • 使用event.target.value="",可以应用在上传多张图片的业务情景时,上传相同图片;
    • 定义全局变量imageObject。在每次调用上传本地图片的方法时,先canvas.remove(imageObject)清除图片,再将上传的图片赋值给全局变量imageObject,这种情况适合只能上传一张图片的业务情景。

    8.使用固定定位做遮罩层

    • loading效果:

    小白PC端vue项目+JS定制器经验总结

    <!--span的类我没加上-->
    <div class="loading" id= "loading">
       <img src="images/loading.gif" >
       <span>loading...</span>
    </div>
    
    .loading {
       position: fixed;
       top: 0;
       bottom: 0;
       right: 0;
       left: 0;
       background-color: white;
       opacity: 0.8;
       z-index: 2021;
       display: flex;
       justify-content: center;
       align-items: center;
      }
    

    9.fabric.js功能属性

    //禁止缩放时翻转
    lockScalingFlip: true,
    //绕图片中心点缩放
    centeredScaling: true,
    //绕图片中心点旋转
    centeredRotation: true,
    //设置坐标的中心点
    OriginX: 'center',  //X轴方向,有'left','center','right'这三个属性可供选择
    OriginY: 'center',//Y轴方向,有'top','center','bottom'这三个属性可供选择
    //fabric.js中的left和top
    //left是中心点到画布左侧的距离
    //top是中心点到画布上方的距离
    

    写在最后

      还是很小白,还有很多知识需要学习和总结,专心学习技术。


                            总结有点小绕,但只要自己看得懂就行了。



    起源地下载网 » 小白PC端vue项目+JS定制器经验总结

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元