微信小程序基础知识-进阶一

做小程序开发已有快一年,写下自己的心得,希望多大家有帮助!微信开放文档

小程序Dom元素使用的是view而不是div。

小程序中block元素不渲染在页面中,只用来作为逻辑容器                        

  • 小程序使用wx:if和wx:for语法

  • 小程序绑定事件使用 bindtap和catchtap,bindtap会事件冒泡 而catchTap不会事件冒泡。

小程序动态绑定样式或类名

一、动态绑定样式

通过 style 属性可以动态设置元素的内联样式。你可以将样式值绑定到数据中,并根据逻辑动态更新。

<view style="width: {{width}}px; height: {{height}}px; background: {{color}};"></view>
<button bindtap="changeStyle">改变样式</button>
Page({
  data: {
    width: 100,
    height: 100,
    color: 'red'
  },
  changeStyle() {
    this.setData({
      width: 200,
      height: 200,
      color: 'blue'
    });
  }
});

说明:style 属性中的值使用双大括号 {{}} 绑定到数据。
调用 setData 更新数据后,视图会自动刷新 

二、动态拼接样式 

如果需要拼接多个样式,可以在 JavaScript 中生成完整的样式字符串:

基本用法 :
<view style="{{dynamicStyle}}"></view>
<button bindtap="updateStyle">更新样式</button>
Page({
  data: {
    dynamicStyle: 'width: 100px; height: 100px; background: red;'
  },
  updateStyle() {
    this.setData({
      dynamicStyle: 'width: 200px; height: 200px; background: green;'
    });
  }
});
.active {
  color: green;
}
.inactive {
  color: red;
}

 说明:

  • 使用三元运算符 {{condition ? 'classA' : 'classB'}} 动态切换类名。
  • 在 CSS 文件中定义 active 和 inactive 类 
多个类名的拼接:

如果需要同时应用多个类名,可以使用数组或字符串拼接的方式:

<view class="base-class {{extraClass}}">内容</view>
<button bindtap="addExtraClass">添加额外类名</button>
Page({
  data: {
    extraClass: ''
  },
  addExtraClass() {
    this.setData({
      extraClass: 'highlight'
    });
  }
});
.base-class {
  font-size: 16px;
}
.highlight {
  color: blue;
  font-weight: bold;
}
条件组合类名 

如果需要根据多个条件动态组合类名,可以使用模板语法:

<view class="item {{isBold ? 'bold' : ''}} {{isRed ? 'red' : ''}}">内容</view>
<button bindtap="toggleBold">切换加粗</button>
<button bindtap="toggleRed">切换红色</button>
Page({
  data: {
    isBold: false,
    isRed: false
  },
  toggleBold() {
    this.setData({
      isBold: !this.data.isBold
    });
  },
  toggleRed() {
    this.setData({
      isRed: !this.data.isRed
    });
  }
});
.bold {
  font-weight: bold;
}
.red {
  color: red;
}
 动态绑定样式与类名结合

可以同时动态绑定样式和类名,以实现更复杂的效果,如获取设备的宽高来设置导航栏位置等:

<view class="{{isActive ? 'active' : 'inactive'}}" style="font-size: {{fontSize}}px;">内容</view>
<button bindtap="toggleActive">切换状态</button>
<button bindtap="increaseFontSize">增大字体</button>
Page({
  data: {
    isActive: true,
    fontSize: 16
  },
  toggleActive() {
    this.setData({
      isActive: !this.data.isActive
    });
  },
  increaseFontSize() {
    this.setData({
      fontSize: this.data.fontSize + 2
    });
  }
});
.active {
  color: green;
}
.inactive {
  color: red;
}
总结
  • 动态绑定样式:通过 style 属性绑定数据,支持动态更新样式值。
  • 动态绑定类名:通过 class 属性绑定数据,支持条件切换或多类名拼接。
  • 数据驱动:尽量避免直接操作 DOM,而是通过 setData 更新数据,触发视图刷新。 

小程序获取Dom元素的方法

        在小程序中,获取 DOM 元素的方式与传统的 Web 开发有所不同。由于小程序的视图层和逻辑层是分离的,因此无法直接使用 document.querySelector 或类似的方法来操作 DOM。以下是小程序中获取 DOM 元素的常见方法: 

使用 SelectorQuery
基本用法
Page({
  data: {},
  onReady() {
    // 创建 SelectorQuery 实例
    const query = wx.createSelectorQuery();

    // 查询指定选择器的节点
    query.select('#myElement').boundingClientRect((rect) => {
      console.log(rect); // 输出元素的位置和尺寸信息
    }).exec();
  }
});
获取多个元素 

如果需要获取多个元素,可以使用 selectAll 方法: 

Page({
  data: {},
  onReady() {
    const query = wx.createSelectorQuery();

    // 查询所有匹配的选择器的节点
    query.selectAll('.myClass').boundingClientRect((rects) => {
      console.log(rects); // 输出所有匹配元素的位置和尺寸信息
    }).exec();
  }
});
获取滚动位置 

如果需要获取某个滚动容器的滚动位置,可以使用 scrollOffset 方法:

Page({
  data: {},
  onReady() {
    const query = wx.createSelectorQuery();

    query.select('#scrollView').scrollOffset((res) => {
      console.log(res.scrollTop, res.scrollLeft); // 输出滚动位置
    }).exec();
  }
});
使用 NodesRef 的其他方法 

        SelectorQuery 返回的 NodesRef 对象支持多种方法,用于获取不同的节点信息。

 获取节点的字段信息

