文章目录
小程序 template的使用 VS 小程序自定义组件:
Component
Component允许有自己的方法和属性,它包括wxml,wxss,js,json文件
注意:在自定义组件中(如mask组件)用id选择器会报错:
VM2696:1 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.
//mask.wxss
#iii{
width: 800rpx;
height: 800rpx;
background-color: #f0f;
}
准备工作:
在pages同级目录下创建components目录,然后创建mask目录,右键,新建components
父组件向子组件传参:
father.json: 小程序Json文件中不能写注释,必须用双引号,不能用单引号
{
"usingComponents": {
"maskComponent": "../../components/mask/mask"
}
}
father.wxml:
<!--name的值为json配置文件中usingComponents的键值 -->
<!--使用maskComponent组件(对应的JSON中写的什么就什么),
父传子:父组件中传递一个在data中定义的参数/值,子组件js的properties中映射,然后在wxml中引用.
给子组件传递paramParentToChild参数,值为变量dadToSon的值
-->
<maskComponent paramParentToChild="{{dadToSon}}"></maskComponent>
father.js:
data: {
dadToSon:"这是爸爸给儿子传的值",
}
components/mask/mask.wxml
<text>components/mask/mask.wxml</text>
<view class="box" bindtap="haha"></view>
<view>
父组件给子组件传值: {{paramParentToChild}} //接受父组件穿过来的参数
</view>
<view class="iii"></view>
components/mask/mask.wxss
.box{
width: 100rpx;
height: 100rpx;
background: yellow;
}
.iii{
width: 800rpx;
height: 800rpx;
background-color: #f0f;
}
// components/mask/mask.js
Component({
/**
* 组件的属性列表
*/
// vue里面叫props,对应父组件传过来的参数,是组件的对外属性的映射
// type属性类型,value属性值,observer属性值被更改是的响应函数
properties: {
paramParentToChild: {
type: String,//类型
value: 'default value'//默认值
}
},
/**
* 组件的初始数据,组建内部数据定义在这里,和properties中的属性一同渲染组件
*/
data: {
},
/**
* 组件的方法列表
*/
// 子组件的方法需要写在methods:{}里面
methods: {
//haha是子组件中的一个普通的方法
haha: function(){
console.log("I'm a component,哈哈哈哈哈哈哈哈")
}
}
})
mask.json
{
"component": true,
"usingComponents": {}
}
子组件向父组件传参:
father.wxml
<!--
子组件向父组件传递数据主要通过监听事件, 比如like点赞功能触发了一个like事件
父组件通过绑定like事件来监听
在组件引用的时候,绑定一个子组件中的事件名字onMyEvent,这个事件要在父组件的JS中也要定义,
可以名字不同,但是要对应.子组件触发该事件,然后向父组件传值
-->
<maskComponent bind:myevent="onMyEvent"></maskComponent>
<view class="bb" hover-class="none" hover-stop-propagation="false">
子组件传给父组件的参数值: {{paramChildToParentaaa}}
</view>
father.js
data: {
paramChildToParentaaa: 'default value' //设置初始值,非必须,可以不设,下面方法中直接更新
},
onMyEvent: function (e) {
console.log(e)
//通过事件接收
this.setData({
paramChildToParentaaa: e.detail.paramChildToParent //从e.detail中获取子组件传过来的值并更新初始值
})
},
father.json:
{
"usingComponents": {
"maskComponent": "../../components/mask/mask"
}
}
子组件中定义按钮用于触发事件函数
<!--components/mask/mask.wxml-->
<button bindtap='change'>向父组件中传入参数</button>
// mask.js
/**
* 组件的方法列表
*/
// 子组件的方法需要写在methods:{}里面
methods: {
//触发change事件向父组件传值
change: function () {
// 父组件引用子组件时的方法名 bind:myevent="onMyEvent",传的参数对象
this.triggerEvent('myevent', { paramChildToParent: "666传值成功" });
}
}
JSON文件内容同”父组件向子组件传参”
兄弟组件传参:
再创建一个article组件
father.json
{
"usingComponents": {
"maskComponent": "../../components/mask/mask",
"articleComponent": "../../components/article/article"
}
}
father.wxml
<!-- 兄弟组件传参:流程:子组件article -> 父组件(中转站) -> 子组件mask -->
<maskComponent aParamFromBrother="{{toBrother}}"></maskComponent>
<articleComponent bind:getParam="onGetParam"></articleComponent>
father.js
/**
* 页面的初始数据
*/
data: {
toBrother: 0
},
onGetParam: function(e) {
this.setData({
toBrother: e.detail.paramFromBrother
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
article.wxml
<!--components/article/article.wxml-->
<button bindtap="wakeUp">点击给父组件传参数,然后传给我兄弟</button>
article.js
methods: {
wakeUp: function () {
this.triggerEvent('getParam', { paramFromBrother: 666 });
}
}
article.json不变
<!--components/mask/mask.wxml-->
<view>
从我兄弟中拿到的数据是(其实是爸爸给的): {{aParamFromBrother}}
</view>
mask.js
properties: {
aParamFromBrother: {
type: Number,//类型
value: 'default value'//默认值
}
},
mask.json不变
点击按钮:
另一种引用子组件以及获取组件内属性/方法的方式: selectComponent
father.wxml
<maskComponent id="maska"></maskComponent>
father.js
onLoad: function (options) {
// 父组件直接拿子组件数据(不需要触发事件)
let comp = this.selectComponent('#maska') //也可以传递 .className,但不能传组件的标签选择器,否则null
console.log(comp);
// 调用父组件中的haha方法
console.log(comp.haha());
},
mask.wxml
<text id="ooo">
这是mask中的text组件,用来测试selectComponent的
</text>
mask.js
控制台:
Template
template中只有 wxml和wxss文件,支持独立的样式,但没有自己的方法,是静态的,动态数据必须由引用它;
template,在引用的时候需要在引用页面对应的.wxml和.wxss文件中导入
father.wxml
<!-- 声明需要使用的模板文件 -->
<import src ="../template/mask/mask.wxml"/>
<!--
(1)father.wxml中template 标签的is属性与template.wxml中template 标签的name属性值相同
(2)father.wxml文件中要通过import标签声明需要使用的模板文件
-->
<!--
在<data="{{'这是一个参数'}}">中传多少个参数,对应的template里就能获取多少个参数,
传参的时候要逗号隔开即可,而且传的必须是一个对象
如:<data="{{obj}}"> 或 <data="{{...obj}}"> 注:第一种写法在template中引用的时候要写成 {{obj.参数名}};
第二种写法直接写成 {{参数名}}
-->
<template is="mask" data="{{...aaaaa}}"></template>
father.wxss
/**导入模板样式**/
@import "../template/mask/mask.wxss";
/**......**/
father.js
data: {
aaaaa: { firstName: Alice, lastName: 'Hu' }
}
alerthello(e){
console.log('hello!',e);
},
/pages/template/mask/mask.wxml
<!--
一个模板文件中可定义多个template,每个template以name属性进行区分,
在父页面调用的时候is属性对应template的name属性;
-->
<template name="mask">
<view class="mask">
<view class="popUp">
<!--
当需要为template中的元素绑定事件函数时,直接用bindtap绑定父页面js文件中定义的方法即可;
数据也是直接引用;
小程序中事件处理函数的参数就是event,不能传入其他参数...有时候时间函数中需要用到自定义数据,如 循环中对应 的index等(data-index="{{index}}"),以 data-*的形式定义即,取值方 式:e.currentTarget.dataset.abc;
-->
<text class="info" bindtap="alerthello" data-abc="abc">这是template中的内容:点我有惊喜哦,{{firstName}},ooo</text>
</view>
</view>
</template>
/pages/template/mask/mask.wxss
.mask{
width: 100%;
height: 100%;
/*absolute与fixed,滚动滚动条,元素的位置是否会随着改变 */
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99;
color: #ffffff;
}
.popUp{
position: absolute;
top: 10%;
left: 19%;
width: 460rpx;
height: 200rpx;
background: red;
}