鸿蒙OS 开发一个JS FA应用
本章节主要介绍如何开发一个 JS FA 应用。此应用相对于 Hello World 应用模板具备更复杂的页面布局、页面样式和页面逻辑。该页面可以通过将焦点移动到不同颜色的圆形来选择不同的食物图片,也可以进行添加到购物车操作,应用效果图如下。
图1 JS FA应用效果图
构建页面布局
开发者在 index.hml 文件中构建页面布局。在进行代码开发之前,首先要对页面布局进行分析,将页面分解为不同的部分,用容器组件来承载。根据 JS FA 应用效果图,此页面一共分成三个部分:标题区、展示区和购物车区。根据此分区,可以确定根节点的子节点应按列排列。
标题区是由两个按列排列的 tex t组件实现,购物车区由一个 text 组件构成。展示区由按行排列的 swiper 组件和 div 组件组成,如下图所示:
- 第一部分是由一个容器组件 swiper,包含了四个image 组件构成;
- 第二部分是由一个容器组件 div,包含了一个 text 组件和四个画布组件 canvas 绘制的圆形构成。
图2 展示区布局
根据布局结构的分析,实现页面基础布局的代码示例如下(其中四个 image 组件和 canvas 组件通过 for 指令来循环创建):
<!-- index.hml -->
<div class="container">
<div class="title-section">
<div class="title">
<text class="name">Food</text>
<text class="sub-title">Choose What You Like</text>
</div>
</div>
<div>
<swiper id="swiperImage" class="swiper-style">
<image src="{{$item}}" class="image-mode" focusable="true" for="{{imageList}}"></image>
</swiper>
<div class="container">
<div class="description-first-paragraph">
<text class="description">{{descriptionFirstParagraph}}</text>
</div>
<div class="color-column">
<canvas id="{{$item.id}}" onfocus="swipeToIndex({{$item.index}})" class="color-item" focusable="true"
for="{{canvasList}}"></canvas>
</div>
</div>
</div>
<div class="cart">
<text class="{{cartStyle}}" onclick="addCart" onfocus="getFocus" onblur="lostFocus" focusable="true">
{{cartText}}</text>
</div>
</div>
说明
common 目录用于存放公共资源,swiper 组件里展示的图片需要放在 common 目录下。
构建页面样式
开发者在 index.css 文件中需要设定的样式主要有 flex-direction(主轴方向),padding(内边距), font-size(字体大小)等。在构建页面样式中,还采用了 css 伪类的写法,当焦点移动到 canvas 组件上时,背景颜色变成白色,也可以在 js 中通过 focus 和 blur 事件动态修改 css 样式来实现同样的效果。
/* index.css */
.container {
flex-direction: column;
}
.title-section {
flex-direction: row;
height: 60px;
margin-bottom: 5px;
margin-top: 10px;
}
.title {
align-items: flex-start;
flex-direction: column;
padding-left: 60px;
padding-right: 160px;
}
.name {
font-size: 20px;
}
.sub-title {
font-size: 15px;
color: #7a787d;
margin-top: 10px;
}
.swiper-style {
height: 250px;
width: 350px;
indicator-color: #4682b4;
indicator-selected-color: #f0e68c;
indicator-size: 10px;
margin-left: 50px;
}
.image-mode {
object-fit: contain;
}
.color-column {
flex-direction: row;
align-content: center;
margin-top: 20px;
}
.color-item {
height: 50px;
width: 50px;
margin-left: 50px;
padding-left: 10px;
}
.color-item:focus {
background-color: white;
}
.description-first-paragraph {
padding-left: 60px;
padding-right: 60px;
padding-top: 30px;
}
.description {
color: #7a787d;
font-size: 15px;
}
.cart {
justify-content: center;
margin-top: 20px;
}
.cart-text {
font-size: 20px;
text-align: center;
width: 300px;
height: 50px;
background-color: #6495ed;
color: white;
}
.cart-text-focus {
font-size: 20px;
text-align: center;
width: 300px;
height: 50px;
background-color: #4169e1;
color: white;
}
.add-cart-text {
font-size: 20px;
text-align: center;
width: 300px;
height: 50px;
background-color: #ffd700;
color: white;
}
构建页面逻辑
开发者在 index.js 文件中构建页面逻辑,主要实现的是两个逻辑功能:
- 当焦点移动到不同颜色的圆形,swiper 滑动到不同的图片;
- 当焦点移动到购物车区时,“Add To Cart”背景颜色从浅蓝变成深蓝,点击后文字变化为“Cart + 1”,背景颜色由深蓝色变成黄色,添加购物车不可重复操作。
逻辑页面代码示例如下:
// index.js
export default {
data: {
cartText: 'Add To Cart',
cartStyle: 'cart-text',
isCartEmpty: true,
descriptionFirstParagraph: 'This is the food page including fresh fruit, meat, snack and etc. You can pick whatever you like and add it to your Cart. Your order will arrive within 48 hours. We gurantee that our food is organic and healthy. Feel free to ask our 24h online service to explore more about our platform and products.',
imageList: ['/common/food_000.JPG', '/common/food_001.JPG', '/common/food_002.JPG', '/common/food_003.JPG'],
canvasList: [{
id: 'cycle0',
index: 0,
color: '#f0b400',
}, {
id: 'cycle1',
index: 1,
color: '#e86063',
}, {
id: 'cycle2',
index: 2,
color: '#597a43',
}, {
id: 'cycle3',
index: 3,
color: '#e97d4c',
}],
},
onShow() {
this.canvasList.forEach(element => {
this.drawCycle(element.id, element.color);
});
},
swipeToIndex(index) {
this.$element('swiperImage').swipeTo({index: index});
},
drawCycle(id, color) {
var greenCycle = this.$element(id);
var ctx = greenCycle.getContext("2d");
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(15, 25, 10, 0, 2 * 3.14);
ctx.closePath();
ctx.stroke();
ctx.fill();
},
addCart() {
if (this.isCartEmpty) {
this.cartText = 'Cart + 1';
this.cartStyle = 'add-cart-text';
this.isCartEmpty = false;
}
},
getFocus() {
if (this.isCartEmpty) {
this.cartStyle = 'cart-text-focus';
}
},
lostFocus() {
if (this.isCartEmpty) {
this.cartStyle = 'cart-text';
}
},
}
效果示例
实现此实例后,效果示例如下图所示。
图3 运行效果
更多建议: