美文网首页
Vue.js重构有赞商城(I)

Vue.js重构有赞商城(I)

作者: 饥人谷_哈噜噜 | 来源:发表于2018-11-21 21:39 被阅读0次

    1. 首页index.html

    • 迁移静态页面

    index.html的头部

    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <!-- DNS 预解析 -->
      <link rel="dns-prefetch" href="https://dn-kdt-img.qbox.me/">
      <link rel="dns-prefetch" href="https://img.yzcdn.cn/">
      <link rel="dns-prefetch" href="https://b.yzcdn.cn/">
      <link rel="dns-prefetch" href="https://su.yzcdn.cn/">
      <link rel="dns-prefetch" href="https://h5.youzan.com/v2/">
      <link rel="dns-prefetch" href="https://h5.youzan.com/">
      <meta name="keywords" content="有赞,移动电商服务平台">
      <meta name="description" content="有赞是帮助商家在微信上搭建微信商城的平台,提供店铺、商品、订单、物流、消息和客户的管理模块,同时还提供丰富的营销应用和活动插件。">
      <!-- 是否为手持设备优化 -->
      <meta name="HandheldFriendly" content="True">
      <!-- 为某个宽度特殊优化 -->
      <meta name="MobileOptimized" content="320">
      <!-- 电话号码和邮箱识别 -->
      <meta name="format-detection" content="telephone=no">
      <!-- 针对LCD液晶显示器设计,可提高文字的清晰度 -->
      <meta http-equiv="cleartype" content="on">
      <link rel="shortcut icon" href="https://b.yzcdn.cn/v2/image/yz_fc.ico">
      <title>发现朋友圈的推荐</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
      <!--<link rel="stylesheet" href="./css/common.css">-->
      <!--<link rel="stylesheet" href="./css/index.css">-->
    </head>
    

    (1). DNS 预读取

    DNS 预读取是一项使浏览器主动去执行域名解析的功能,其范围包括文档的所有链接,无论是图片的,CSS 的,还是 JavaScript 等其他用户能够点击的 URL。
    因为预读取会在后台执行,所以 DNS 很可能在链接对应的东西出现之前就已经解析完毕。这能够减少用户点击链接时的延迟。

    MDN-dns文档

    dns.png

    (2). 移动端适配
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    • 修改webpack配置 路径简化
    修改路径配置.png
    • 创建vue实例

    vue实例挂载点不能是htmlbody

    添加挂载点.png
    • 后台获取数据

    第三方插件:axiosaxios中文文档

    rap-lists.png

    yarn add axios

    api.png 数据渲染.png
    • 数据滚动加载

    常用的UI库:
    weui 微信小程序的UI库
    mint-ui
    YDUI vue官网推荐的移动端UI库

    安装mint.png
    安装mint插件.png
    官网文档
    mint按需引入.png
    修改.babelrc文件.png

    找到自己需要的组件,复制粘贴到index.js中,此项目引入Infinite scroll无限滚动指令:

    引入组件.png

    为 HTML 元素添加 v-infinite-scroll 指令即可使用无限滚动。滚动该元素,当其底部与被滚动元素底部的距离小于给定的阈值(通过 infinite-scroll-distance 设置)时,绑定到 v-infinite-scroll 指令的方法就会被触发。

    <ul class="js-list js-lazy" data-src=""  
        v-infinite-scroll="getLists"
        infinite-scroll-disabled="loading"
        infinite-scroll-distance="10" 
    >
    

    !!!别忘记index.js中引入啊!!!

    import 'css/common.css'  //webpack.base.conf.js中的alias配置了路径
    import './index.css'
    import Vue from 'vue'
    import axios from 'axios'
    import url from 'js/api.js'
    import { InfiniteScroll } from 'mint-ui';
    Vue.use(InfiniteScroll);
    
    • 底部导航组件

    单vue组件 template必需(根节点只能有一个),style可以有多个

    Foot.vue: 
    <template>
        <div class="bottom-nav"> //根节点只能有一个
        ……
        </div>
    </template>
    
    <script>
    </script>
    
    <style>
      // src/pages/index/index.css中的.bottom-nav样式
    </style>
    
    html部分:
    <foot></foot>
    

    !!!别忘记index.js中引入啊!!!
    import Foot from 'components/Foot.vue'

    • 轮播组件

    第三方插件:swiper

    rap-banner.png
    安装swiper.png
    Swipe.vue: 
    <template>
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div class="swp-page swiper-slide" v-for="list in lists">
                    <a class="js-no-follow" v-bind:href="list.clickUrl">
                      <img class="goods-main-photo fadeIn" v-bind:src="list.img">
                    </a>
                </div>
            </div>
            <div class="swiper-pagination"></div>
        </div>
    </template>
    <script>
        import Swiper from 'swiper'
        import 'swiper/dist/css/swiper.css'
        export default {
            name: 'swipe',
            props: {
                lists: {
                    type: Array, 
                    required: true
                },
                name: {}
            },
            mounted(){
                this.init()
            },
            methods: {
                init(){
                   // Swiper文档
                }
            }
        }
    </script>
    <style>
      // 调整图片的样式
    </style>
    
    分页.png 自动轮播.png
    index.html:
    <!--<div class="js-image-swiper custom-image-swiper  custom-image-swiper-single" data-images="1">--> 
      <swipe v-bind:lists="bannerLists" name="swipe.vue" v-if="bannerLists"></swipe>
    <!--</div> -->   
    

    父类传递,其中v-bind:lists="bannerLists" name="swipe.vue"是动态绑定,对应index.js中的props

    index.js: 
    components: {
            Foot, //ES6语法 等价于Foot: Foot
            Swipe
    }
    

    !!!别忘记index.js中引入啊!!!
    import Swipe from 'components/Swipe.vue'

    2. 分类页category.html

    caregory.html,过程与首页类似。page目录下新建category文件夹,迁移静态文件,category.js文件中引入css样式文件、引入各种需要的插件。api.js文件中加

        topList: '/category/topList', //分类页面的一级分类
        subList: '/category/subList',  //分类页面的二级分类
        rank: '/category/rank'  //分类页面的综合排行
    

    category.html文件中删掉li标签的内容,留一个模板渲染
    :侧边栏菜单即二级菜单,事件绑定官网文档v-on:click简写成@click
    :绑定class,语法:<div v-bind:class="{ active: isActive }"></div>
    改:原网站bug,热词排行榜无法下拉到最底,最后一行的词条无法完全显示

    category.css文件中加入:
      .main-content {
        overflow-y: scroll;
      }
    
      .inner-content {
        margin-bottom: 50px;
      }
    
    一级分类.png
    二级分类.png
    综合排行.png 综合排行详细.png
    补充:过滤器filters
    官网文档
    filters: {
        number: function(price){
            var priceStr= ' ' + price
            if(priceStr.indexOf('.') > -1){  //检索的字符串值没有出现,则该方法返回 -1。
              var priceArr = PriceStr.split('.')
              return priceArr[0] + '.' + (priceArr[1] + '0').substr(0,2) //11.2 >> 11.20    
           }else{
              return priceStr + '.00'
           }
        }
    }
    
    html部分:
     <div class="price">¥{{list.price|number}}</div>
    

    3. 列表页search.html

    • 迁移静态页面:


      页面目录结构.png
    • 优化Foot.vue
      querystring模块 :qs官方文档
      yarn add qs

    eg:
    var obj = qs.parse('a=c');
    assert.deepEqual(obj, { a: 'c' });
    

    逻辑:

    1. 通过脚本给a标签渲染``href```属性
    changeNav( list,index ){
        location.href = `${list.href}&index=${index}` 
    }
    

    2.获取该导航选项所对应的index

    {index} = qs.parse( location.search.substr('1') )  //index: number
    // 加{ }标签是对象的结构赋值
    

    3.当前索引值即:通过href获取到的index值(string类型需转换为整型)
    curIndex: parseInt(index) || 0 //初始值为0

    • js部分
      大致和前面的步骤类似,引入各种插件、文件,获取数据,渲染到HTML
      注:input标签上绑定value值,```:value='keyword'
      search-热门分类页.png
    • mixin(混入)(对过滤器filterFoot.vue的优化)
      参考官方文档
      个人理解:mixins就是定义一部分公共的方法或者计算属性,然后混入到各个组件中使用,方便管理与统一修改
      1.modules文件夹下的js文件夹,新建mixin.js文件
    import Foot from 'components/Foot.vue'
    var mixin: {
      filter: {
        currency: function(price){
          ...
        }
      },
      components: {
        Foot
      }
    }
    export default mixin
    

    2.对应需要这些组件的文件中(index.jscategory.jssearch.js)等引入mixin

    import mixin from 'js/mixin'
    
    new Vue({
      mixins: [mixin]
    })
    
    • 回到顶部的动画效果动画库velocity
      参考文档:velocity-github官方文档npm velocity-animateVelocity.js中文文档
      yarn add velocity-animate
      安装velocity.png
      Velocity(document.body, 'scroll', {duration: 1000})
      html部分的<div class="container" ...>上绑定@touchmove="move"事件,<div class="go-to-top"...>上绑定@click="toTop"事件;删掉css部分对应.go-to-topdisplay: none
    遇到的问题document.body.scrollTop一直是0

    解决:

    • 页面指定了DTD,即指定了DOCTYPE时,使用document.documentElement
    • 页面没有DTD,即没指定DOCTYPE时,使用document.body
    注意:实现列表页触底加载功能,一定要注意需要滚动的是哪个DOM节点!!!首页是<ul class="js-list js-lazy" ...>;列表页是<div class="container with-top-search" ...>

    相关文章

      网友评论

          本文标题:Vue.js重构有赞商城(I)

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