mall1

image.png
ENV = 'development'

VUE_APP_BASE_API = 'http://itfly.vip:8888'
  ENV = 'production'

  VUE_APP_BASE_API = 'http://itfly.vip:8888'

vue.config.js

module.exports = {
  css: {
    loaderOptions: {
      css: {},
      postcss: {
        plugins: [
          require('postcss-px2rem')({
            remUnit: 37.5
          })
        ]
      }
    }
  },
  devServer: {
    // proxy: {
    //   '/api': {
    //     target: 'https://yys.res.netease.com', // 目标地址
    //     ws: true, /// / 是否启用websockets
    //     changeOrigin: true, // 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
    //     pathRewrite: { '^/api': '/' } // 这里重写路径
    //   }
    // }
    before(app) {
      app.get('/api', (req, res) => {
        res.send(require('./mock/data.json'))
      })
    }
  }
}

package.json

{
  "name": "vue-mall-phone-2105",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "build:prod": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.23.0",
    "core-js": "^3.6.5",
    "lib-flexible": "^0.3.2",
    "moment": "^2.29.1",
    "nprogress": "^0.2.0",
    "postcss-px2rem": "^0.3.0",
    "vant": "^2.0.5",
    "vue": "^2.6.11",
    "vue-router": "^3.5.2",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-vuex": "^4.5.14",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "babel-eslint": "^10.1.0",
    "babel-plugin-import": "^1.8.0",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "node-sass": "^4.14.1",
    "sass-loader": "^9.0.3",
    "vue-cli-plugin-route": "0.0.7",
    "vue-cli-plugin-vant": "~1.0.1",
    "vue-template-compiler": "^2.6.11"
  }
}

babel.config.js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

eslink

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/essential',
    '@vue/standard'
  ],
  parserOptions: {
    parser: 'babel-eslint'
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'space-before-function-paren': 0,
    'eol-last': 0,
    'no-multiple-empty-lines': 0
  }
}
image.png

image.png

api
goods

import request from '../utils/request'

export const getGoods = ({ page, limit }) => {
  return request({
    method: 'get',
    // eslint-disable-next-line quotes
    url: `/api/getgoods?pageindex=${page}&limit=${limit}`
  })
}

export const getGoodsInfo = id => {
  return request({
    method: 'get',
    url: '/api/goods/getinfo/' + id
  })
}

home

import request from '../utils/request'

export const getLunbo = () => {
  return request({
    method: 'get',
    url: '/api/getlunbo'
  })
}

export const getGrids = () => {
  return request({
    method: 'get',
    url: '/api/grids'
  })
}

news

import request from '../utils/request'

export const getNewsList = () => {
  return request({
    method: 'get',
    url: '/api/getnewslist'
  })
}
export const getNewsInfo = id => {
  return request({
    method: 'get',
    url: '/api/getnew/' + id
  })
}


export const getComments = ({ id, pageNo, pageSize }) => {
  return request({
    method: 'get',
    // eslint-disable-next-line quotes
    url: `/api/getcomments/${id}?pageindex=${pageNo}&limit=${pageSize}`
  })
}
export const postComments = ({ id, content }) => {
  return request({
    method: 'post',
    url: '/api/postcomment/' + id,
    data: {
      content
    }
  })
}

photos

import request from '../utils/request'

export const getImageCategory = () => {
  return request({
    method: 'get',
    url: '/api/getimgcategory'
  })
}

export const getImages = id => {
  return request({
    method: 'get',
    url: '/api/getimages/' + id
  })
}


export const getImageInfo = id => {
  return request({
    method: 'get',
    url: '/api/getimageInfo/' + id
  })
}

export const getThumImages = id => {
  return request({
    method: 'get',
    url: '/api/getthumimages/' + id
  })
}

components comment

<template>
  <div class="comment">
    <van-field
      class="content"
      v-model="message"
      rows="1"
      autosize
      label="发表评论"
      type="textarea"
      placeholder="请输入bb的内容"
      autofocus
      ref="fieldRef"
    />
    <van-button
      type="primary"
      block
      @click="postComments"
    >提交评论</van-button>

    <div class="comment-list">
      <van-card
        v-for="(item,index) in comments"
        :key="index"
        :desc="item.content"
      >
        <template #thumb>
          <van-icon name="https://b.yzcdn.cn/vant/icon-demo-1126.png" />
          <div>{{item.user_name}}</div>
        </template>
        <template #title>
          <van-rate
            v-model="value"
            readonly
          />
        </template>
        <template #price>
          {{item.add_time}}
        </template>
      </van-card>
    </div>
    <van-loading
      type="circular"
      v-if="isLoading"
      class="more"
    >
      加载中...
    </van-loading>
    <div
      v-else
      @click="getMore"
      class="more"
    >
      {{hasMore?'被掏空了': '加载更多'}}
    </div>
  </div>
