WebApp商城

一:準(zhǔn)備工作
1、項(xiàng)目結(jié)構(gòu)
compnents文件夾 存放整個項(xiàng)目公共的組件
assets文件夾 存放樣式和字體圖標(biāo)
api文件夾 存放請求文件
pages文件夾存放項(xiàng)目頁面
pages文件夾中有conponents存放的是頁面級的公共組件
2鳖粟、搭建開發(fā)環(huán)境

  1. 初始化項(xiàng)目
npm init

2)安裝開發(fā)依賴

npm install --save-dev css-loader@4.2.1 style-loader@1.2.1 file-loader@6.0.0 url-loader@4.1.0 

3)安裝生產(chǎn)依賴

npm install art-template@4.13.2 swiper@6.1.1 

4)修改scripts屬性值

"start": "webpack-dev-server --open chrome" 

3删铃、配置webpack.config.js文件

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 獲取絕對路徑
const resolve = dir => path.resolve(__dirname, dir);

module.exports = {
  mode: 'development',
  // Webpack 入口文件
  entry: {
    index: './src/pages/index',
    destination: './src/pages/destination'
  },
  // Webpack 輸出路徑
  output: {
    // 輸出的目錄
    path: resolve('dist'),
    // 輸出的文件名
    filename: 'js/[name].js'
  },
  // source-map踱蠢,調(diào)試用的,出錯的時候,將直接定位到原始代碼阵谚,而不是轉(zhuǎn)換后的代碼
  devtool: 'cheap-module-eval-source-map',
  resolve: {
    // 自動補(bǔ)全(可以省略)的擴(kuò)展名
    extensions: ['.js'],
    // 路徑別名
    alias: {
      api: resolve('src/api'),
      icons: resolve('src/assets/icons'),
      styles: resolve('src/assets/styles'),
      components: resolve('src/components'),
      pages: resolve('src/pages'),
      utils: resolve('src/utils')
    }
  },
  // 不同類型模塊的處理規(guī)則
  module: {
    rules: [
      // css
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // 模板文件
      {
        test: /\.art$/,
        loader: 'art-template-loader'
      },
      // 圖片
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        loader: 'url-loader',
        options: {
          // 小于 10K 的圖片轉(zhuǎn)成 base64 編碼的 dataURL 字符串寫到代碼中
          limit: 10000,
          // 其他的圖片轉(zhuǎn)移到
          name: 'images/[name].[ext]',
          esModule: false
        }
      },
      // 字體文件
      {
        test: /\.(woff2?|eot|ttf|otf)$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: 'fonts/[name].[ext]'
        }
      }
    ]
  },
  plugins: [
    // 自動將依賴注入 html 模板钞翔,并輸出最終的 html 文件到目標(biāo)文件夾
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './src/pages/index/index.art',
      chunks: ['index']
    }),
    new HtmlWebpackPlugin({
      filename: 'destination.html',
      template: './src/pages/destination/destination.art',
      chunks: ['destination']
    })
  ]
};

二严卖、首頁開發(fā)
1、頭部組件布轿,下方代碼是components/header/index.js

import './header.css';

// 需要添加的類名
const CHANGED_CLASS_NAME = 'header-transition';
// 初始狀態(tài)哮笆,主要是為了防止多次觸發(fā)的問題
const INIT_STATE = 'init';
// 改變狀態(tài),主要是為了防止多次觸發(fā)的問題
const CHANGED_STATE = 'changed';

// 添加Header類
class Header {
 // 需要傳遞四個參數(shù)
 // 1:元素汰扭,2稠肘、距離,3萝毛、滾動條所在的元素项阴,4、綁定事件的元素
 constructor(el, critical_point, scrollContainer, eventEl = scrollContainer) {
   this.el = el;
   this.critical_point = critical_point;

   // 滾動條所在的容器
   this.scrollContainer = scrollContainer;

   // 監(jiān)聽滾動事件的元素
   this.eventEl = eventEl;
   // 調(diào)整狀態(tài)
   this.setState(INIT_STATE);
   // 綁定事件
   this.bindEvent();
 }

 // 設(shè)置狀態(tài)
 setState(state) {
   this.state = state;
 }

 // 綁定事件
 bindEvent() {
   this.eventEl.addEventListener(
     'scroll',
     () => {
       if (this.needChange()) {
         this.setState(CHANGED_STATE);
         this.change();
       } else if (this.needReset()) {
         this.setState(INIT_STATE);
         this.reset();
       }
     },
     false
   );
 }
 // 重置笆包,去掉類名
 reset() {
   this.el.classList.remove(CHANGED_CLASS_NAME);
 }
 // 不是初始的狀態(tài)环揽,并且滾動的距離大于等于設(shè)定的距離
 needReset() {
   return (
     this.state !== INIT_STATE &&
     this.scrollContainer.scrollTop <= this.critical_point
   );
 }

 //   變化,添加類名
 change() {
   this.el.classList.add(CHANGED_CLASS_NAME);
 }

 //   需要變化庵佣,不是已改變的狀態(tài)歉胶,并且滾動的距離小于設(shè)定的距離
 needChange() {
   return (
     this.state !== CHANGED_STATE &&
     this.scrollContainer.scrollTop > this.critical_point
   );
 }
}
// 導(dǎo)出頂部
export default Header;

使用Header類,下方代碼是pages/index/components/header/index.js

import Header from 'components/header';

const scrollContainer = document.getElementById('index-page');
const headerEl = scrollContainer.querySelector('.header');

new Header(headerEl, 0, scrollContainer);

2、幻燈片組件
下方代碼是:pages/index/components/slider/config.js

