• vue使用jsonp获取数据,开发热卖推荐组件


    1、安装jsonp

    cnpm install --save jsonp

    2、jsonp API

    jsonp( url, opts, fn )

    3、封装jsonp方法

    src/assets/js/jsonp.js

    import jsonp from 'jsonp';
    
    /*data格式案例
    {
        id:1,
        name:'cyy'
    }
    */
    const parseParam=param=>{
        /*将data格式转换为
        [
            [id,1],
            [name,cyy]
        ]
        */
        let arr=[];
        for(const key in param){
            arr.push([key,param[key]]);
        }
        /*先将data格式转换为
        [
            id=1,
            name=cyy
        ]
        */
       /*再将data格式转换为
        id=1&name=cyy
        */
        return arr.map(value=>value.join("=")).join('&');
    }
    
    export default (url,data,options)=>{
        // 如果存在?,则url后面加&;如果不存在则加?
        url+=((url.indexOf('?')<0) ? '?' : '&' ) + parseParam(data);
    
        return new Promise((resolve,reject)=>{
            
            //jsonp用法,三个参数:jsonp(url,options,callback)
            jsonp(url,options,(err,data)=>{
                if(err){
                    reject(err);
                }else{
                    resolve(data);
                }
            })
        })
    }

    4、调用jsonp方法

    src/api/recommend.js

    import jsonp from 'assets/js/jsonp';
    
    //获取热门推荐数据
    export const getHomeRecommend=(page=1,psize=20)=>{
        const url='https://ju.taobao.com/json/tg/ajaxGetItemsV2.json';
        const params={
            page,
            psize,
            type:0,
            frontCatId:''//type和frontCatId是根据给定的淘宝接口来添加的
        }
    
        //调用jsonp获取数据
        return jsonp(url,params,{
            param:'callback'
        }).then(res=>{
            if(res.code==='200'){
                return res;
            }
    
            throw new Error('没有成功获取到数据');
        }).catch(err=>{
            if(err){
                console.log(err);
            }
            
        });
        
    }

    5、通过jsonp获取热门推荐的数据,并渲染到页面上

    src/pages/home/recommend.vue

    <template>
        <div class="recommend">
            <h3 class="recommend-title">热卖推荐</h3>
            <div class="loading-container" v-if="!recommends.length">
                <me-loading inline />
            </div>
            <ul class="recommend-list">
                <li class="recommend-item" v-for="(item,index) in recommends" :key="index">
                    <router-link class="recommend-link" :to="{name:'home-product',params:{id:item.baseinfo.itemId}}">
                        <p class="recommend-pic"><img class="recommend-img" :src="item.baseinfo.picUrl"></p>
                        <p class="recommend-name">{{item.name.shortName}}</p>
                        <p class="recommend-oriPrice"><del>¥{{item.price.origPrice}}</del></p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">{{item.price.actPrice}}</strong></span>
                            <span class="recommend-count">{{item.remind.soldCount}}件已售</span>
                        </p>
                    </router-link>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
    import {getHomeRecommend} from 'api/recommend';
    import MeLoading from 'components/loading';
    
    export default {
        name:"Recommend",
        data(){
            return {
               recommends:[],
               curPage:1,
               totalPage:1
            }
        },
        components:{
            MeLoading
        },
        created(){
            this.getRecommends();        
        },
        methods:{
            getRecommends(){           
                if(this.curPage>this.totalPage) return Promise.reject(new Error('没有更多了'));
    
                return getHomeRecommend(this.curPage).then(data=>{
                    return new Promise(resolve=>{
                  
                        if(data){
                            console.log(data);
                            
                            this.curPage++;
                            this.totalPage=data.totalPage;
    
                            // concat合并数组内容,每次获取的数据都追加进来
                            this.recommends=this.recommends.concat(data.itemList);
    
                            this.$emit("loaded",this.recommends);//热门推荐区域加载完毕后触发消息
                            resolve();
                        }
                    })
                });
            }
        }
    }
    </script>
    
    <style lang="scss" scoped>
    
        .recommend{
            position:relative;
            100%;
            padding:10px 0;
            font-size:14px;
            text-align:center;
            background:#fff;
    
            &:before,
            &:after{
                content:"";
                display:block;
                position:absolute;
                top:14%;
                40%;
                height:1px;
                background:#ddd;
            }
    
            &:before{
                left:0;        
            }
    
            &:after{
                right:0;
            }
        }
        .recommend-list{
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap:wrap;
        }
        .recommend-title{
            margin-bottom:8px;
        }
        .recommend-item{
            49%;
            background:#fff;
            box-shadow:0 1px 1px 0 rgba(0,0,0,0.12);
            margin-bottom:8px;
        }
        .recommend-link{
            display:block;
        }
        .recommend-pic{
            position:relative;
            100%;
            padding-top:100%;// 可以实现高度与宽度一致
            margin-bottom:5px;
        }
        .recommend-img{
            100%;
            position:absolute;
            top:0;
            left:0;
            height:100%;
        }
        .recommend-name{
            height:40px;
            padding:0 5px;
            margin-bottom:8px;
            line-height:1.5;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            white-space: normal !important;
            word-wrap: break-word;
            text-align:left;
    
        }
        .recommend-oriPrice{
            padding:0 5px;
            margin-bottom:8px;
            color:#ccc;
            text-align:left;
        }
        .recommend-info{
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding:0 5px;
            margin-bottom:8px;
        }
        .recommend-price{
            color:#e61414;
    
            &-num{
                font-size:20px;
            }
        }
        .recommend-count{
            color:#999;
        }
        .loading-container{
            padding-top:80px;
        }
         
    </style>

    6、首页中使用recommend组件

    src/pages/home/index.vue

    <template>
        <div class="home">
            <scrollbar :data="recommends">
                <slider />
                <home-nav />
                <!-- 热门推荐加载完成后更新滚动条 -->
                <recommend @loaded="updateScroll" />
            </scrollbar>
            <!-- 该页面自己的子路由 -->
            <router-view></router-view>
        </div>
    
    </template>
    
    <script>
    import Slider from 'components/slider';
    import Scrollbar from 'components/scroll';
    import HomeNav from './nav';
    import Recommend from './recommend';
    
    export default {
        name:"Home",
        components:{
            Slider,   
            Scrollbar,
            HomeNav,
            Recommend    
        },
        data(){
            return{
                recommends:[]
            }
        },
        methods:{
            updateScroll(recommends){
                this.recommends=recommends;
            }
        }
    }
    </script>
    
    <style scoped>
        .home{
            100%;
            height:100%;
        }
    </style>

    7、修改scroll组件,在热门推荐加载之后更新滚动条

    src/components/scroll/index.vue

    <template>
        <swiper class="swiper" :options="swiperOption" ref="swiper">
        <swiper-slide>
            <!-- 所有内容放在插槽里 -->
            <slot></slot>
        </swiper-slide>
        <div class="swiper-scrollbar" slot="scrollbar"></div>
      </swiper>
    </template>
    
    <script>
      import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
      import 'swiper/css/swiper.css';
    
      export default {
        name: 'Scrollbar',
        title: 'Scrollbar',
        components: {
          Swiper,
          SwiperSlide
        },
        data() {
          return {
            swiperOption: {
              scrollbar: {
                el: '.swiper-scrollbar',
                hide: true
              },
              direction:'vertical',
              slidesPerView:'auto',
              freeMode:true,
              setWrapperSize:true
            }
          }
        },
        props:{
          recommends:{
            type:[Array,Object],
            default(){
              return [];
            }
          }
        },
        watch:{//当recommends值发生改变时
          recommends(){
            this.$refs.swiper && this.$refs.swiper.$swiper.update();//更新滚动条长度
          }
        }
      }
    </script>
    
    <style lang="scss" scoped>
        .swiper-container{
            100%;
            height:100%;
            overflow:hidden;
        }
        .swiper-wrapper{
            height:auto;
        }
        .swiper-slide{
            height:auto;
        }
    </style>

    效果图

  • 相关阅读:
    spring boot 中@Mapper和@Repository的区别
    yarn和npm的对比以及yarn的使用
    vue环境搭建
    小白的springboot之路(六)、跨域解决方案CORS
    DWR3.0框架入门(1) —— 实现ajax
    DWR3.0框架入门(3) —— ScriptSession的维护及优化
    DWR3.0框架入门(2) —— DWR的服务器推送
    Freemarker入门案例
    dom4j生成和解析xml文件
    struts2拦截器-自定义拦截器,放行某些方法(web.xml配置)
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12641872.html
Copyright © 2020-2023  润新知