VueDemo-7.首页展示

7.首页展示

 

7.1 展示nav导航

<template>
  <div class="box">
    <header class="header">home header</header>
    <div class="content">
      <div class="myswiper">
        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
          <van-swipe-item>1</van-swipe-item>
          <van-swipe-item>2</van-swipe-item>
          <van-swipe-item>3</van-swipe-item>
          <van-swipe-item>4</van-swipe-item>
        </van-swipe>
      </div>
      <van-grid icon-size="40px" :column-num="5" :border="false">
        <van-grid-item v-for="item of navList" :key="item.navid" :icon="item.imgurl" :text="item.title" />
      </van-grid>
    </div>
  </div>
</template>
<script>
import Vue from 'vue'
import { Swipe, SwipeItem, Grid, GridItem } from 'vant'
​
Vue.use(Swipe)
Vue.use(SwipeItem)
Vue.use(Grid)
Vue.use(GridItem)
export default {
  data () {
    return {
      navList: [
        { navid: 1, title: '嗨购超市', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/125678/35/5947/4868/5efbf28cEbf04a25a/e2bcc411170524f0.png' },
        { navid: 2, title: '数码电器', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png!q70.jpg' },
        { navid: 3, title: '嗨购服饰', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/41867/2/15966/7116/60ec0e0dE9f50d596/758babcb4f911bf4.png!q70.jpg' },
        { navid: 4, title: '嗨购生鲜', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png!q70.jpg.dpg' },
        { navid: 5, title: '嗨购到家', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196472/7/12807/7127/60ec0ea3Efe11835b/37c65625d94cae75.png!q70.jpg.dpg' },
        { navid: 6, title: '充值缴费', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/185733/21/13527/6648/60ec0f31E0fea3e0a/d86d463521140bb6.png!q70.jpg.dpg' },
        { navid: 7, title: '9.9元拼', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/36069/14/16068/6465/60ec0f67E155f9488/595ff3e606a53f02.png!q70.jpg.dpg' },
        { navid: 8, title: '领券', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/186080/16/13681/8175/60ec0fcdE032af6cf/c5acd2f8454c40e1.png!q70.jpg.dpg' },
        { navid: 9, title: '领金贴', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196711/35/12751/6996/60ec1000E21b5bab4/38077313cb9eac4b.png!q70.jpg.dpg' },
        { navid: 10, title: 'plus会员', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/37709/6/15279/6118/60ec1046E4b5592c6/a7d6b66354efb141.png!q70.jpg.dpg' }
      ]
    }
  }
}
</script>
​
<style lang='stylus' scoped>
// scoped 代表该样式只在当前组件是有效的,不会影响其他组件的样式
.myswiper
  height 150px
  width 96%
  margin 10px 2%
​
.my-swipe
  border-radius 10px
  height 100%
</style>
​

7.2做好接口的准备工作

接口地址:Loading...

7.3 vue项目中进行数据的请求 - 演示 - 基础

yarn add axios -S    /   cnpm i axios -S

如果项目的开发过程中遇到了如下错误

上图说明 发生了跨域的问题。No 'Access-Control-Allow-Origin' header is present on the requested resource.

跨域问题 ---- 同源策略 --- 协议+域名+端口

// commonjs规范
module.exports = {}    ====>   const module = require(path)
​
// es6 模块化
export default {}     =====>   import module from 'path'
​
export const str = '1'   
export const str1 = '2'  
export const str2 = '3'    =====>   import { str, str1, str2 } from 'path'
​
export function fn1 () {}
export function fn2 () {}
export function fn3 () {}  =====> import { fn1, fn2, fn3 } from 'path'
  • 2.axios的get请求和post请求

axios.get('url?id=1').then(res=> console.log(res)) // 1
axios.get('url', { params: { id: 1} }).then(res => console.log(res)) // 2
​
axios.post('url', { id: 1 }).then(res => console.log(res)) // 3
​
axios({}) // 4 
  • 3.自定义axios

项目中创建utils文件夹,用来存放我们自己封装的一些方法

// src/utils/request.js

import axios from 'axios'
​
// 自定义axios
// const ins = axios.create({
//   // baseURL 以后调用接口可以不用写这个,程序会自动拼接
//   baseURL: 'http://121.89.205.189:3001/api',
//   timeout: 6000 // 请求的超时时间
// })
​
// 环境 - 开发环境 | 测试环境 | 生产环境
//       localhost |  ip地址  |  域名
//      yarn serve | yarn build  | yarn build
//      development |       |  production
// process 属于nodejs自带的一个全局的模块 ---- 进程
// http://nodejs.cn/api/process.html#processenv
// process.env ---- 判断环境
// process.env 本身并没有 NODE_ENV 这个变量,程序脚手架设置的 -- webpack 设置
const isDev = process.env.NODE_ENV === 'development' // 判断当前的运行环境的
​
const ins = axios.create({
  baseURL: isDev ? 'http://121.89.205.189:3001/api' : 'http://121.89.205.189:3001/api',
  timeout: 6000 // 请求的超时时间
})
​
// 请求拦截器
ins.interceptors.request.use((config) => {
  // 比如登录的验证 - token
  return config
}, (error) => {
  return Promise.reject(error)
})
​
// 响应拦截器
ins.interceptors.response.use((response) => {
  // 验证登录,如果验证不通过,可以跳转到登录页面,验证通过,返回想要的数据
  return response
}, (error) => {
  return Promise.reject(error)
})
​
export default ins
​
  • 4.跨域问题

    • 前端解决 ----- 代理

    • 后端解决 ----- 设置接口无跨域

      app.all("*",function(req,res,next){
        //设置允许跨域的域名,*代表允许任意域名跨域
      // res.header("Access-Control-Allow-Origin","http://localhost:8081"); // 白名单
        res.header("Access-Control-Allow-Origin","*");
        //允许的header类型, content-type
        res.header("Access-Control-Allow-Headers","*");
        //跨域允许的请求方式
        res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
        next();
      });

module.exports = {
  devServer: {
    // proxy: 'http://121.89.205.189/api' // string 形式
    proxy: {
      '/api': {
        target: 'http://121.89.205.189/api',
        ws: true,
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}
​
import axios from 'axios'
​
// development 开发环境   production 生产环境
const isDev = process.env.NODE_ENV === 'development'
​
// baseURL 会自动加到所有的请求之前
const request = axios.create({
  // http://121.89.205.189/api/pro/list ==> /pro/list
  baseURL: isDev ? '/api' : 'http://121.89.205.189/api',
  timeout: 6000
})
​
// 拦截器
request.interceptors.request.use(config => {
  return config
}, err => Promise.reject(err))
request.interceptors.response.use(response => {
  return response
}, err => Promise.reject(err))
​
export default request
​

7.4 数据请求的流程

  • 1.如果项目的接口有跨域的问题,项目的根目录下创建 vue.config.js文件

配置完成重新运行项目

vue.config.js 其实可以看作是 webpack.config.js 配置的重写

Webpack 是 前端模块化开发,组件化开发的利器,之后会专门的讲解

  • 2.src/api文件夹下封装 各个模块的数据请求

产品模块相关的接口 src/api/home.js

// request 即为自定义封装的axios
import request from './../utils/request'
/**
 * 首页轮播图的请求封装
 */
export function getBannerList () {
  return request.get('/banner/list')
}
/**
 * 首页秒杀列表的封装
 * @param {Object} params { count: 1, limitNum: 6 }
 */
export function getSeckillList (params) {
  // get请求的参数
  return request.get('/pro/seckilllist', { params })
}
​
/**
 * 首页分页列表的封装
 * @param {Object} params { count: 1, limitNum: 10 }
 */
export function getProList (params) {
  return request.get('/pro/list', { params })
}
​
  • 3.首页请求轮播图的数据

<template>
  <div class="box">
    <header class="header">home header</header>
    <div class="content">
      <div class="myswiper">
        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
          <van-swipe-item v-for="item of bannerList" :key="item.bannerid">
            <van-image
              :src="item.img"
            />
          </van-swipe-item>
        </van-swipe>
      </div>
      <van-grid icon-size="40px" :column-num="5" :border="false">
        <van-grid-item v-for="item of navList" :key="item.navid" :icon="item.imgurl" :text="item.title" />
      </van-grid>
    </div>
  </div>
</template>
<script>
import Vue from 'vue'
import { Swipe, SwipeItem, Grid, GridItem, Image as VanImage } from 'vant'
import { getBannerList } from '@/api/home' // @ 代表的就是src的目录
Vue.use(Swipe)
Vue.use(SwipeItem)
Vue.use(Grid)
Vue.use(GridItem)
Vue.use(VanImage)
export default {
  data () {
    return {
      navList: [
        { navid: 1, title: '嗨购超市', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/125678/35/5947/4868/5efbf28cEbf04a25a/e2bcc411170524f0.png' },
        { navid: 2, title: '数码电器', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png!q70.jpg' },
        { navid: 3, title: '嗨购服饰', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/41867/2/15966/7116/60ec0e0dE9f50d596/758babcb4f911bf4.png!q70.jpg' },
        { navid: 4, title: '嗨购生鲜', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png!q70.jpg.dpg' },
        { navid: 5, title: '嗨购到家', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196472/7/12807/7127/60ec0ea3Efe11835b/37c65625d94cae75.png!q70.jpg.dpg' },
        { navid: 6, title: '充值缴费', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/185733/21/13527/6648/60ec0f31E0fea3e0a/d86d463521140bb6.png!q70.jpg.dpg' },
        { navid: 7, title: '9.9元拼', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/36069/14/16068/6465/60ec0f67E155f9488/595ff3e606a53f02.png!q70.jpg.dpg' },
        { navid: 8, title: '领券', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/186080/16/13681/8175/60ec0fcdE032af6cf/c5acd2f8454c40e1.png!q70.jpg.dpg' },
        { navid: 9, title: '领金贴', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196711/35/12751/6996/60ec1000E21b5bab4/38077313cb9eac4b.png!q70.jpg.dpg' },
        { navid: 10, title: 'plus会员', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/37709/6/15279/6118/60ec1046E4b5592c6/a7d6b66354efb141.png!q70.jpg.dpg' }
      ],
      bannerList: []
    }
  },
  mounted () {
    getBannerList().then(res => {
      console.log(res.data)
      this.bannerList = res.data.data
    })
  }
}
</script>
​
<style lang='stylus' scoped>
// scoped 代表该样式只在当前组件是有效的,不会影响其他组件的样式
.myswiper
  height 150px
  width 96%
  margin 10px 2%
​
.my-swipe
  border-radius 10px
  height 100%
</style>
​

  • 4.首页请求 秒杀的列表数据 src/views/home/index.vue

<template>
  <div class="box">
    <header class="header">home header</header>
    <div class="content">
      <div class="myswiper">
        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
          <van-swipe-item v-for="item of bannerList" :key="item.bannerid">
            <van-image
              :src="item.img"
            />
          </van-swipe-item>
        </van-swipe>
      </div>
      <van-grid icon-size="40px" :column-num="5" :border="false">
        <van-grid-item v-for="item of navList" :key="item.navid" :icon="item.imgurl" :text="item.title" />
      </van-grid>
      <!-- ++++++++++++++++++ -->
      <ul class="seckillTitle">
        <li>嗨购秒杀</li>
        <li>
          <van-count-down :time="time">
            <template #default="timeData">
              <span class="block">{{ timeData.hours }}</span>
              <span class="colon">:</span>
              <span class="block">{{ timeData.minutes }}</span>
              <span class="colon">:</span>
              <span class="block">{{ timeData.seconds }}</span>
            </template>
          </van-count-down>
        </li>
        <li>
          更多秒杀
          <van-icon name="clock" color="#f66" size="16"/>
        </li>
      </ul>
      <ul class="seckillList">
        <li v-for="item of seckillList" :key="item.proid">
          <van-image
            width="55px"
            height="55px"
            :src="item.img1"
          />
          <p>
            ¥{{ item.originprice }}
          </p>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import Vue from 'vue'
// ++++++++++++++
import { Swipe, SwipeItem, Grid, GridItem, Image as VanImage, CountDown, Icon } from 'vant'
// ++++++++++++++
import { getBannerList, getSeckillList } from '@/api/home' // @ 代表的就是src的目录
Vue.use(Swipe)
Vue.use(SwipeItem)
Vue.use(Grid)
Vue.use(GridItem)
Vue.use(VanImage)
Vue.use(CountDown) // ++++++++++++++
Vue.use(Icon) // ++++++++++++++
export default {
  data () {
    return {
      navList: [
        { navid: 1, title: '嗨购超市', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/125678/35/5947/4868/5efbf28cEbf04a25a/e2bcc411170524f0.png' },
        { navid: 2, title: '数码电器', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png!q70.jpg' },
        { navid: 3, title: '嗨购服饰', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/41867/2/15966/7116/60ec0e0dE9f50d596/758babcb4f911bf4.png!q70.jpg' },
        { navid: 4, title: '嗨购生鲜', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png!q70.jpg.dpg' },
        { navid: 5, title: '嗨购到家', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196472/7/12807/7127/60ec0ea3Efe11835b/37c65625d94cae75.png!q70.jpg.dpg' },
        { navid: 6, title: '充值缴费', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/185733/21/13527/6648/60ec0f31E0fea3e0a/d86d463521140bb6.png!q70.jpg.dpg' },
        { navid: 7, title: '9.9元拼', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/36069/14/16068/6465/60ec0f67E155f9488/595ff3e606a53f02.png!q70.jpg.dpg' },
        { navid: 8, title: '领券', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/186080/16/13681/8175/60ec0fcdE032af6cf/c5acd2f8454c40e1.png!q70.jpg.dpg' },
        { navid: 9, title: '领金贴', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196711/35/12751/6996/60ec1000E21b5bab4/38077313cb9eac4b.png!q70.jpg.dpg' },
        { navid: 10, title: 'plus会员', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/37709/6/15279/6118/60ec1046E4b5592c6/a7d6b66354efb141.png!q70.jpg.dpg' }
      ],
      bannerList: [],
      seckillList: [], // ++++++++++++++
      time: 3 * 60 * 60 * 1000 // ++++++++++++++
    }
  },
  mounted () {
    getBannerList().then(res => {
      // console.log(res.data)
      this.bannerList = res.data.data
    })
    getSeckillList().then(res => { // ++++++++++++++
      console.log(res.data)
      this.seckillList = res.data.data
    })
  }
}
</script>
​
<style lang='stylus' scoped>
// scoped 代表该样式只在当前组件是有效的,不会影响其他组件的样式
.myswiper
  height 150px
  width 96%
  margin 10px 2%
​
.my-swipe
  border-radius 10px
  height 100%
​
.seckillList
  display flex
  li
    flex 1
    height 0.7rem
    display flex
    flex-direction column
    justify-content center
    align-items center
    .van-image
      img
        width 0.55rem
        height 0.55rem
    p
      color #f66
.colon { // ++++++++++++++
  display: inline-block;
  margin: 0 4px;
  color: #ee0a24;
}
.block { // ++++++++++++++
  display: inline-block;
  width: 22px;
  color: #fff;
  font-size: 12px;
  text-align: center;
  background-color: #f66;
}
.seckillTitle // ++++++++++++++
  display flex
  height 0.4rem
  li
    text-align left
    &:nth-child(1)
      width 60px
      margin-left 10px
      font-size 14px
      font-weight bold
    &:nth-child(3)
      width 120px
      text-align right
      font-size 14px
      margin-right 10px
      color #f66
      .van-icon
        transform rotate(225deg)
    &:nth-child(2)
      flex: 1
​
</style>
​

7.5 请求首页产品列表的数据

观察京东的分类页面,得知,可以点击切换产品列表的展示形

  • 1创建产品的列表组件

    src/components/ProList.vue

    <template>
      <div>产品列表</div>
    </template>
    ​
  • 2.首页引入产品列表组件

<template>
  <div class="box">
    <header class="header">home header</header>
    <div class="content">
        ...
      <!-- 产品列表 -->
      <ProList />
    </div>
  </div>
</template>
<script>
...
import ProList from '@/components/ProList'
...
export default {
  components: {
    ProList
  },
  ....
}
</script>
​
<style lang="stylus">
...
</style>
​
  • 3.设计产品列表的样式

<template>
  <ul class="proList " :class="'cols_' + num">
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <div class="changeIcon" @click="num = num === 1 ? 2 : 1">
      <van-icon name="apps-o" v-if="num === 1" size="24"/>
      <van-icon name="bars" v-else size="24"/>
    </div>
  </ul>
</template>
<script>
import Vue from 'vue'
import { Image as VanImage, Icon } from 'vant'
Vue.use(VanImage)
Vue.use(Icon)
export default {
  data () {
    return {
      num: 1
    }
  }
}
</script>
​
<style lang="stylus" scoped>
.proList
  &.cols_1 // 左图右文
    .proItem
      height 1rem
      display flex
      .itemImage
        width 1rem
        height 1rem
        border 1px solid #cccccc
        box-sizing border-box
        .van-image
          img
            width 0.94rem
            height 0.94rem
            margin 0.03rem
            display block
            border 1px solid #f66
            box-sizing border-box
      .itemInfo
        flex 1
        height 1rem
        box-sizing border-box
        padding 5px 10px
        border-bottom 1px solid #ccc
        .proname
          font-size 14px
        .price
          color #f66
  &.cols_2 // 上图下文
    display flex
    flex-wrap wrap
    .proItem
      width 48%
      margin 3px 1%
      .itemImage
        height 1.7rem
        width 100%
        .van-image
          width 100%
          height 100%
          overflow hidden
          border 1px solid #ccc
          img
            width 100%
            height 100%
            display block
      .itemInfo
        padding 3px 10px
        background-color #fff
        .proname
          font-size 14px
        .price
          color #f66
.changeIcon
  position fixed
  width 32px
  height 32px
  border-radius 50%
  border 1px solid #cccccc
  display flex
  justify-content center
  align-items center
  bottom 60px
  right 10px
  background-color #fff
</style>
​

// src/App.vue

  • 5.首页引入数据请求方法以及请求数据 src/views/home/index.vue

<template>
  <div class="box">
    <header class="header">home header</header>
    <div class="content">
      <div class="myswiper">
        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
          <van-swipe-item v-for="item of bannerList" :key="item.bannerid">
            <van-image
              :src="item.img"
            />
          </van-swipe-item>
        </van-swipe>
      </div>
​
      <van-grid icon-size="40px" :column-num="5" :border="false">
        <van-grid-item v-for="item of navList" :key="item.navid" :icon="item.imgurl" :text="item.title" />
      </van-grid>
      <ul class="seckillTitle">
        <li>嗨购秒杀</li>
        <li>
          <van-count-down :time="time">
            <template #default="timeData">
              <span class="block">{{ timeData.hours }}</span>
              <span class="colon">:</span>
              <span class="block">{{ timeData.minutes }}</span>
              <span class="colon">:</span>
              <span class="block">{{ timeData.seconds }}</span>
            </template>
          </van-count-down>
        </li>
        <li>
          更多秒杀
          <van-icon name="clock" color="#f66" size="16"/>
        </li>
      </ul>
      <ul class="seckillList">
        <li v-for="item of seckillList" :key="item.proid">
          <van-image
            width="55px"
            height="55px"
            :src="item.img1"
          />
          <p>
            ¥{{ item.originprice }}
          </p>
        </li>
      </ul>
      <!-- 产品列表 ++++++++++++++++++++++ -->
      <ProList :proList = "proList"/>
    </div>
  </div>
</template>
<script>
import Vue from 'vue'
import { Swipe, SwipeItem, Grid, GridItem, Image as VanImage, CountDown, Icon } from 'vant'
  // ++++++++++++++++++++
import { getBannerList, getSeckillList, getProList } from '@/api/home' // @ 代表的就是src的目录
import ProList from '@/components/ProList'
Vue.use(Swipe)
Vue.use(SwipeItem)
Vue.use(Grid)
Vue.use(GridItem)
Vue.use(VanImage)
Vue.use(CountDown)
Vue.use(Icon)
export default {
  components: {
    ProList
  },
  data () {
    return {
      navList: [
        { navid: 1, title: '嗨购超市', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/125678/35/5947/4868/5efbf28cEbf04a25a/e2bcc411170524f0.png' },
        { navid: 2, title: '数码电器', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png!q70.jpg' },
        { navid: 3, title: '嗨购服饰', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/41867/2/15966/7116/60ec0e0dE9f50d596/758babcb4f911bf4.png!q70.jpg' },
        { navid: 4, title: '嗨购生鲜', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png!q70.jpg.dpg' },
        { navid: 5, title: '嗨购到家', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196472/7/12807/7127/60ec0ea3Efe11835b/37c65625d94cae75.png!q70.jpg.dpg' },
        { navid: 6, title: '充值缴费', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/185733/21/13527/6648/60ec0f31E0fea3e0a/d86d463521140bb6.png!q70.jpg.dpg' },
        { navid: 7, title: '9.9元拼', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/36069/14/16068/6465/60ec0f67E155f9488/595ff3e606a53f02.png!q70.jpg.dpg' },
        { navid: 8, title: '领券', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/186080/16/13681/8175/60ec0fcdE032af6cf/c5acd2f8454c40e1.png!q70.jpg.dpg' },
        { navid: 9, title: '领金贴', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/196711/35/12751/6996/60ec1000E21b5bab4/38077313cb9eac4b.png!q70.jpg.dpg' },
        { navid: 10, title: 'plus会员', imgurl: 'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/37709/6/15279/6118/60ec1046E4b5592c6/a7d6b66354efb141.png!q70.jpg.dpg' }
      ],
      bannerList: [],
      seckillList: [],
      proList: [], // ++++++++++++++++++++
      time: 3 * 60 * 60 * 1000
    }
  },
  mounted () {
    getBannerList().then(res => {
      // console.log(res.data)
      this.bannerList = res.data.data
    })
    getSeckillList().then(res => {
      console.log(res.data)
      this.seckillList = res.data.data
    })
    getProList().then(res => { // ++++++++++++++++++++
      this.proList = res.data.data
    })
  }
}
</script>
​
<style lang='stylus' scoped>
// scoped 代表该样式只在当前组件是有效的,不会影响其他组件的样式
.myswiper
  height 150px
  width 96%
  margin 10px 2%
​
.my-swipe
  border-radius 10px
  height 100%
​
.seckillList
  display flex
  li
    flex 1
    height 0.7rem
    display flex
    flex-direction column
    justify-content center
    align-items center
    .van-image
      img
        width 0.55rem
        height 0.55rem
    p
      color #f66
.colon {
  display: inline-block;
  margin: 0 4px;
  color: #ee0a24;
}
.block {
  display: inline-block;
  width: 22px;
  color: #fff;
  font-size: 12px;
  text-align: center;
  background-color: #f66;
}
.seckillTitle
  display flex
  height 0.4rem
  li
    text-align left
    &:nth-child(1)
      width 60px
      margin-left 10px
      font-size 14px
      font-weight bold
    &:nth-child(3)
      width 120px
      text-align right
      font-size 14px
      margin-right 10px
      color #f66
      .van-icon
        transform rotate(225deg)
    &:nth-child(2)
      flex: 1
​
</style>
​
  • 6.渲染产品列表的数据

s r c/components/ProList.vue

<template>
  <ul class="proList " :class="'cols_' + num">
    <li class="proItem" v-for="item of proList" :key="item.proid">
      <div class="itemImage">
        <van-image :src="item.img1"/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">{{ item.proname }}</div>
        <div class="price">¥{{ item.originprice }}</div>
      </div>
    </li>
    <!-- <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li>
    <li class="proItem">
      <div class="itemImage">
        <van-image src=""/>
      </div>
      <div class="itemInfo">
        <div class="proname van-multi-ellipsis--l2">产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称产品名称</div>
        <div class="price">¥111</div>
      </div>
    </li> -->
    <div class="changeIcon" @click="num = num === 1 ? 2 : 1">
      <van-icon name="apps-o" v-if="num === 1" size="24"/>
      <van-icon name="bars" v-else size="24"/>
    </div>
  </ul>
</template>
<script>
import Vue from 'vue'
import { Image as VanImage, Icon } from 'vant'
Vue.use(VanImage)
Vue.use(Icon)
export default {
  data () {
    return {
      num: 1
    }
  },
  props: {// ++++++++++
    proList: {
      type: Array,
      require: true
    }
  }
}
</script>
​
<style lang="stylus" scoped>
.proList
  &.cols_1 // 左图右文
    .proItem
      height 1rem
      display flex
      background-color #fff
      .itemImage
        width 1rem
        height 1rem
        // border 1px solid #cccccc
        box-sizing border-box
        .van-image
          width 0.94rem
          height 0.94rem
          margin 0.03rem
          img
            width 0.94rem
            height 0.94rem
            margin 0.03rem
            display block
            // border 1px solid #f66
            box-sizing border-box
      .itemInfo
        flex 1
        height 1rem
        box-sizing border-box
        padding 5px 10px
        border-bottom 1px solid #ccc
        .proname
          font-size 14px
        .price
          color #f66
  &.cols_2 // 上图下文
    display flex
    flex-wrap wrap
    .proItem
      width 48%
      margin 3px 1%
      .itemImage
        height 1.7rem
        width 100%
        .van-image
          width 100%
          height 100%
          overflow hidden
          border 1px solid #ccc
          img
            width 100%
            height 100%
            display block
      .itemInfo
        padding 3px 10px
        background-color #fff
        .proname
          font-size 14px
          height 32px
        .price
          color #f66
.changeIcon
  position fixed
  width 32px
  height 32px
  border-radius 50%
  border 1px solid #cccccc
  display flex
  justify-content center
  align-items center
  bottom 60px
  right 10px
  background-color #fff
</style>
​
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手把手进行Django Vue前后端分离开发的入门,可以通过以下步骤实现: 1. 首先,确保已经安装了Python和Node.js,以及相应的开发环境。 2. 创建一个Django项目,可以使用命令`django-admin startproject project_name`来创建项目。 3. 进入项目目录,创建一个Django应用,可以使用命令`python manage.py startapp app_name`来创建应用。 4. 在Django中配置应用,包括数据库连接、URL路由等,可在`settings.py`中进行配置。 5. 创建数据库模型,可以在应用目录下的`models.py`中定义模型类,表示数据表结构。 6. 执行迁移命令,将模型映射到数据库中,可使用命令`python manage.py makemigrations`和`python manage.py migrate`执行。 7. 在应用目录下创建视图函数,用于处理客户端的请求,其中可以包括接收和发送JSON数据。 8. 在`urls.py`中配置URL路由,将请求的URL与对应的视图函数进行关联。 9. 使用Vue CLI创建Vue项目,可以使用命令`vue create frontend`来创建项目。 10. 在Vue项目中安装axios,用于发送HTTP请求,可以使用命令`npm install axios`进行安装。 11. 按照需求,在Vue组件中编写前端代码,可以使用axios与后端进行数据交互,获取数据并展示。 12. 运行Django项目,可以使用命令`python manage.py runserver`来启动Django服务器。 13. 运行Vue项目,可以使用命令`npm run serve`来启动Vue开发服务器。 通过以上步骤,即可实现Django Vue前后端分离开发入门。在实践中,可以进一步学习和了解Django和Vue的相关文档和教程,通过不断实践和探索,提升开发技能。相关的示例代码和项目实例可以参考知乎上的文章。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值