前端fayermall开发项目(页面逻辑)
一、个人用户信息
1、通用模块的开发
![]()
1)左边是登录和没登录两个状态
2)页面初始化的时候,会读取用户信息;会请求一个检查登录状态的接口,通过接口判断,如果我们拿到用户信息了,就说明有登陆状态;如果没拿到,报错了,就说明没有登录;
3)页面初始化的时候,同时也要加载购物车数量,请求一个获取购物车数量接口;
require('./nav.css');
var _mm = require('util/mm.js');
var _user = require('service/user-service.js');
var _cart = require('service/cart-service.js');
//导航
var nav = {
init : function(){
this.bindEvent();
this.loadUserInfo();
this.loadCartCount();
return this; //this指向 init调用(nav.init()),即把nav又返回去了,输出的时候还是nav对象
},
bindEvent : function(){
//点击登录事件
$('.js-login').on('click',function(){
_mm.doLogin();
});
//注册点击事件
$('.js-register').on('click',function(){
window.location.href = './user-register.html'
});
//退出点击事件
$('.js-logout').on('click',function(){
_user.logout(function(res){
window.location.reload();//重新刷新页面
},function(errMsg){
_mm.errorTips(errMsg);
})
});
},
//加载用户信息
loadUserInfo : function(){
_user.checkLogin(function(res){
$('.user.not-login').hide().siblings('.user.login').show()
.find('.username').text(res.username);
},function(errMsg){
//
})
},
//加载购物车数量
loadCartCount : function(){
_cart.getCartCount(function(res){
$('.nav .cart-count').text(res || 0);
},function(errMsg){
$('.nav .cart-count').text(0);
})
}
}
module.exports = nav.init();//这是因为这个模块被引用后就一定会立即执行init的,所以就在模块的输出时就做了,这样在引用它的地方就不用再每次调用init方法了
2、通用头部header,两个逻辑
![]()
1)搜索提交
【】获取Input的val,就是keyword,如果存在,则通过参数的形式,跳转到list页
2)输入完东西,搜索以后,进入了list.html页以后,input框内不能为空,应该是搜索的内容,所以要根据url参数 进行回填
【】页面一加载进来的时候,读取url的参数,即keyword值,并回填到input
//通用页面头部 var header = { init : function(){ var _this = this; this.onLoad(); this.bindEvent(); }, onLoad : function(){ var keyword = _mm.getUrlParam('keyword'); //如果keyword存在,则回填输入框 if(keyword){ $('#search-input').val(keyword); } }, bindEvent : function(){ var _this = this; //点击搜索,做搜索提交 $('#search-btn').on('click',function(){ _this.searchSubmit(); console.log(222); }) //输入回车后,做搜索提交 $('#search-input').on('keyup',function(e){ if(e.keyCode == 13){ _this.searchSubmit(); } }) }, //搜索的提交 searchSubmit : function(){ var keyword = $.trim($('#search-input').val()); //如果有keyword的时候,正常跳转到List页 if(keyword){ window.location.href = './list.html?keyword=' + keyword; }else{ _mm.goHome(); } } } header.init();
3、通用侧边导航
1)就一个逻辑,就是用js渲染侧边栏
【】把侧边导航当做一个通用模块,单独写成一个.string的模块,然后通过本地创建数据,把数据渲染到里面。
【】添加active:通过其他页面传进来option和已经创建的option进行合并选项,把传进来的option.name和this.name.option作为判断条件,如果相等,就给navlist添加一个标记位,用来添加active;
//侧边导航 var navSide = { option : { name : '', navlist : [ {name : 'user-center',desc : '个人中心',href : './user-center.html'}, {name : 'order-list',desc : '我的订单',href : './order-list.html'}, {name : 'user-pass-update',desc : '修改密码',href : './user-pass-update.html'}, {name : 'about',desc : '关于MMall',href : './about.html'} ] }, init : function(option){ //合并选项,后者覆盖前者 $.extend(this.option,option); this.renderNav(); }, //渲染导航菜单 renderNav : function(){ var iLength = this.option.navlist.length; for(var i = 0; i < iLength; i++ ){ if(this.option.navlist[i].name === this.option.name){ this.option.navlist[i].isActive = true; } }; //渲染list数据 var navHtml = _mm.renderHtml(templateNavSide,{ navlist : this.option.navlist }); $('.nav-side').html(navHtml); } } module.exports = navSide;
{{#navlist}} {{#isActive}} <li class="nav-item active"> {{/isActive}} {{^isActive}} <li class="nav-item"> {{/isActive}} <a class="link" href="{{href}}">{{desc}}</a> </li> {{/navlist}}
4、个人中心开发
1)个人中心展示 user-center.html
【】创建user-center.string模板,请求接口渲染

2)个人信息修改 user-center-update
【】初始化,左侧导航
init: function(){ this.onLoad(); this.bindEvent(); }, onLoad : function(){ // 初始化左侧菜单 navSide.init({ name: 'user-center' }); // 加载用户信息 this.loadUserInfo(); },
【】做验证,点击提交
先定义一个变量validateResult,即validateForm函数的返回值result对象,通过返回对象状态码status的true or false 来进行提交以及验证,验证通过(true),请求接口;验证错误,就返回一个msg;
bindEvent : function(){ var _this = this; // 点击提交按钮后的动作 $(document).on('click', '.btn-submit', function(){ var userInfo = { phone : $.trim($('#phone').val()), email : $.trim($('#email').val()), question : $.trim($('#question').val()), answer : $.trim($('#answer').val()) }, //输入框验证信息 validateResult = _this.validateForm(userInfo); if(validateResult.status){ // 更改用户信息 _user.updateUserInfo(userInfo, function(res, msg){ _mm.successTips(msg); window.location.href = './user-center.html'; }, function(errMsg){ _mm.errorTips(errMsg); }); } else{ _mm.errorTips(validateResult.msg); } }); }, // 验证字段信息 validateForm : function(formData){ var result = { status : false, msg : '' }; // 验证手机号 if(!_mm.validate(formData.phone, 'phone')){ result.msg = '手机号格式不正确'; return result; } // 验证邮箱格式 if(!_mm.validate(formData.email, 'email')){ result.msg = '邮箱格式不正确'; return result; } // 验证密码提示问题是否为空 if(!_mm.validate(formData.question, 'require')){ result.msg = '密码提示问题不能为空'; return result; } // 验证密码提示问题答案是否为空 if(!_mm.validate(formData.answer, 'require')){ result.msg = '密码提示问题答案不能为空'; return result; } // 通过验证,返回正确提示 result.status = true; result.msg = '验证通过'; return result; }
二、首页(纯属静态页面,没有请求接口http://localhost:8080/dist/view/index.html)
1、左侧关键字导航

1)产品关键字,点击跳转到list.html?keyword=xxx页面,所以要在a标签里把关键字参数keyword写到链接里
<li class="keywords-item"> <a class="link" target="_blank" href="./list.html?keyword=电脑">电脑</a> <span class="cate_menu_line">/</span> <a class="link" target="_blank" href="./list.html?keyword=办公配件">办公配件</a> </li>
2、首页banner
1)样式布局:用绝对定位,然后用透明度属性,来切换图片。还另外加了css3的transform和transition的变化和过渡。

2)把轮播的脚本单独放在slider-img.js,然后在Index.js里引用。webpack用requrie方式引入模块
1 require('page/common/nav/nav.js'); 2 require('page/common/header/header.js'); 3 var sliderImg = require('util/slider/slider-img.js'); 4 var navSide = require('page/common/nav-side/nav-side.js'); 5 var _toolbar = require('page/common/toolbar/toolbar.js'); 6 var _mm = require('util/mm.js');
3、产品列表