fields 方法可以获取节点的特定字段信息,例如大小、位置、数据集等:

Page({
  data: {},
  onReady() {
    const query = wx.createSelectorQuery();

    query.select('#myElement').fields({
      size: true,       // 获取宽高
      scrollOffset: true, // 获取滚动位置
      dataset: true     // 获取自定义数据
    }, (res) => {
      console.log(res.width, res.height); // 宽高
      console.log(res.dataset);          // 自定义数据
    }).exec();
  }
});
获取上下文信息 

        如果需要获取 Canvas 或视频等组件的上下文,可以使用 context 方法: 

Page({
  data: {},
  onReady() {
    const query = wx.createSelectorQuery();

    query.select('#myCanvas').context((res) => {
      console.log(res.context); // 输出 Canvas 上下文
    }).exec();
  }
});
注意事项: 
  • 异步性:SelectorQuery 是异步的,必须调用 .exec() 才会执行查询。
  • 时机问题:确保在页面或组件渲染完成后再调用 SelectorQuery,通常可以在 onReady 生命周期中执行。
  • 性能优化:避免频繁调用 SelectorQuery,尤其是在高频事件(如滚动或触摸事件)中。
  • 兼容性:不同平台的小程序(如微信、支付宝、百度等)可能对 SelectorQuery 的支持略有差异,请参考对应平台的文档 

小程序父子组件传参和事件调用 

一、父组件向子组件传参 

父组件可以通过 properties 向子组件传递参数。这是最常见的一种通信方式。 

1.子组件定义接收参数 

在子组件的 properties 中定义需要接收的参数:

// 子组件(child-component.js)
Component({
  properties: {
    // 接收父组件传递的参数
    title: {
      type: String,
      value: '默认标题'
    },
    count: {
      type: Number,
      value: 0
    }
  }
});
2.父组件传递参数 

在父组件的 WXML 中通过属性绑定的方式传递参数:

<!-- 父组件 -->
<child-component title="父组件传递的标题" count="{{parentCount}}"></child-component>
// 父组件(parent-component.js)
Page({
  data: {
    parentCount: 42
  }
});
3.子组件使用参数 

在子组件中可以直接通过 this.properties 访问传递过来的参数(虽然使用this.data也能访问,但更推荐使用this.properties): 

console.log(this.properties.title); // 输出:父组件传递的标题
console.log(this.properties.count); // 输出:42
二、子组件向父组件传递事件 

子组件可以通过触发自定义事件向父组件传递数据。父组件需要监听这些事件并处理。 

1.子组件触发事件 

 在子组件中使用 triggerEvent 方法触发事件,并传递数据:

// 子组件(child-component.js)
Component({
  methods: {
    sendDataToParent() {
      const data = { message: '来自子组件的消息', value: 123 };
      this.triggerEvent('customEvent', data);
    }
  }
});
2.父组件监听事件 

在父组件的 WXML 中通过 bind 或 catch 监听子组件触发的事件:

<!-- 父组件 -->
<child-component bind:customEvent="handleCustomEvent"></child-component>

在父组件的 JS 文件中定义事件处理函数:

// 父组件(parent-component.js)
Page({
  handleCustomEvent(event) {
    console.log(event.detail.message); // 输出:来自子组件的消息 无论子组件传递的是一个简单数据类型还是复杂数据类型 父组件接受event永远是一个对象
    console.log(event.detail.value);   // 输出:123
  }
});
三、父组件主动调用子组件的方法 

父组件可以通过 selectComponent 获取子组件实例,然后直接调用子组件的方法(也可以获取子组件属性)。 

 1.子组件定义方法

在子组件中定义一个方法供父组件调用:

// 子组件(child-component.js)
Component({
  methods: {
    sayHello() {
      console.log('Hello from child component!');
    }
  }
});
2.父组件调用子组件方法 

 在父组件中使用 this.selectComponent 获取子组件实例,并调用其方法:

// 父组件(parent-component.js)
Page({
  callChildMethod() {
    const child = this.selectComponent('#myChild');
    if (child) {
      child.sayHello(); // 调用子组件的方法
    }
  }
});

注意:在父组件的 WXML 中为子组件设置唯一的 id

<!-- 父组件 -->
<child-component id="myChild"></child-component>
<button bindtap="callChildMethod">调用子组件方法</button>
四、使用全局状态管理(可选,一般用于存储和更新全局数据如用户手机号等) 

如果父子组件之间层级较深,或者需要频繁通信,可以考虑使用全局状态管理工具(如 getApp() 或第三方库 mobx-miniprogram)来共享数据。

用 getApp() 共享全局数据 

在 app.js 中定义全局数据:

// app.js
App({
  globalData: {
    sharedValue: '全局共享数据'
  }
});

 在父组件或子组件中访问全局数据:

const app = getApp();
console.log(app.globalData.sharedValue); // 输出:全局共享数据
修改全局数据 

在任何组件都可以修改全局数据,每次访问全局数据最好都在onshow的时候获取,避免在当前页面修改了数据,返回上一页的时候使用的data里的全局数据还未同步: 

const app = getApp();
app.globalData.sharedValue = '新的全局数据';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值