ionic4.x-京东商城

本文详细介绍了使用Ionic框架进行移动应用开发的过程,包括项目搭建、Tab样式修改、全局样式设置、第三方图标集成、轮播图和商品列表的实现、搜索模块布局、用户中心设计以及接口调用等。内容涵盖 Ionic 的 Android 和 iOS 平台样式统一、页面跳转、事件处理、数据存储等多个方面,展示了完整的移动端应用开发流程。
摘要由CSDN通过智能技术生成


功能:
首页、分类、购物车、我的

在这里插入图片描述

上传码云

git remote add origin https://gitee.com/lkp_ksbk/ionic_jd_shop.git
git push -u origin master

搭建项目,增加tab4,并修改tab样式

ionic start jdshop tabs // 搭建项目
ionic g page tab4 // 第四个tab页面

添加上tab4,然后修改tab的文字和icon。
首页:home、分类:shirt、购物车: cart、 我的:settings

修改tab的颜色:
1.使用自定义主题色的方法,并没有改变tab的选中颜色,所以不行。
2.修改某一类组件的颜色(ion-tab-button)。css properties

.ion-color-tabs {
  --ion-color-base: #69bb7b;
  --ion-color-base-rgb: 105,187,123;
  --ion-color-contrast: #ffffff;
  --ion-color-contrast-rgb: 255,255,255;
  --ion-color-shade: #5ca56c;
  --ion-color-tint: #78c288;
}
// 可以把base和contrast的颜色做一个调换,那么背景是白色的,只是选中和非选中只有一点色差,不是那种选中红,不选中黑的状态。
// 修改底部图标的选中颜色以及默认颜色
ion-tab-button{
  --color:#8C8E8C;
  --color-selected:#F53D3D;
}

android和ios配置统一样式

默认:android和ios是两套不一样的样式。
app.module.ts:

IonicModule.forRoot() // forRoot可以配置参数。

可以配置很多,自己进去看看,eg:backButtonIcon,animated,menuIcon,menuType等等。

IonicModule.forRoot({
  mode:'ios', // 都是ios样式
  backButtonText:'返回' // 返回按钮,默认是汉字,不是back了。
}),

添加全局样式和rem

global.scss和variables.scss中都行。

/*自定义的全局css样式*/
body,
div,
ul,
li,
ol,
h1,
h2,
h3,
h4,
h5,
h6,
input,
textarea,
select,
p,
dl,
dt,
dd,
a,
img,
button,
form,
table,
th,
tr,
td,
tbody,
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
  margin: 0;
  padding: 0;
}

html {
  font-size: 62.5%; // 浏览器的默认字体大小是16px          16*62.5%=10px
}

.clearfix {
  &::after {
    display: block;
    content: "";
    height: 0px;
    clear: both;
  }
}

ul,
ol {
  list-style-type: none;
}

search模块布局

第三方字体图标icon

eg:iconfont
选中icon下载,然后选择颜色和大小及格式,即可。eg:下载png格式,我们就可以使用iconfont的图标了。

search:扫码和消息icon。
search:i-searchbar
消息提示icon:i-badge。

<ion-header [translucent]="true">
  <ion-toolbar>

    <!-- 左侧的扫码icon -->
    <ion-buttons slot="start" class="qrcode-container">
      <ion-img src="assets/images/qrcode.png"></ion-img>
    </ion-buttons>

    <!-- 搜索框 -->
    <!-- (ionChange)="onSearchChange($event)" -->
    <ion-searchbar placeholder="请输入搜索内容" [debounce]="250" animated>
    </ion-searchbar>

    <!-- 右侧的消息icon -->
    <ion-buttons slot="end" class="message-container">
      <ion-img src="assets/images/message.png"></ion-img>
      <ion-badge color="danger" mode="ios" class="message-badge">9</ion-badge>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

// badge需要定位一下,且container需要给一个padding,那么就能对齐了。

图片:。。。。

轮播图

图片:

/**
 * 轮播图 第一次滑动轮播图的时候,会有一个白色背景的问题,应该是图片不知道h,所以触发的
 */
public slidesList = [];
getSlidesList() {
  for (let i = 1; i < 4; i++) {
    this.slidesList.push({
      pic: `assets/images/slide0${i}.png`, // 图片
      url: '' // 跳转的地址
    });
  }
}

轮播图配置:
1.配置参数,自动轮播
2.手动操作后,需要继续自动轮播。

