文章目录
常见组件
view
- hover-class 指定按下去的样式类。当 hover-class=“none” 时,没有点击态效果
- hover-stop-propagation 指定是否阻止本节点的祖先节点出现点击态
- hover-start-time 按住后多久出现点击态,单位毫秒
- hover-stay-time 手指松开后点击态保留时间,单位毫秒
text
- 文本标签
- 只能嵌套text
- 长按文字可以复制(只有这个标签有这个功能)
- 可以对空格 回车 进行编码
属性值 | 类型 | 默认值 | 说明 |
---|---|---|---|
selectable | Boolean | false | 文本是否可选 |
decode | Boolean | false | 是否解码 |
<!--
1 长按文字复制 selectable
2 对文本内容 进行 解码
-->
<text selectable decode>
text
123
</text>
<text selectable decode>
text 123<
</text>
image
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
src | String | 图片资源地址 | |
mode | String | ‘scale ToFIll’ | 图片裁剪、缩放的模式 |
lazy-load | Boolean | false | 图片懒加载 |
mode有效值:
mode 有13中模式,其中4种是缩放模式,9种事裁剪模式。
<!--pages/demo07/demo07.wxml-->
<!--
image 图片标签
1 src 指定要加载的图片的路径
图片存在默认的宽度和高度 320 * 240
2 mode 决定 图片内容 如何 和 图片标签 宽度 做适配
1 scaleToFill 默认值 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素
2 aspectFit 保持宽高比 确保图片的长边 显示出来 页面轮播图 常用
3 aspectFill 保持纵横比缩放图片 只保证图片的 短 边能完全显示出来 少用
4 widthFix 宽度不变 高度自动变化 保持原图的宽高比不变 常用
(以前web中的图片的 宽度指定了之后 高度 会自己按比例来调整)
5 bottom......类似以前的background-position
3 小程序中的图片 直接支持 懒加载 lazy-load
1 lazy-load 会自己判断 当图片 出现在视口 上下 三屏的高度 之内的时候 自己开始加载图片
-->
<image mode="widthFix" src="https://s3.ax1x.com/2021/02/15/y6QXk9.jpg">
//图片已经上传到图床上的
</image>
image{
box-sizing:border-box;
border:1px solid red;
width:300px;
height: 500px;
}
scaleToFill
aspectFit
aspectFill
widthFix
swiper
<!--
1 轮播图外层容器 swiper
2 每一个轮播项 swiper-item
3 swiper标签 存在默认的样式
1 width 100%
2 height 150px image 存在默认高度和宽度 320 * 240
3 swiper 高度 无法实现由内容撑开的
4 先找出来原图的宽度和高度 等比例 给swiper 定 宽度和高度
原图的宽度和高度 1125 * 352 px
swiper 宽度 / swiper 高度 = 原图的宽度 / 原图的高度
swiper 高度 = swiper 宽度 * 原图的高度 / 原图的宽度
height : 100% 或 750rpx 或 100wx * 352 px / 1125px
5 autoplay 自动轮播
6 interval 自动修改时间
7 circular 衔接轮播
8 indicator-dots 显示 指示器 分页器 索引器
9 indicator-color 指示器的未选择的颜色
10 indicator-active-color 选中的时候的指示器的颜色
-->
<swiper autoplay interval="1000" circular indicator-dots indicator-color="#0094ff" indicator-active-color="#ff0094">
<swiper-item><image mode="widthFix" src="image/test1.jpg"></image></swiper-item>
<swiper-item><image mode="widthFix" src="image/test2.jpg"></image></swiper-item>
<swiper-item><image mode="widthFix" src="image/test3.jpg"></image></swiper-item>
<swiper-item><image mode="widthFix" src="image/test4.jpg"></image></swiper-item>
</swiper>
/* pages/demo10/demo10.wxss */
swiper{
width: 100%;
height: calc(100vw * 352 / 1125 );
}
image{
width: 100%;
}
navigator
<!--
导航组件 navigator
0 块级元素 默认会换行 可以直接加宽度和高度
1 url 要跳转的页面路径 绝对路径 相对路径
2 target 要跳转到当前的小程序 还是其他的小程序的页面
self 默认值 自己的小程序的页面
miniProgram 其他的小程序的页面
3 open-type 跳转方式
1 navigate 默认值 保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar 页面
2 redirect 关闭当前页面 跳转到应用内的某个页面,但是不能跳到tabbar 页面
3 switchTab 跳转到tabBer 页面 ,并关闭其他所有非 tabBar 页面
4 reLaunch 关闭所有页面,打开到应用内的某个页面
5 navigateBack 关闭当前页面,返回上一页面或多级页面,可通过getCurrentPages() 获取当前的页面栈,决定需要返回几层
6 exit 退出别人的小程序,target="miniProgram"时生效
-->
<navigator url="/pages/demo10/demo10">轮播图页面</navigator>
<navigator url="/pages/index/index">直接跳转到tabbar页面 跳转不了</navigator>
<navigator open-type="redirect" url="/pages/demo10/demo10">轮播图页面 redirect</navigator>
<navigator open-type="switchTab" url="/pages/index/index">switchTab 直接跳转到 tabBer 页面</navigator>
<navigator open-type="reLaunch" url="/pages/index/index">reLaunch 可以随便跳转</navigator>
rich-text 富文本标签
能够把html中的语言 转化为小程序的语言
// pages/demo12/demo12.js
Page({
data: {
// 1 标签字符串 最常用的
// html 中复制的是 淘宝触屏版页面中的一段
// html:'淘宝触屏版页面中的一段代码'
// 2 对象数组
html:[
{
// 1 div 标签 name属性来指定
name:"div",
// 2 标签上有哪些属性
attrs:{
//标签上的属性 class style
class:"my_div",
style:"color:red;"
},
// 3 子节点 children 要接收的数据类型和nodes 第二种渲染方式的数据类型一致
children:[
{
name:"p",
attrs:{},
// 放文本
children:[
{
type:"text",
text:"hello"
}
]
}
]
}
]
}
})
<!--
rich-text 富文本标签
1 nodes 属性来实现
1 接收标签字符串
2 接收对象数组
-->
<rich-text nodes="{{html}}"></rich-text>
button
// pages/demo13/demo13.js
Page({
//获取用户的手机号码信息
getphonenumber(e){
console.log(e);
},
//获取用户个人信息
getUserInfo(e){
console.log(e);
}
})
<!--
button 标签
1 外观的属性
1 size 控制按钮的大小的
1 default 默认大小
2 mini 小尺寸
2 type 用来控制按钮的颜色
1 default 灰色
2 primary 绿色
3 warn 红色
3 plain 按钮是否镂空 背景色透明
4 loading 是否在名称前面 加一个等待图标
-->
<button>默认按钮</button>
<button size="mini">mini默认按钮</button>
<button type="primary">primary 默认按钮</button>
<button type="warn">warn默认按钮</button>
<button type="warn" plain>plain 按钮</button>
<button type="primary" loading >loading 按钮</button>
<!--
button 开发能力
open-type :
1 contact 直接打开 客服对话功能 需要在微信小程序的后台配置
2 share 转发当前的小程序 到微信朋友中 不能把小程序 分享到 朋友圈中
3 getPhoneNumer 获取当前用户的手机号码信息 结合一个事件来使用 不是一个企业的小程序帐号 没有权限来获取用户的手机号码
1 绑定一个事件 bindgetphonenumber
2 在事件的回调函数中 通过参数来获取信息
3 获取到的信息 已经加密过了
需要用户自己搭建小程序的后台服务器, 在后台服务器中进行解析 手机号码。返回到小程序中 就可以看信息了
4 getUserInfo 获取当前用的个人信息
1 使用方法 类似 获取用户的手机号码
2 可以直接获取 不存在加密的字段
5 launchApp 在小程序当中 直接打开 app
1 需要先在 app中 通过app中的某个链接 打开 小程序
2 在小程序中 再通过这个功能 重新打开app
3 找到 京东的app 和 京东的小程序
6 openSetting 打开小程序内置的 授权页面
1 授权页面中 只会出现 用户曾经点击过的 权限
7 feedback 打开 小程序内置的 意见反馈页面
1 只能够通过真机调试来打开 跟 contact 类似
-->
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getphonenumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetUserInfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
open-type的contact 的实行流程
- 小程序的appid 由测试号改为自己的appid
- 登录微信小程序官网,添加 客服- 微信
- 准备两个帐号
普通用户a
客服-微信b - 用普通用户a进行扫码
- 点击contact按钮 就可以与客服号交流
icon
<!--
小程序中的字体图标
1 type 图标中的类型
success|success_no_circle|infowarn|waiting|cancel|download|search|clear
2 size 大小
3 color 图标的颜色
-->
<icon type="success" size="23" color="red">
</icon>
radio
// pages/demo14/demo14.js
Page({
data: {
gender:""
},
handleChange(e)
{
// 1 获取单选框中的值
let gender=e.detail.value;
// 2 把值赋值给data中的数据
this.setData({
//gender:gender 相当于
gender})
}
})
<!--
radio 单选框
1 radio标签 必须要和 父元素 radio-group 来使用
2 value 选中的单选框的值
3 需要给radio-group 绑定 change 事件
4 需要在页面中显示 选中的值
-->
<radio-group bindchange="handleChange">
<radio color="red" value="male">男</radio>
<radio color="pink" value="female">女</radio>
</radio-group>
<view>您选中的是:{{gender}}</view>
checkbox
<!--
-->
<view>
<checkbox-group bindchange="handleItemChange">
<checkbox value="{{item.value}}" wx:for="{{list}}" wx:key="id">
{{item.name}}
</checkbox>
</checkbox-group>
<view>
选中的水果:{{checkedList}}
</view>
</view>
// pages/demo15/demo15.js
Page({
data: {
list:[
{
id:0,
name:"苹果",
value:"apple"
},
{
id:1,
name:"葡萄",
value:"grape"
},
{
id:2,
name:"香蕉",
value:"bananer"
}
],
checkedList:[]
},
//复选框的选中事件
handleItemChange(e){
// 1 获取被选中的复选框的值
const checkedList=e.detail.value;
// 2 进行赋值
this.setData({
checkedList
})
}
})
自定义组件
创建自定义组件
步骤
- 现在pages同层级目录下新建一个components的文件夹 components内新建Tabs文件夹 Tabs新建Tabs 组件文件js json wxml wxss
// components/Tabs/Tabs.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
// components/Tabs/Tabs.json
{
"component": true,
"usingComponents": {}
}
<!--components/Tabs/Tabs.wxml-->
<text>components/Tabs/Tabs.wxml</text>
/* components/Tabs/Tabs.wxss */
- 在要使用的页面的json文件中写代码
// pages/demo16/demo16.json
{
"usingComponents": {
"Tabs":"../../components/Tabs/Tabs"
}
}
- 在页面中当成一个普通标签使用即可
<!--
-->
<Tabs>
</Tabs>
实例实现
标题激活选中 + Tabs 样式优化
<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
<view class="tabs_title">
<!-- <view class="title_item">首页</view>
<view class="title_item">原创</view>
<view class="title_item">分类</view>
<view class="title_item">关于</view> -->
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="handleItemTap"
data-index="{{index}}"
>
{{item.name}}
</view>
</view>
<view class="tabs_content">内容</view>
</view>
// components/Tabs/Tabs.js
Component({
/**
* 里面存放的是 要从父组件中接收的数据
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
tabs:[
{
id:0,
name:"首页",
isActive:true
},
{
id:1,
name:"原创",
isActive:false
},
{
id:2,
name:"分类",
isActive:false
},
{
id:3,
name:"关于",
isActive:false
}
]
},
/**
1 页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
2 组件.js 文件中 存放事件回调函数的时候 必须要存放在methods中!!!
*/
methods: {
handleItemTap(e){
/*
1 绑定点击事件 需要在methods中绑定
2 获取被点击的索引
3 获取原数组
4 对数组循环
1 给每一个循环性 选中属性 改为false
2 给 当前的 索引的 项 添加激活选中效果就可以了!!!
*/
// 2 获取索引
const {index}=e.currentTarget.dataset;
// 3 获取data中的数组
// 解构 对 复杂类型进行解构的时候 复制了一份 变量的引用而已
// 最严谨的做法 重新拷贝一份 数组,再对这个数组的备份进行处理,
// let tabs=JSON.parse(JSON.stringify(this.data.tabs)); 深拷贝
// 不要直接修改 this.data.数据
// let {tabs}=this.data;= let tabs=this.data.tabs;
let tabs=this.data.tabs;
// 4 循环数组
// [].forEach 遍历数组 遍历数组的时候 修改了 v. 也会导致源数组被修改
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
this.setData({
tabs
})
}
}
})
/* components/Tabs/Tabs.wxss */
.tabs{}
.tabs_title{
display: flex;
padding:10rpx 0;
}
.title_item{
flex:1;
display: flex;
justify-content: center;
align-items: center;
}
.active{
color: red;
border-bottom: 5px solid currentColor;
}
.tabs_content{}
父向子传递数据
原理👇
1 父组件wxml
<!--
1 父组件(页面)传递数据 通过 标签属性的方式来传递
1 在子组件上进行接收
-->
<Tabs aaa="a123b">
</Tabs>
2 子组件js
// components/Tabs/Tabs.js
Component({
/**
* 里面存放的是 要从父组件中接收的数据
*/
properties: {
// 要接受的数据的名称
aaa:{
// type 要接收的数据的类型
type:String,
//value 默认值
value:""
}
},
})
3 子组件的wxml
<view>{{aaa}}</view>
步骤 👇
- 将子组件.js中的data数据 剪切到父组件的data数据中
// pages/demo16/demo16.js
Page({
/**
* 页面的初始数据
*/
data: {
tabs:[
{
id:0,
name:"首页",
isActive:true
},
{
id:1,
name:"原创",
isActive:false
},
{
id:2,
name:"分类",
isActive:false
},
{
id:3,
name:"关于",
isActive:false
}
]
}
})
- 在父组件wxml中传递数据
<!--
1 父组件(页面)传递数据 通过 标签属性的方式来传递
1 在子组件上进行接收
-->
<Tabs tabs="{{tabs}}">
</Tabs>
- 子组件js中存放要从父组件中接收的数据
// components/Tabs/Tabs.js
Component({
/**
* 里面存放的是 要从父组件中接收的数据
*/
properties: {
tabs:{
type:Array,
value:[]
}
}
)}
- 子组件的wxml中
<view class="tabs">
<view class="tabs_title">
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="handleItemTap"
data-index="{{index}}"
>
{{item.name}}
</view>
</view>
<view class="tabs_content">内容</view>
</view>
效果是一样的
子向父传递数据
需要改造代码
- 修改子组件.js中的handleItemTap的代码
原先代码是写死的 不能修改父组件中的数据 换成触发父组件中的事件来修改数组 关键在于父组件自定义事件的名称itemChange和要传递的参数index
// components/Tabs/Tabs.js
Component({
/**
* 里面存放的是 要从父组件中接收的数据
*/
properties: {
tabs:{
type:Array,
value:[]
}
},
/**
* 组件的初始数据
*/
data: {
},
methods: {
handleItemTap(e){
/*
1 绑定点击事件 需要在methods中绑定
2 获取被点击的索引
3 点击事件触发的时候
触发父组件中的自定义事件 同时传递数据给 父组件
this.triggerEvent("父组件自定义事件的名称",要传递的参数)
*/
// 2 获取索引
const {index}=e.currentTarget.dataset;
// 3 触发父组件中的自定义事件 同时传递数据给 父组件
this.triggerEvent("itemChange",{index});
}
}
})
- 在父组件.wxml中绑定一个事件
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange">
</Tabs>
- 在父组件.js中的实现handleItemChange事件
// pages/demo16/demo16.js
Page({
/**
* 页面的初始数据
*/
data: {
tabs:[
{
id:0,
name:"首页",
isActive:true
},
{
id:1,
name:"原创",
isActive:false
},
{
id:2,
name:"分类",
isActive:false
},
{
id:3,
name:"关于",
isActive:false
}
]
},
//自定义事件 用来接收子组件传递的数据的
handleItemChange(e){
// 接收传递过来的参数
const {index}=e.detail;
//以下代码从之前子组件.js的实现代码中复制过来
let tabs=this.data.tabs;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
this.setData({
tabs
})
}
})
实现功能👇
slot
- 在子组件的wxml文件中
<view class="tabs">
<view class="tabs_title">
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="handleItemTap"
data-index="{{index}}"
>
{{item.name}}
</view>
</view>
<view class="tabs_content">
<!--
slot 标签 其实就是一个占位符 插槽
等到 父组件调用 子组件的时候 再传递 标签过来 最终 这些被传递的标签
就会替换 slot 插槽的位置
-->
<slot>
</slot>
</view>
</view>
- 对于父组件.wxml
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange">
<block wx:if="{{tabs[0].isActive}}">0</block>
<block wx:elif="{{tabs[1].isActive}}">1</block>
<block wx:elif="{{tabs[2].isActive}}">2</block>
<block wx:else="{{tabs[3].isActive}}">3</block>
</Tabs>
页面效果👇