</template>
<script>
import { getComments, postComments } from '@/api/news'
export default {
  props: ['id'],
  data() {
    return {
      message: '',
      value: 5,
      comments: [],
      pageNo: 0,
      pageSize: 3,
      hasMore: false,
      disabled: false,
      isLoading: false
    }
  },
  created() {
    this.getComments()
  },
  methods: {
    async getComments() {
      if (this.hasMore !== false) {
        this.disabled = true
        return
      }
      ++this.pageNo
      const res = await getComments({ id: this.id, pageNo: this.pageNo, pageSize: this.pageSize })
      this.comments = this.comments.concat(res.data.message)
      // 计算临界点
      this.hasMore = this.pageNo * this.pageSize > res.data.count
    },
    getMore() {
      this.isLoading = true
      setTimeout(() => {
        this.isLoading = false
        this.getComments()
      }, 1000)
    },
    async postComments() {
      if (this.message) {
        await postComments({ id: this.id, content: this.message })
        this.comments.unshift({
          user_name: '匿名用户',
          add_time: new Date().getTime(),
          content: this.message,
          rate: 5
        })

        this.message = ' '
        // this.$refs.fieldRef.focus()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.comment {
  .content {
    margin: 10px 0;
    border: 1px solid #ddd;
    padding: 10px 16px;
    height: 60px;
  }
  .comment-list {
    margin-top: 10px;
    .van-icon {
      font-size: 50px;
    }
    .van-card__desc {
      margin-top: 15px;
    }
  }
  .more {
    color: #969799;
    font-size: 14px;
    line-height: 50px;
    text-align: center;
  }
}
</style>

swiper

<template>
  <div>
    <van-swipe
      :autoplay="autoplay"
      indicator-color="white"
      class="my-swipe"
    >
      <van-swipe-item
        v-for="item in lunbolist"
        :key="item.id"
      >
        <img v-lazy="item.src||item.img">
      </van-swipe-item>
    </van-swipe>
  </div>
</template>
<script>
export default {
  props: {
    lunbolist: {},
    autoplay: {
      type: Number,
      default: 0
    }
  }
}
</script>
<style lang="scss" scoped>
.my-swipe {
  height: 150px;
  text-align: center;
  img {
    width: 50%;
    height: 100%;
  }
}
</style>

diretives

import Vue from 'vue'

Vue.directive('price', {
  inserted(el, binding) {
    console.log(el)
    el.textContent = binding.value + el.textContent
  }
})

// export default function (Vue) {
//   Vue.directive('price', {
//     inserted(el, binding) {
//       el.textContent = binding.value + el.textContent + '元'
//     }
//   })
// }

filters

import Vue from 'vue'
import moment from 'moment'

Vue.filter('datefmt', arg => {
  return moment(arg).format('YYYY-MM-DD HH:mm:ss')
})

mixins

// export default {
//   created() {
//     console.log('mixins created')
//   },
//   methods: {
//     goDetail(url, id) {
//       this.$router.push(url + '/' + id)
//     }
//   }
// }

import Vue from 'vue'

// 全局混入 容易变量 重复
Vue.mixin({
  methods: {
    goDetail(url, id) {
      this.$router.push(url + '/' + id)
    }
  }
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一、概念介绍 Vue.js和React.js分别是目前国内和国外最火的前端框架,框架跟类库/插件不同,框架是一套完...
    刘远舟阅读 1,035评论 0 0
  • 前言 接触vue框架也有一个多月的时间了,整理下之前做过的一个小demo,主要是熟悉vue全家桶技术,界面布局模仿...
    视觉派Pie阅读 26,478评论 20 285
  • vue2笔记 脚手架文件结构 ├── node_modules ├── public │ ├── favico...
    Daydream_许多阅读 194评论 0 0
  • #vue2笔记 ##脚手架文件结构 ├──node_modules ├──public │├──favicon.i...
    Daydream_许多阅读 421评论 0 0
  • 1、Saber框架简介 Saber框架是与BladeX框架匹配的前端框架,是在Vue-cli基础上,加载了多种组件...
    Ayanga阅读 4,276评论 0 0