1)这里的内容是直接从后台导入的数据,因为没有请求接口,所以每个产品的categoryId都需要手动添加;这里注意一个情况,就是在html里面引用图片的时候,一定要用requrie的方式,然后通过相对路径来添加图片;
<li class="floor-item"> <a href="./list.html?categoryId=100007"> <span class="floor-text">电视</span> <img class="floor-img" src="<%= require('../image/floor/floor1-2.jpg') %>" alt="电视" /> </a> </li>
4、左侧悬浮和右侧悬浮,头部悬浮


![]()
1)都用了固定定位fixed
2)左侧和顶部的悬浮,用同一个脚本做显示隐藏,在Index.js引入toolbar.js,单独封装.webpack用module.exports输出模块(对象)
require('./toolbar.css');
//参数 $fixedBar 要定位的对象
//参数Topobj 相对于某个定位的对象
//参数docClass fiexd显示隐藏的控制class值
var _toolbar = {
//fixedbar 切换
fixedbar : function(obj,Topobj,docClass){
var $fixedBar = $(obj),
$offsetTop = '';
if(obj === '.leftbar'){
$offsetTop = $(Topobj).offset().top-200;
}else{
$offsetTop = $(Topobj).offset().top;
}
$(window).scroll(function(){
if($(window).scrollTop() > $offsetTop){
$fixedBar.addClass(docClass);
}else{
$fixedBar.removeClass(docClass);
}
});
}
}
module.exports = _toolbar;
3)悬浮的样式效果,都添加了css3简单的动画效果
.transition(@transition){ -webkit-transition:@transition; -moz-transition:@transition; -ms-transition:@transition; -o-transition:@transition; transition:@transition; } .transform-origin(@right, @bottom){ -webkit-transform-origin:@right @bottom; -moz-transform-origin:@right @bottom; -o-transform-origin:@right @bottom; -ms-transform-origin:@right @bottom; transform-origin:@right @bottom; } .scale(@scale){ -webkit-transform : scale(@scale); -moz-transform : scale(@scale); -ms-transform : scale(@scale); -o-transform : scale(@scale); transform : scale(@scale); }
三、商品列表页(http://localhost:8080/dist/view/list.html?keyword=手机)
1、商品列表页list.html分为两个路口从首页进入,一个是点击商品通过传递参数categoryId,一个通过搜索,通过传递参数keyword;

2、页面是通过新建list.string用hogan.js渲染的
{{#list}} <li class="p-item"> <div class="p-img-con"> <a class="link" href="./detail.html?productId={{id}}" target="_blank"> <img class="p-img" src="{{imageHost}}{{mainImage}}" alt="{{name}}" /> </a> </div> <div class="p-price-con"> <span class="p-price">¥{{price}}</span> </div> <div class="p-name-con"> <a class="p-name" href="./detail.html?productId={{id}}" target="_blank">{{name}}</a> </div> </li> {{/list}} {{^list}} <p class="err-tip">很抱歉,实在找不到您要的商品。</p> {{/list}}
3、页面处理的脚本
1)01页面一加载进来,02点击默认,升序降序按钮,03点击分页;分别都会加载list;
2)通过url获取keyword或者categoryId参数
data : { listParam : { keyword : _mm.getUrlParam('keyword') || '', categoryId : _mm.getUrlParam('categoryId') || '', orderBy : _mm.getUrlParam('orderBy') || 'default', pageNum : _mm.getUrlParam('pageNum') || 1, pageSize : _mm.getUrlParam('pageSize') || 5 } }
四、详情页

1、先通过url获取到productId,然后传递参数,来渲染详情页
2、包含的事件
bindEvent : function(){ var _this = this; // 图片预览 $(document).on('mouseenter', '.p-img-item', function(){ var imageUrl = $(this).find('.p-img').attr('src'); $('.main-img').attr('src', imageUrl); }); // count的操作 $(document).on('click', '.p-count-btn', function(){ var type = $(this).hasClass('plus') ? 'plus' : 'minus', $pCount = $('.p-count'), currCount = parseInt($pCount.val()), minCount = 1, maxCount = _this.data.detailInfo.stock || 1; if(type === 'plus'){ $pCount.val(currCount < maxCount ? currCount + 1 : maxCount); } else if(type === 'minus'){ $pCount.val(currCount > minCount ? currCount - 1 : minCount); } }); // 加入购物车 $(document).on('click', '.cart-add', function(){ _cart.addToCart({ productId : _this.data.productId, count : $('.p-count').val() }, function(res){ window.location.href = './result.html?type=cart-add'; }, function(errMsg){ _mm.errorTips(errMsg); }); }); }
3、添加购物车功能,请求接口,跳转到加入购物车成功后提示页
五、购物车和订单(不详细说明了,面试的时候演示)
六、登录注册页面
posted on 2017-08-06 23:29 fayerSmile 阅读(1062) 评论(0) 收藏 举报

浙公网安备 33010602011771号