前端转鸿蒙开发学习

1,906 阅读3分钟

基础知识

本文需要有一定前端开发经验

如果有看过鸿蒙官方文档是最好的 详细教程移步官方文档

我们需要用到deveco开发工具然后创建一个项目。创建好后基本格式如下图所示。页面文件放在entry下面的pages文件夹下,正常开发一般是创建一个ets文件

image.png

页面构建相关总结

最近写了一个月鸿蒙了,感觉有html+css+js基础,学习入门不会太难。 类比学习 在构建页面,可以通过类比的方式学习。

在开始之前需要简单了解一下鸿蒙页面结构,

@Entry
@Component
struct demoPage {
  @State nickname: string = "流萤"
  build() {
    Column() {
      Column(){
        userInfo({userName: this.nickname})
      }.width("100%").height("240lpx").margin({bottom: "24lpx"})
      Column(){
        Text('学习计划...') // 此处为具体设计布局,text仅作案例代替详细信息模块
      }.width("100%").height("240lpx").margin({bottom: "24lpx"})
    }.width("100%").height("500lpx")
  }
}

@Component // 自定义组件
export struct userInfo {
  @Prop userName: string = ''
  build() {
    Row() {
      Image($r('app.media.app_icon')).width('64lpx').height('64lpx').borderRadius('32lpx')
      Text(this.userName)
    }.width('100%').height("72lpx").justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Center)
  }
}

在需要的时候可以在文件内 export 组定义组件,也可以单独创建文件夹定义组件

1.p标签,span标签和Text组件

在HTML中,我们写一段文字链接可能是

<p>1、请阅读
  <span style="color: #2ACF6F" @click="gowebView(item.url)">
    《用户隐私协议》
  </span>
</p>
  gowebView(url) {
    this.window.open(url)
  }

在鸿蒙中,创建一段文字,可以用 Text组件实现,比如我们创建一段文字

Text() {
  Span('1、请阅读')
  Span('《用户隐私协议》')
    .onClick(() => {
      this.goWebview(LinkConstants.SDKDirectory)
    })
    .fontColor('#2ACF6F')
}
.fontSize('26lpx')
.fontColor('#333333')
.textAlign(TextAlign.Start)

可以把Text组件当成p标签,span则一样

鸿蒙中写样式有点像HTML的内联样式,只是在css中是通过"-"链接,比如:

.font-size: 22px,在鸿蒙则是.fontSize('22px')

2.div与Column,Row组件的联想

在HTML中,div是块级元素,比如我们创建一个模块,上面放用户信息,下面放学习计划

<div class="header-container">
  <div class="userInfo">用户信息...</div>
  <div class="studyPlan">学习计划...</div>
</div>

在鸿蒙中,我们可以做类似的布局思想

Column() {
  Column(){
    Text('用户信息...') // 此处为具体设计布局,text仅作案例代替详细信息模块
  }.width("100%").height("240lpx").margin({bottom: "24lpx"})
  Column(){
    Text('学习计划...') // 此处为具体设计布局,text仅作案例代替详细信息模块
  }.width("100%").height("240lpx").margin({bottom: "24lpx"})
}.width("100%").height("500lpx")

前端开发中经常会用到flex布局,比如一个左右布局的用户信息,效果如图:

image.png

    <div class="userInfo">
      <img class="avatar" src="../../assets/avatar_01.png" />
      <div class="info">
        <div class="nickname">流萤</div>
        <div class="ID">26710</div>
      </div>
    </div>
  .userInfo {
    width: 100%;
    display: flex;
    align-items: center;
    .avatar {
      width: 64px;
      height: 64px;
      display: block;
      margin-right: 12px;
    }
    .info {
      height: 64px;
      .nickname {
        font-size: 20px;
        font-weight: bold;
        color: #666666;
        height: 36px;
      }
      .ID {
        height: 28px;
        font-size: 16px;
        font-weight: 400;
        color: #999999;
      }
    }
  }

在鸿蒙中我们可以使用Row组件,会横向布局,类似于css中的flex

@Component // 自定义组件
export struct userInfo {
  @Prop userName: string = ''
  build() {
    Row() {
      Image($r('app.media.app_icon')).width('64lpx').height('64lpx').borderRadius('32lpx')
      Text(this.userName)
    }.width('100%').height("72lpx").justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Center)
  }
}

// 然后在父组件使用
@Entry
@Component
struct demoPage {
  @State nickname: string = "流萤"
  build() {
    Column() {
      Column(){
        userInfo({userName: this.nickname}) // 此处使用userInfo组件
      }.width("100%").height("240lpx").margin({bottom: "24lpx"})
    }.width("100%").height("500lpx")
  }
}

除了Row组件之外,还可以使用Flex组件来实现弹性布局

interface user {
  nickname: string,
  avatar: string,
  age: string
}

Scroll() {
  Flex({wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceBetween}) {
    ForEach(this.userList, (item: user, index)=> {
      userInfo({data: item, type: 1})
    })
  }.width('100%').margin({bottom: '48lpx'})
  .padding({top: '0lpx', left: '25lpx', right: '25lpx'})
}

以上是使用了一个滚动容器+flex组件布局,可以看到flex使用和css类似,换行,靠近两边的一个flex布局。

2.1拓展,ForEach与v-for

熟悉vue的都知道,在vue中循环一串列表一般会用到v-for,在鸿蒙里面,对应ForEach。

继续沿用上面的例子,userList是我们的数据,item则是具体的每一项数据,包含昵称,头像,年龄等等。userInfo则是需要渲染的每一项子集组件,接受参数item。

2.2拓展,image组件

Image组件可以直接引用本地资源文件,

Image($r('app.media.app_icon'))

也可以引入网页地址,但是需要在配置文件中开启网络协议,在官方教学课程会提到

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
  }
],
@State url: string = 'https://i1.hdslb.com/bfs/archive/75344ea16cb1fef4b14a63aa65fec2d376db41f0.jpg'
Image(this.url)

3.定位

在前端开发中会用到position:absolute,fixed等等;在鸿蒙中,也有position属性 我们定义一个column,设置宽高100%,然后让子集用position定位到底部。

Column() {
  Text('提交')
    .width("100%").height("240lpx").margin({bottom: "24lpx"})
    .position({bottom: '0lpx', left: '0lpx'})
}.width("100%").height("100%")

这样我们就让提交按钮定位到页面最底部了,他会根据父元素宽高定位

4.Stack组件

Stack组件可以理解为叠层布局,默认上下左右居中布局

@Entry
@Component
struct demoPage {
  @State nickname: string = "流萤"
  build() {
    Stack() {
      Column() {

      }.width('150lpx').height('150lpx').backgroundColor('#666666')
      Column() {

      }.width('100lpx').height('100lpx').backgroundColor('#999999')
    }.width('200lpx').height('200lpx').backgroundColor("#333333")
  }
}

在上述代码中,定义了一个宽高200的容器,也可以理解为stack是一个宽高200的div

但是这个div的特殊之处在于里面的元素可以叠层。效果如图

image.png

总结

到这,基本的布局我们都会了,还有一个list和grid布局可以自行参考官方教学文档,总体来说构建页面不是很难,多实践写写demo,或者做一个自己感兴趣的页面,多练习就熟悉了