真机测试
菜单栏Tools -> Device Manager,需要登陆华为账号。如果什么设备都没有的话就创建一个新的。
Tips
使用JSON格式的文件请求数据时
// @ts-nocheck
import menuData from '../../common/data/cookbook-category.json';
export default{
data:{
type: 'category',
menuData:[]
},
handleSliderClick(type){
//点击事件
console.log(type)
this.type = type
console.log(this.type)
},
computed:{
filteredMenuData() {
return this.menuData[this.type]
}
},
onInit(){
console.log(JSON.stringify(menuData.data));
//这个可以用来判断数据有没有请求成功
this.menuData = menuData.data
}
}
导航栏制作
- 创建文件
src->main->js->default->common,创建data文件夹,在data文件夹下创建tabbarItem.js文件
//img为未选中状况下显示的导航栏图标,simg为选中状况下的,
//name为导航栏中代表对应页面的名字, 显示在图标底下
export default[
{
img:"common/images/home.png",
simg:"common/images/home_green.png",
name:"首页"
},
{
img:"common/images/hot.png",
simg:"common/images/hot_green.png",
name:"热点"
},
{
img:"common/images/us.png",
simg:"common/images/us_green.png",
name:"社区"
},
{
img:"common/images/me.png",
simg:"common/images/me_green.png",
name:"个人信息"
}
]
default文件夹下,创建components文件夹,用于存放可以复用的组件。components下创建tabbar文件夹,tabbar文件夹中创建tabbar.hml,tabbar.css,tabbar.js三个文件。
<!--tabbar.hml-->
<div class="container">
<toolbar class="tabbar">
<!--icon这样设置后点击预览当前页面所对应的导航栏图标就会是simg而不是默认的img了,会变色-->
<!--icon会对jump()传过来的index值进行判断,看选择哪个图片-->
<!--不过页面现在还不会跳转,要看路由-->
<toolbar-item for="{{tabbarItems}}"
icon='{{$idx == index ? $item.simg : $item.img}}'
value='{{$item.name}}'
onclick="jump($idx)" >
</toolbar-item>
<!--value是要显示的文本内容,icon是显示的图标-->
<!--$item是for里面的每个单个项,对应tabbarItem.js里面的内容-->
<!--jump($idx)为js中自定义的方法,可为什么要写成$idex呢,加$?-->
<!--$idx是一个整体,不是$和idx两部分。-->
</toolbar>
</div>
/*tabbar.css*/
.container {
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
/*height: 100%;*/
/*height这个根据具体的实现效果来说*/
}
//
.title {
font-size: 40px;
color: #000000;
opacity: 0.9;
}
.tabbar{
position:fixed;
left:0;
bottom:0;
}
import tabbarItems from '../../common/datas/tabbarItem.js';
import router from '@system.router';
//import是引用外部的
//router这行是必备的
//在这个里面谁是父组件,谁是子组件?
export default {
data:{
tabbarItems
},
//以下为props传值两种写法
//props:["index"],
//
props:{
index:{
type:Number, //index的值类型是Number
default(){
return 0;
}
//默认设置index值为0,即显示首页
}
},
//由各个分页面的的导航栏组件<comp>
//这里用props是指
// tabbar.js的props声明中有index使index可以由index.html传到tabbar.hml
//传完后导航栏发生变化,
//jump是自定义方法。
jump(index){
// this.tabbarItems.forEach((item,index) => {
// item.img = tabbarItems[index].img;
// });
// this.tabbarItems[index].img = this.tabbarItems[index].simg;
switch(index){
case 0:
router.push({
uri:"pages/index/index",
params:{
info:"case0 这是路由传递的参数"
}
});
break;
case 1:
router.push({
uri:"pages/category/category",
// params:{
// info:"case1 这是路由传递的参数"
// }
});
break;
case 2:
router.push({
uri:"pages/more/more",
params:{
info:"这是路由传递的参数"
}
});
break;
case 3:
router.push({
uri:"pages/me/index",
params:{
info:"这是路由传递的参数"
}
});
break;
}
}
}
首页引用导航栏方法
<!--引用导航栏组件-->
<element name='comp' src='../../components/tabbar'></element>
<div>
<comp index="0"></comp>
</div>
搜索栏制作(做个样子,没实际用处)
这个里面的搜索栏还没法输入实际的搜索内容
<!--saearch.hml-->
<div class="search-container {{from === 'cate' ? 'cate-outer-bg' : 'index-outer-bg'}}">
<div class="search-input {{from === 'cate' ? 'cate-inner-bg' : 'index-inner-bg'}}">
<image class="search-input-image" src="../../common/images/搜索.png"></image>
<text class="search-input-text">想吃什么,比如川菜</text>
</div>
</div>
/*search.css*/
.search-container {
padding: 10px 15px;
}
.search-input {
height: 40px;
width: 100%;
justify-content: center;
align-items: center;
border-radius: 6px;
border: 0.5px solid #ee742f;
}
.search-input-image {
width: 20px;
height: 20px;
}
.search-input-text {
font-size: 12px;
font-weight: 100;
}
.index-inner-bg {
background-color: #fff;
}
.cate-inner-bg {
background-color: #f2f2f2;
border-width: 0;
}
.index-outer-bg {
background-color: #f2f2f2;
}
.cate-outer-bg {
background-color: #fff;
}
//search.js
//这里的props在哪个地方用到了呢?
export default{
props:['from']
}
菜单页面
菜单页面下有多个子组件 search
<!--category.html-->
<!--都是引用的子组件,下面会写-->
<!--有一个问题,子组件外面的框是不是要尽可能的小,贴近子组件自身啊,不要在外面套一个很大的div,如果套了的话这样的多个子组件引用的话位置怎么算呢?这是个大问题?-->
<element name='comp' src='../../components/tabbar/tabbar'></element>
<element name="cb-menu" src="./menu-list/menu-list"></element>
<element name="cb-search" src="../../components/search/search"></element>
<div class="cate-container">
<div class="cate-header">
<div class="cate-header-nav">
<div class="cate-header-nav-item" @click="handleSliderClick('category')">
<text class="item-text">
分类
</text>
</div>
<div class="cate-header-nav-item" @click="handleSliderClick('material')">
<text class="item-text">
食材
</text>
</div>
<div if="{{ type === 'category' }}" class="cate-header-nav-slider">
<text class="slider-text">
分类
</text>
</div>
<div else class="cate-header-nav-slider move">
<text class="slider-text">食材</text>
</div>
</div>
</div>
<cb-search from="cate"></cb-search>
<cb-menu menu-data="{{ filteredMenuData }}" first-item="{{ type === 'category' ? '热门' : '肉类' }}"></cb-menu>
<!--导航栏不显示-->
<comp index="1" style="color: red;"></comp>
</div>
.cate-container {
flex-direction: column;
height: 100%;
}
.cate-header {
width: 100%;
height: 44px;
background-color: #ee742f;
justify-content: center;
align-items: center;
}
.cate-header-nav {
width: 140px;
height: 30px;
border-radius: 30px;
border: 0.5px solid #FFF;
position: relative;
z-index: 1;
}
.cate-header-nav-item {
flex: 1;
justify-content: center;
align-items: center;
height: 30px;
}
.item-text {
font-size: 12px;
color: #FFF;
}
.cate-header-nav-slider {
position: absolute;
left: 0;
border-radius: 30px;
width: 70px;
height: 30px;
background-color: #FFF;
z-index: 0;
justify-content: center;
align-items: center;
transition: left 200ms ease-in;
font-size: 16px;
}
.slider-text {
font-size: 12px;
color: #ee742f;
}
.move {
left: 70px;
}
//category.js
// @ts-nocheck
import menuData from '../../common/data/cookbook-category.json';
//引用外部json文件,这个json文件的内容显示交给那些子组件吧
export default{
data:{
type: 'category',
menuData:[]
},
handleSliderClick(type){
console.log(type)
this.type = type
console.log(this.type)
},
computed:{
filteredMenuData() {
return this.menuData[this.type]
}
},
onInit(){
// console.log(JSON.stringify(menuData.data));
this.menuData = menuData.data
}
}
菜单侧栏组件
<!--menu-list.html-->
<div class="menu-container">
<div class="menu-tab">
<div class="menu-tab-item {{ $item === currentTab ? 'menu-tab-item-active' : 'menu-tab-item-normal' }}"
for="{{ tabs }}"
@click="handleTabClick($item)">
<text class="menu-tab-item-text">
{{ $item }}
</text>
</div>
</div>
<div class="menu-list">
<div class="menu-list-item" for="{{ lists }}">
<text class="menu-list-item-text">
{{ $item }}
</text>
</div>
</div>
</div>
/*menu-list.css*/
.menu-container {
/* flex: 1;*/
border-top: 0.5px solid #CCC;
}
.menu-tab {
width: 100px;
background-color: #f3f3f3;
flex-direction: column;
}
.menu-tab-item {
height: 60px;
justify-content: center;
align-items: center;
width: 100px;
}
.menu-tab-item-text {
font-size: 12px;
font-weight: 100;
/* height: 100%;*/
/* align-content: stretch;*/
}
.menu-tab-item-normal {
background-color: #f3f3f3;
}
.menu-tab-item-text-normal {
/* font-size: 12px;*/
/* font-weight: 100;*/
/* height: 100%;*/
/* align-content: stretch;*/
color: #000;
border-bottom: 0;
}
.menu-tab-item-active {
background-color: #FFF;
}
.menu-tab-item-text-active {
font-size: 12px;
font-weight: 100;
/* height: 100%;*/
/* align-content: stretch;*/
/* color: #ee742f;*/
/* border-bottom: 2px solid #ee742f;*/
}
.menu-list {
flex: 1;
flex-wrap: wrap;
}
.menu-list-item {
width: 33.333333%;
height: 40px;
justify-content: center;
align-items: center;
}
.menu-list-item-text {
font-size: 12px;
font-weight: bold;
}
//props里的,表示用来接受其他组件传进来的值
//组件中menuData、firstItem都是一个prop,将两个属性放到一起,就是props,这就是props的由来,是prop的复数形式,代表多个prop属性的集合。
export default {
props: ['menuData', 'firstItem'],
data() {
console.log(this.menuData)
//如果的得到了数据,这里会显示[Obejct,Object]
return {
currentTab: this.firstItem
}
},
handleTabClick(currentTab) {
this.currentTab = currentTab
},
//用于 menu切换
computed: {
tabs() {
console.log(Object.keys(this.menuData))
return Object.keys(this.menuData)
},
lists() {
return this.menuData[this.currentTab]
}
},
onReady() {
this.$watch('firstItem',(newValue) =>{
this.currentTab = newValue
})
}
}