美文网首页
vue的探索之路(一)

vue的探索之路(一)

作者: Powen | 来源:发表于2017-05-11 23:47 被阅读0次

前言:这次的App项目是由native+H5组合而成,整个App分为2个模块,我负责的是商城首页到生成订单的一系列页面以及业务代码,在这里总结一下遇到的问题。第一次写笔记,多多见谅。

打包工具

项目采用webpack进行打包,虽然之前有过一些基础的接触,但是这次还是第一次自己尝试的去配置,稍微补了一下webpack的内容。

//webpack.config.js
module.exports = {
    entry: {
        ProductDetails:"./src/js/ProductDetails.js",
        Orderdetail:"./src/js/Orderdetail.js",
        Logistics:"./src/js/Logistics.js",
        Index:"./src/js/Index.js",
        ...
    },
    output: {
        path: './dist',
        filename: '[name].js'
    },
     resolve: {
        alias: {
            'vue': 'vue/dist/vue.js',
        }
    }, 
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/
            },
            {
                test: /\.vue$/,
                loader: 'vue'
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader!'
            },
            {
                test: /\.scss$/,
                exclude: /node_modules/,
                loader: 'style-loader!css-loader!sass-loader'
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'url' 
            }
            
        ]
    },
    
}

入口

entry :配置起始文件的路径,它可以是数组,对象,字符串。在这里我采用了多页面入口的方式。

输出

output: path: 配置最终打包完成后的路径所在;filename:最终打包后文件的名称,由于是多页面入口文件,这里为了方便使用[name].js,这样最终打包出来的文件名称跟入口文件名称一致。

加载器

module(loaders):
test:注意是正则表达式,不要加引号,匹配要处理的文件

loader:要使用的loader,"-loader"可以省略

include: 把要处理的目录包括进来

exclude:不需要去处理的目录。


与native的交互

  • 目前是通过自定义协议的方式,也就是URL,协商一个通用的协议比如app.owen://?pushcode=1 ,前端通过location.href,而native则是通过截取这段URL,获取里面的参数进行处理。

难点一.

模仿淘宝商品详情,虽然不要求完全一样但是功能基本要一致。难点就是在商品属性选择后价格,库存,图片都要改变,到这首先想到的就是Vue中的watch.然后就是每种分类的点击效果,不冲突,不重复。

demo1.png
demo2.png
这里我想了很久该怎么做才能做到点击效果的同时又能使用watch监控,实现动态。经过不断的尝试我终于找到了方法,通过深入响应式原理了解,只有在data属性上的js对象都被会vue遍历再通过Object.definePropery将全部属性转换getter/setter,可以通过console.log()查看,它们在内部行了追踪依赖,才能实现响应。

在这里有个重点,Vue 不允许在已经创建的实例上动态添加新的根级响应式属性,也就是说我们只能动态添加在已存在的根级属性中,我在Vue创建了根级属性iscur

    data: {
        iscur: {},//当前的商品子属性attrid
    }  
    

可以通过this.$set(this.iscur,'b',2),但是如果新添加的新属性在改变后并不会触发更新怎么办,这里是采用this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }),创建一个新的对象,让它包含原对象的属性和新的属性。

言归正传,通过请求获取分类数据,这里我通过遍历父分类,给iscur动态添加属性,

            this.arrts.forEach( (val, index)=> {              
                    var attrsId = {
                        //设置子分类attrid
                        ['type' + index]: ""
                    }
                    ....
                    this.iscur = Object.assign({}, this.iscur, attrsId) //实现data响应
                    ....              
                })

可以看到iscur 中的属性,


demo3.png

在看看HTML处:

//父分类
<div class="attr" v-for="(attr,findex) in arrts">
   <h1 >{{attr.attrname}}</h1>
   <ul :id="attr.attrid">
          //子分类
          <li  v-for="(item,index) in attr.attrValueList" 
           :class="{active:iscur['type'+findex]==item.attrid}"         
           v-on:click="actives($event,findex,item.attrid)"                   
          >{{item.attrname}}</li>                   
   </ul>
</div>

首先分类信息会有两次遍历,首先遍历出父分类,再遍历子分类,其中:class="{active:iscur['type'+findex]==item.attrid}是判断当前父分类下选中的是哪个子分类id。v-on:click="actives($event,findex,item.attrid)点击子分类时将父分类的id和子分类的id传入

 actives: function (e, findex, attrid) {   
            this.iscur['type' + findex] = attrid;
        }

最后使用watch监控iscur对象,在每次点击后,iscur就会发生改变,从而执行handler,
在其中执行对比sku,更换价格,图片,以及库存。

iscur: {
            /*
            监控 iscur 对象
            当iscur中属性发生变化时,我们获取iscur中每个属性的value值,再与价格表中的数据进行对比,提取出相同项的数据
            */

            handler: function (val) {

                // do  something 
            },
            // 深度观察
            deep: true
        },

难点二.

这种类分页:

demo5.png
最开始做的时候也最简单,上面部分横向导航栏,下面展示商品,每次点击分类时候去请求相应的数据,替换掉展示商品部分的数据,这样的结果就是出现重复请求数据,体验也差。之后想试着优化这部分,看了主流app类似这种分类页效果,就是点击子分类,如果是第一次则加载数据,否则就显示数据,再次点击分类的时候刷新。
思路:首先我在data中设置一个属性productlist专门用来存放数据,默认值设置为一个空数组 ,在子分类成功后执行setModels方法
setModels: function (datas) { 
            /**
             * 初始化productlist的数据结构
             * 根据分类数据遍历后分别添加obj,用来存放数据
             */

            datas.forEach((value, index) => {
                var obj = {
                    brandid: value.brandid,
                    list: []
                }
                this.productlist.push(obj)
            })
        },

通过这个方法,productlist拥有了跟分类相同个数对象,之后每次点击子分类后去请求商品列表,然后遍历每个数据push到相应obj的list数组中,这样就保存了数据。当然点击时候还需要一个方法去判断什么时候去请求。

 cacheData: function (index,brandid) {
            /**
             * 通过index知道分类的索引号,获取数据
             * 如果list的长度为0,代表无数据,则去请求数据
             */   
            var indexdata=this.productlist[index]
            if(indexdata.list.length==0){
                this.getlistdata(brandid)
            }else{
                return false
            }
            
        },

Tips

this.$nextTick(function(){
//dom更新
})

这个方法通常是我们需要运用到dom时候调用的,比如swiper,js 在获取图片数据后,实例化swiper必须在该回调函数内执行才有效。获取一些其他第三方插件需要操作dom节点,获取边距等都需要在回调函数内执行。

相关文章

网友评论

      本文标题:vue的探索之路(一)

      本文链接:https://www.haomeiwen.com/subject/lfjmzttx.html