鸿蒙数据传值
//* 传值
//* @State
/*
*@State创建一个响应式的数据,但不是所有的更改都会引起刷新,只有被框架观察到的修改才会被刷新UI
* 1. 基本数据类型如 number string boolean等值的变化修改
* 2. Object类型,只会观察到第一层的数据变化或者自身数据的赋值变化.原因是,监听多层会消耗巨大的性能
* */
//* @Prop
/*
* @Prop 父子单项传值
* 在父组件中通过参数的方式传递,在子组件中通过@prop接收,如果没有通过@prop接收,那么他就无法得到响应式,
* 即无法随着父组件的数据修改而被修改
* 在子组件中可以修改@prop传值,但是当父组件修改之后,子组件的依旧会被覆盖
* 也可以给子组件传递一个函数,通过接收该函数来修改数据,来实现数据的同步
* 在给子组件传递的函数时,应该是一个箭头函数,原因就是this指向问题
* */
//* @Link 可以实现双向同步绑定 -- 不需要提供默认值
//* @Provide @Consume 跨组件传值
//* @Observed @ObjectLink 嵌套对象数组
/*
* 可以直接监听到对象的内层嵌套
* 需要通过class类来创建对象
* @ObjectLink 不可以使用在Entry入口文件中
* UI的更新,不根据数据的更新而更新,而是依附于@ObjectLink
* */
interface ClPerson {
name:string
age:number
}
@Observed
class Person {
name:string
age:number
constructor(infoObj:ClPerson) {
this.name = infoObj.name
this.age = infoObj.age
}
}
@Component
struct Son {
@Prop sonMessage :string = ""
@Link sonName:string
sonChange=()=>{}
build() {
Column(){
Text(`这是子组件的数据${this.sonMessage}-${this.sonName}`)
Button('修改').onClick(()=>{
this.sonChange();
this.sonName = '本'
})
}
}
}
@Component
struct Son2 {
@ObjectLink info:Person
build() {
Text(`学生的信息:${this.info.name}-${this.info.age}`)
}
}
@Entry
@Component
struct Index {
@State message: string = 'nihao';
@State name:string = "Ben"
@State personArr:ClPerson[] = [new Person({name:'ben',age:18}),new Person({name:'ben',age:18})]
build() {
Column(){
Text(`这是父组件的数据${this.message}} - ${this.name}}`)
Son({
sonMessage:this.message,
sonName:this.name,
sonChange:()=>{this.message="您好"}
})
List(){
ForEach(this.personArr,(item:ClPerson,index:number)=>{
ListItem(){
Son2({
info:item
})
}
})
}
}
}
}
成员变量和成员函数
//* 成员变量和成员函数
/*
* 定义在strcu中的变量或者函数
*成员变量通过外部传参可以被修改
* 成员函数只有箭头函数可以被修改
* */
//* BuilderParam 传递UI
/*
* 通过BuilderParam可以允许用户在自定义组件中传递UI
* 多个BuilderParam传递通过参数的形式而不是尾随闭包
* -->
* Son({
* oneBuilderParam:结构1
* twoBuilderParam:结构二
* })
* */
@Component
struct Son {
@BuilderParam contentBuilderParam:()=> void = this.builderParam
@State title:string = '默认文本'
@Builder
builderParam() {
Text('默认builderParam')
}
build() {
Column() {
Row() {
Text(this.title)
}
this.contentBuilderParam()
}
}
}
@Component
struct Son2 {
@BuilderParam Bp1:() => void =this.builderContent1
@BuilderParam Bp2:() => void =this.builderContent2
@Builder
builderContent1() {
Text('son2默认文本1')
}
@Builder
builderContent2() {
Text('son2默认文本2')
}
build() {
Column() {
this.Bp1()
this.Bp2()
}
}
}
@Entry
@Component
struct Index {
@State message: string = 'nihao';
clickFun = () => {
console.log('112233')
}
@Builder
Son21() {
Text('这是修改的son2中的1')
}
@Builder
Son22() {
Text('这是被修改的Son2中的2')
}
build() {
Column() {
Son({title:'这是标题'}){
Button('这是按钮').onClick(()=>{
this.clickFun()
})
}
Son2({
Bp1:this.Son21,
Bp2:this.Son22
})
}
}
@Styles @Builder @Extend
// * swiper组件
/*
* loop 是否循环
* autoplay 是否自动播放
* interval 间隔时长
* vertical 纵/横
* */
// * 指示器的样式修改 indicator - false 则不展示
/*
* Indicator.dot()
.itemWidth(20) 默认指示器
.itemHeight(20)
.color(Color.Black)
.selectedItemWidth(40) 选中指示器
.selectedItemHeight(20)
.selectedColor(Color.Red)
* */
// * aspectRatio(1) 宽高比
//* @Extend 扩展组件的样式 事件实现复用
/*
* @Extend(组件名)
* function funName(参1,参2,...) {}
* */
@Extend(Text)
function swiperTextExtend(bgc: ResourceColor,msg: string) {
.fontSize(20)
.fontWeight(700)
.textAlign(TextAlign.Center)
.backgroundColor(bgc)
.onClick(()=>{
AlertDialog.show({
message:msg
})
})
}
// * @Styles 抽取通用属性和方法 不支持传参 局部的或者外部的调用方法一致
@Styles function commitStyle() {
.width(100)
.height(100)
}
// * @Builder 自定义的构建函数 结构 样式 事件 调用内部方法需要使用 this.funName
interface ImgInter {
imgUrl:string
number:number
getImg:string
}
@Builder
function commitBuilder(number:number,getImg:string,imgUrl:string) {
Badge({
count:number,
position:BadgePosition.RightTop,
style:{
fontSize:12,
badgeSize:16,
badgeColor:"#d7000f"
}
}){
Image($r(getImg ? getImg: imgUrl)).width(60)
}
}
@Entry
@Component
struct Index {
@State message: string = 'nihao';
@Styles commitFun() {
.onClick(()=>{
this.message = '你好'
})
}
@State imgArr: ImgInter[] = [
{
imgUrl:'app.media.cj_01',
number:0,
getImg:''
},
{
imgUrl:'app.media.cj_02',
number:0,
getImg:''
},
{
imgUrl:'app.media.cj_03',
number:0,
getImg:''
},
{
imgUrl:'app.media.cj_04',
number:0,
getImg:''
},
{
imgUrl:'app.media.cj_05',
number:0,
getImg:''
},
{
imgUrl:'app.media.cj_06',
number:0,
getImg:''
},
]
build() {
Column(){
Swiper(){
Text("1").swiperTextExtend(Color.Orange,'弹窗1')
Text("2").swiperTextExtend(Color.Pink,'弹窗2')
Text("3").swiperTextExtend(Color.Green,'弹窗3')
}.width("100%")
.height(250)
.loop(true)
.autoPlay(true)
.interval(4000)
.vertical(false)
.indicator(
Indicator.dot()
.itemWidth(20)
.itemHeight(20)
.color(Color.Black)
.selectedItemWidth(40)
.selectedItemHeight(20)
.selectedColor(Color.Red)
)
Text('这是文本:'+this.message).commitStyle().commitFun()
Grid(){
ForEach(this.imgArr,(item:ImgInter,index:number)=> {
GridItem(){
commitBuilder(item.number,item.getImg,item.imgUrl)
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr')
.width('100%')
.height(200)
}
}
}
scroll
// * scroll
/*
* scroll 中只允许拥有一个子组件
*
* 属性
* scrollable:
* ScrollDirection.Horizontal 横向
* ScrollDirection.Vertical 纵向
* scrollBar: 控制滚动条显示隐藏
* BarState.On 打开
* BarState.Off 关闭
* edgeEffect: 滑动的动态效果
* Spring Fade
*
* 控制器
* 1. 创建scroller实例
* 2. 绑定scroll组件
* 3. 调用方法 scrollEdge()
* */
@Entry
@Component
struct Index {
@State message: string = 'nihao';
scroll: Scroller = new Scroller();
build() {
Column(){
Scroll(this.scroll){
Column({space:20}){
ForEach(Array.from({length:20}),(item:number,index:number)=> {
Text('这是文本'+index)
.width('100%')
.height(120)
.borderRadius(8)
.fontSize(20)
.fontWeight(800)
.backgroundColor(Color.Orange)
.fontColor(Color.White)
})
}
}.width("100%")
.padding(10)
.height(400)
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Off)
.scrollBarColor(Color.Pink)
.scrollBarWidth(30)
.edgeEffect(EdgeEffect.Spring)
.onScroll((x,y)=>{
console.log('滚动到',this.scroll.currentOffset().yOffset)
})
Button('回到顶部').margin(20).onClick(()=>{
this.scroll.scrollEdge(Edge.Top)
})
Button('获取已经滚动的距离').onClick(()=>{
const y = this.scroll.currentOffset().yOffset
console.log('这是y',y)
})
}
}
tabs
//* tabs
/*
* 属性
* barposition 调整位置
* vertical 垂直 / 水平
* scrollable 是否手势滑动切换
* animationDuration 滑动时间
* barMode 是否滑动
* */
@Entry
@Component
struct Index {
@State message: string = 'nihao';
@State selectIndex: number = 0
@Builder
myTabs(tabIndex:number,img:ResourceStr,selectImg:ResourceStr,title:string) {
Column({space:4}){
Image(tabIndex == this.selectIndex ? selectImg : img).width(20)
Text(title).fontColor(tabIndex == this.selectIndex ? Color.Red : Color.Black)
}
}
build() {
// Tabs({barPosition:BarPosition.Start}){
// TabContent(){
// Text('首页内容')
// }.tabBar('首页')
// TabContent(){
// Text('推荐内容')
// }.tabBar('推荐')
// TabContent(){
// Text('列表内容')
// }.tabBar('列表')
// TabContent(){
// Text('我的内容')
// }.tabBar('我的')
// }
// .vertical(true)
// .scrollable(false)
// .animationDuration(1000)
// .barMode(BarMode.Scrollable)
Tabs({barPosition:BarPosition.End}){
TabContent(){
Text('淘宝页面')
}.tabBar(this.myTabs(0,$r('app.media.cj_01'),$r('app.media.cj_d01'),'淘宝'))
TabContent(){
Text('QQ页面')
}.tabBar(this.myTabs(1,$r('app.media.cj_02'),$r('app.media.cj_d02'),'QQ'))
}.onChange((index:number)=> {
this.selectIndex = index
})
}
}
数据格式和state状态管理
// 数据的格式转换
// * 数字转字符串
/*
* Number() let a = '1.1' Number(a) => 1.1 转失败则为NaN
* parseInt() 去掉小数点部分
* parseFloat() 保留小数点部分 let a = '1.1a' parseFloat(a) => 1.1 自动去掉字符部分
* */
// * 字符串转数字
/*
* toString() let a = 1 a.toString()
* toFixed 四舍五入转文本
* */
// * 状态管理 state
/*
* 核心 state会直接决定UI的初始化渲染,UI一旦发生交互,就会修改state变量,state变量发生变化自动触发UI渲染
* 普通变量:只会在初始化的时候渲染UI,后续变化无法直接渲染
* 状态变量:只要发生变化就可以渲染UI
* */
let myName: string = 'Ben'
@Entry
@Component
struct Index {
@State message: string = 'nihao';
myAge:number = 18
build() {
Column(){
Text(myName)
Text(this.myAge.toString())
Text(this.message)
Button('修改Message').onClick(()=> {
this.message = '你好,你会找到一个满意的工作';
console.log('1122')
})
}
}
}