// Swiper 配置
export default {
  // 循環(huán)模式選項(xiàng)
  loop: true,
  // 是否需要分頁器
  pagination: {
    el: '.swiper-pagination'
  }
  // 是否需要前進(jìn)后退按鈕
  //   navigation: {
  //     nextEl: '.swiper-button-next',
  //     prevEl: '.swiper-button-prev'
  //   },
  // 是否需要滾動條
  //   scrollbar: {
  //     el: '.swiper-scrollbar'
  //   }
};

export const SWIPER_CONTAINER_CLASS = '.swiper-container';

使用幻燈片巴粪,下方代碼是:pages/index/components/slider/index.js

// 引入css
import 'swiper/swiper-bundle.min.css';
import './slider.css';
// 引入js
import Swiper from 'swiper/swiper-bundle.min';
// 引入配置文件
import config, { SWIPER_CONTAINER_CLASS } from './config';

// https://www.swiper.com.cn/api/index.html
// 實(shí)例化
new Swiper(SWIPER_CONTAINER_CLASS, config);

3通今、導(dǎo)航組件
下方代碼是:pages/index/components/nav/config.js

export const URL = 'https://www.imooc.com/api/mall-wepApp/index/nav';
export const LAYOUT_ID = 'index-nav';

下方代碼是:pages/index/components/nav/index.js

import './nav.css';
// 引入模板
import render from './nav.art';
// ajax請求
import { getData, getDelayedData } from 'api/getData';
// 請求地址和盛放結(jié)構(gòu)的元素
import { URL, LAYOUT_ID } from './config';

// https://www.imooc.com/api/mall-wepApp/index/nav
getData(URL).then(data => {
  document.getElementById(LAYOUT_ID).innerHTML = render({
    items: data
  });
});

4、返回頂部
Backtop 組件肛根,下方代碼是:下方代碼是components/backtop/index.js

import './backtop.css';
import 'icons/iconfont.css';

const CHANGED_CLASS_NAME = 'backtop-hidden';
const INIT_STATE = 'init';
const CHANGED_STATE = 'changed';

class Backtop {
  constructor(el, critical_point, scrollContainer, eventEl = scrollContainer) {
    this.el = el;
    this.critical_point = critical_point;

    // 滾動條所在的容器
    this.scrollContainer = scrollContainer;

    // 監(jiān)聽滾動事件的元素
    this.eventEl = eventEl;

    this.setState(INIT_STATE);

    this.bindEvent();
  }

  // 設(shè)置狀態(tài)
  setState(state) {
    this.state = state;
  }

  // 綁定事件
  bindEvent() {
    this.eventEl.addEventListener(
      'scroll',
      () => {
        if (this.needChange()) {
          this.setState(CHANGED_STATE);
          this.change();
        } else if (this.needReset()) {
          this.setState(INIT_STATE);
          this.reset();
        }
      },
      false
    );

    this.el.addEventListener(
      'click',
      () => {
        this.scrollTo();
      },
      false
    );
  }

  scrollTo(top = 0, left = 0) {
    this.scrollContainer.scrollTo({
      top,
      left,
      behavior: 'smooth'
    });
  }

  reset() {
    this.el.classList.add(CHANGED_CLASS_NAME);
  }

  needReset() {
    return (
      this.state !== INIT_STATE &&
      this.scrollContainer.scrollTop <= this.critical_point
    );
  }

  //   變化
  change() {
    this.el.classList.remove(CHANGED_CLASS_NAME);
  }

  //   需要變化
  needChange() {
    return (
      this.state !== CHANGED_STATE &&
      this.scrollContainer.scrollTop > this.critical_point
    );
  }
}

export default Backtop;

使用返回頂部組件,下方代碼是:pages/index/components/backtop/index.js

import Backtop from 'components/backtop';

const scrollContainer = document.getElementById('index-page');
const backtopEl = scrollContainer.querySelector('.backtop');

new Backtop(backtopEl, window.innerHeight, scrollContainer);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辫塌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子派哲,更是在濱河造成了極大的恐慌臼氨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狮辽,死亡現(xiàn)場離奇詭異一也,居然都是意外死亡巢寡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門椰苟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抑月,“玉大人,你說我怎么就攤上這事舆蝴∏酰” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵洁仗,是天一觀的道長层皱。 經(jīng)常有香客問我,道長赠潦,這世上最難降的妖魔是什么叫胖? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮她奥,結(jié)果婚禮上瓮增,老公的妹妹穿的比我還像新娘。我一直安慰自己哩俭,他們只是感情好绷跑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凡资,像睡著了一般砸捏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隙赁,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天垦藏,我揣著相機(jī)與錄音,去河邊找鬼鸳谜。 笑死膝藕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咐扭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼滑废,長吁一口氣:“原來是場噩夢啊……” “哼蝗肪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蠕趁,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤薛闪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俺陋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豁延,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昙篙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诱咏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苔可。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖袋狞,靈堂內(nèi)的尸體忽然破棺而出焚辅,到底是詐尸還是另有隱情,我是刑警寧澤苟鸯,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布同蜻,位于F島的核電站,受9級特大地震影響早处,放射性物質(zhì)發(fā)生泄漏湾蔓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一砌梆、第九天 我趴在偏房一處隱蔽的房頂上張望卵蛉。 院中可真熱鬧,春花似錦么库、人聲如沸傻丝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葡缰。三九已至,卻和暖如春忱反,著一層夾襖步出監(jiān)牢的瞬間泛释,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工温算, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怜校,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓注竿,卻偏偏與公主長得像茄茁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子巩割,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容