//轮播图的属性
public slidesOpts={
  speed:400,
  autoplay: {
    delay: 2000,
  },
  loop:true,
  effect: 'slide' // 'slide'(普通切换、默认),"fade"(淡入)"cube"(方块)"coverflow"(3d流)"flip"(3d翻转)
}

问题:
1.N张图片,第一次循环轮播的时候,每个图片会闪一下空白(跟没找到图片高度似的,第一次循环之后就ok了)
2.设置loop后自动轮播,循环过程中,再到第一张图片的时候,页面会空白,不显示第一张图片。
解决:

<!-- 轮播图 -->
<!-- ion-slide中不要使用ion-img,直接使用img即可,就不会出现上面的问题。-->
<ion-slides #homeSlides pager='true' [options]="slidesOpts" (ionSlideTouchEnd)="doSlideChange()">
  <ion-slide *ngFor="let item of slidesList">
    <img [src]="item.pic" />
  </ion-slide>
</ion-slides>
(ionSlideTouchEnd)="slideTouchEnd()"

//手动滑动完成
slideTouchEnd(){
    this.slide1.startAutoplay();
}
ion-slide{
ion-slides {
  height: 15rem;
  ion-slide {
    width: 100%;
    height: 100%;
    overflow: hidden;

   img{
      width: 100%;
      height: 100%;
    }
  }
}

pager:是否显示分页。

猜你喜欢(可滑动的推荐商品列表)

for(var i=1;i<=7;i++){
  this.hotList.push({
    pic:'assets/0'+i+'.jpg',
    title:'第'+i+'个',
  })
}

//计算hotListWidth的宽度
this.hotListWidth=this.hotList.length*9+'rem';

思路:外层盒子w100%,里层的ul要设置宽一些(计算准确的宽),然后外层overflow:auto即可。

<!-- 外层盒子 -->
<div class="content">

  <!-- 内层盒子 -->
  <ul class="recommend-list-ul">
    <li *ngFor="let item of recommendList">
      <img [src]="item.pic" alt="" />
    </li>
  </ul>
</div>


// 外层
.content {
  overflow-x: auto;

  // 内层
  .recommend-list-ul {
    width: 90rem; // 每一个img是10rem,一共9张图(计算获取)

    li {
      float: left;

      img {
        width: 9rem;
        margin: 0.5rem;
      }
    }
  }
}
<ul class="recommend-list-ul" [ngStyle]="{'width':10*this.recommendList.length+'rem'}">

在这里插入图片描述

商品列表

栅格布局:

<ion-grid fixed>
  <ion-row>
    <ion-col size="6" *ngFor="let item of productList">
      <img [src]="item.pic" alt="" />
      <div class="img-desc">{{item.title}}</div>
    </ion-col>
  </ion-row>
</ion-grid>

商品分类

左、右侧布局:display:flex;布局。

同时要左右两侧各自滚动,不影响其他:同home-可滑动的推荐商品列表(内层1000px,外层100px,overflow:auto;)

在这里插入图片描述

购物车页面

1.购物车商品的页面布局
2.底部的全选和结算
在这里插入图片描述

用户中心

头部用户信息

div使用flex布局即可。

用户信息列表

i-item-icon

背景图片(/assets开头):

background: url('/assets/images/user_bg.jpg') no-repeat center center;

html中:
可以/开头,也可以不。

在这里插入图片描述

ionic项目的真机调试:

1.ionic serve的时候,根据ip地址打开。
公司网络不支持?
mac查ip:设置>网络>高级>TCP/IP>IPv4地址。

电脑联手机演示

360手机助手(手机演示)

问题:
1.轮播图没有铺满,所以有问题;(w100%即可)
2.fontsize:62.5%,所以没有设置fz的时候,都是12*62.5=10px;浏览器最小12所以觉得没问题,但是手机上就不行了。

// global.css中设置:
body {
  font-size: 1.4rem;
}

点击search调到search页面(共用的)

tap事件为什么又不可用了?需要安装hammer.js??我写成click事件了…

安装了hammer也不能使用tap?


constructor(
  public router: Router,
  public navCtrl: NavController
) {}


// 使用Router跳转
// this.router.navigate(['/search']);

// 使用NavController跳转
this.navCtrl.navigateForward('/search');

在这里插入图片描述

search的详情页面

点击返回的时候,返回首页或者分类页面,说明:
search详情页面不是一个单独的页面,跟search是同一个页面。

固定的二级导航

header中再来一个i-toolbar即可。固定在头部的。

修改组件的默认样式:
// 二级导航
ion-toolbar.sub_header{
  display: flex; // 没有display的属性,所以不能修改;如果想修改,包一层div
  background: red; // 不起作用

  --background:red; // 正确的修改组件样式
  .sub_title{
    flex:1;
  }
}

i-item默认一行就…显示了,有时候不需要这样式。
在这里插入图片描述

登录页面

toobar下面的底边线要去掉;
toolbar有border-color属性,没有border属性;我们修改border-color颜色即可。

忘记密码和用户注册布局:可以使用flex左右布局,也可以直接使用slot的方法。

<ion-list>
  <ion-item lines="none">
    <span slot="start">忘记密码</span>
    <span slot="end">用户注册</span>
   </ion-item>
</ion-list>

在这里插入图片描述

注册页面

功能(三个独立的页面):输入手机号,发送验证码,输入密码。

NavController:backnavigateBacknavigateForwardnavigateRoot

input框:
原生input是行内元素;
ion-input是块级元素;padding-left:0;

ion-input {
  border: 1px solid #ccc;
  width: 80%;
  height: 3.2rem;
  margin: 2rem auto; // 块级元素
  --padding-start: .6rem; // 给一个左padding
}
ion-item有默认的样式,需要自己调整一下才能左右对齐
--padding-start
--padding-end

在这里插入图片描述
在这里插入图片描述

封装接口

接口地址:https://www.itying.com/article-11.html
轮播图:http://jd.itying.com/api/focus
猜你推荐:http://jd.itying.com/api/plist?is_hot=1&pageSize=20&page=1
热门推荐:http://jd.itying.com/api/plist?is_best=1&pageSize=20&page=1

ionic g service services/http

HttpClientModuleHttpClient

调用接口,渲染数据。
在这里插入图片描述

商品分类接口联调

一级分类(左侧): http://jd.itying.com/api/pcate
二级分类(右侧): http://jd.itying.com/api/pcate?pid=59f1e1ada1da8b15d42234e9

在这里插入图片描述

商品分类-第三分类页面

第三分类:http://jd.itying.com/api/plist
参数:
cid:第二分类的id。
search:模糊搜索的内容。
page:page
pageSize:size
sort:排序; 综合:all,销量:sales,价格:price
    1.价格:sort=price_1 或者 sort=price_-1
    2.销量:salecount_1salecount_-1
    3.综合:all

功能:
1.上拉加载更多
2.下拉刷新
3.排序

商品分类-第三分类页面-排序

问题:
1.切换tab的时候,页面没有滚动到最顶部
2.加入tab1滚动到最底部,已经禁用上拉加载更多了,切换到tab2的时候,需要放开该功能。
3.升序和降序都要做。(功能已经实现,可以加上向上或者向下的箭头,完成页面)

// 获取ion-content,让它滚动到顶部
@ViewChild(IonContent) ionContent: IonContent;
// 也可以给ion-content用id,用id的方式获取(dom操作:#productListContent)

this.ionContent.scrollToTop(0); /*回到顶部*/
@ViewChild('productListScroll') productListScroll: any;

this.productListScroll.disabled = false; // 恢复上拉加载更多功能
// 升序和降序:每次点击后,改变sort的值,那么再次点击就已经改变了。
this.navList[id - 1].sort = this.navList[id - 1].sort * -1; // 升序和降序:改变sort的值。

注:在做箭头排序的时候,title的样式(颜色)影响了内部icon的颜色,所以一直在做上下判断的时候,不起作用。

.sub_title.active {
  background: #eee;

  span {
    color: #f40; // 只给title加样式;icon自己单独加
  }

  // color: #f40; // 会影响到箭头的颜色
}

在这里插入图片描述

search页面同样的问题

1.清空list
2.重置page
3.滚动到顶部
4.放开infinite-scroll的限制。

在这里插入图片描述

历史记录

storageService:

ionic g service services/storage
添加历史记录
删除历史记录

商品详情

在这里插入图片描述

注册页面

1.封装了post的请求。
2.发送验证码
3.倒计时
4.验证验证码
5.注册

登录功能

1.登录功能
2.订阅
3.生命周期

ngOnInit只有刷新的时候执行了一次,来回切换tab的时候,这个生命周期函数不执行了!!!

为什么???

如果切换tab每次都执行生命周期函数的话,那么会一直调用接口,不太好,所以有缓存的。

所以,不用angualr的生命周期函数,用ionic的生命周期函数。

生命周期函数:


// enter:在tab切换或者第一此执行会触发,在login页面返回没有触发:
// leave:在login页面返回时触发了
ionViewWillEnter:当进入一个页面时触发(如果它从堆栈返回)
ionViewDidEnter:进入后触发
ionViewWillLeave:如果页面将离开触发
ionViewDidLeave:在页面离开后触发
ionViewWillUnload:页面卸载的时候会触发,如果无法触发使用 ngOnDestroy

注:tab4切换到login页面的时候,tab4没有卸载掉,只是push了login页面进去,所以返回的时候,没有执行enter的事件。为了运行速度。

EventEmitter

  1. npm搜索,发现:
    eventemitter很少下载量,eventemitter3下载很多,说明现在用eventemitter3的比较多。
  2. github:https://github.com/primus/eventemitter3

使用:

// 安装配置 EventEmitter
npm install --save eventemitter3

ionic g service services/event


// src/app/services/event.service.ts
import { Injectable } from '@angular/core';
import { EventEmitter } from 'eventemitter3';

@Injectable({
  providedIn: 'root'
})
export class EventService {
  public eventEmit: any;
  constructor() {
    // 定义发射事件
    // 这个实例,被多个组件共享,来实现数据在不同页面之间的共享
    this.eventEmit = new EventEmitter();
  }
}
// 登录页面发出广播:
this.envetService.eventEmit.emit('userInfo', '登录了吗?哈哈' );


// 接收页面接收广播  on默认不触发,只有发出广播后,才会触发。
// 监听事件  eventEmit:是自定义的名字。
this.eventService.eventEmit.on('userInfo', params => {
   console.log('tab4-订阅事件的params:', params);
 });

账号密码:

注册的时候,验证码在后端接口有返回。
已注册密码:
123/123
admin/admin
root/root

设置页面

ionic g page personal
  1. 更改用户信息:生日、性别等
  2. 退出登录
    清空storage,然后发布广播,回到setting页面。

slot的使用,可以自动放在末尾:

<ion-list lines='full'>

    <ion-item>
      头像
      
      <span slot='end' class="item_note">
        <img [src]="personalInfo.avatar" class="avatar" alt="">
      </span>
      
      <ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
    </ion-item>
    
</ion-list>

添加到购物车功能

属性选择
  1. 课程里的方法:js原生方法:事件委托:
/**
 * 选择属性
 */
changeAttr(e) {
  console.log('事件对象e:', e);
  console.log('事件对象e.srcElement:', e.srcElement);
  console.log('事件对象e.srcElement.nodeName:',e.srcElement.nodeName); // SPAN  大写标签名
  console.log('事件对象e.srcElement.className:',e.srcElement.className); // attr_cont

  if (e.srcElement.className.indexOf('attr_cont') > -1) {
    console.log('点击了某一条attr');

    const ele = e.srcElement; // 获取当前dom节点

    // 获取父节点
    const parentEle = ele.parentNode;

    // 所有子节点
    const childrenEle = parentEle.children;

    console.log('所有子节点:', childrenEle);

    // childrenEle.forEach((v,k)=>{
    //   v.removeClassName('active');
    // })

    // 所有节点去掉active的类名
    for (let i = 0;i < childrenEle.length;i++) {
      console.log( '每个子节点的className:', childrenEle[i].className );
      childrenEle[i].className = childrenEle[i].className.replace('active', '');
    }

    // 当前元素增加class:active
    ele.className = ele.className + ' active';
  }
}
  1. 使用angular方法
<!-- 第一层循环 -->
<div class="attr_item" *ngFor="let item of productDetail.attr">
  <span class="attr_title">{{item.cate}}</span>
  
  <!-- 第二层循环 -->
  <span class="attr_cont" *ngFor="let item2 of item.list" 
    (click)="selectAttr(item,item2)"
    [ngClass]="{'active': item.selectedAttr == item2}">{{item2}}</span>
    
</div>


/**
 * 切换属性
 * @param item :第一层循环的item
 * @param item2 :第二层循环的item
 */
selectAttr(item,item2){
  item.selectedAttr = item2;
}
数量选择
添加到购物车
  1. 存储数据:接口或者storage存储在本地;

    本地的话,判断是否有重复的,需要计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值