区别于内部组件,也就是小程序自己提供的写好的部分,这一部分讲的是componnet,也就是通常前端所说的组件
第一部分 组件的创建
前面我们讲了和wxss,wxs,wxml有关的模板,那么这个组件就是三个部分的大整合,准确的说他和一般的page是一样的,也是下图这个结构
当然还是有快捷的方式去创建,就是右键的方式,会创建同名的四个文件
创建之初,一般要在相应的json文件中加上如下的字段
{
"component": true
}
当然现在会主动帮你创建好
第二部分 自定义组件和普通页面的一些区别
wxml和wxss基本上没有区别,最主要的区别在于js部分,我们看一下js部分的结构
(后期补充了一下,组件的wxss只能使用类的形式,这点要注意)
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
和page对象不同,组件是放在Component对象职中的,本身组件是要接受参数的,所以这边有一个properties的属性,data就是自身的一些状态,methods就是方法的集合了。看上去也不是很难。
第三部分 一个简单的组件案例
我们要创建一个包含其他组件的组件,并将最终的组件挂载到页面上
首先是嵌套组件中的子组件
<view class="container">
<view class="tip">我是组件一当中包含的组件二</view>
<view>你应该会看到我的名字:{{userName}}</view>
</view>
//js部分,这里我们主要看一下prop部分
properties: {
userName:{
type:String,
value:"默认用户"
}
// 这里的value应该是一个默认值
},
很明显在wxml当中包含的变量userName就是参数传入的
然后是嵌套组件的父组件,首先要在父组件的json部分对子组件进行注册
{
"component": true,
"usingComponents": {
"com-test2":"/components/com-test2/com-test2"}
}
然后在父组件之中插入
<view class="container">
<view class="tip">我是包含组件二的组件一</view>
<view>这是参数中传入的用户年龄:{{props.userAge}}</view>
<com-test2 user-name="{{props.userName}}"></com-test2>
</view>
//父组件的js部分
properties: {
props:{
type:Object
}
},
需要一个props的参数
把这个嵌套组件在page上挂载,当然挂载之前还是要在json里注册
<view class="container">
<view class="title">欢迎来到page3</view>
<view class="tip">测试自定义组件</view>
<com-test1 props="{{props}}"></com-test1>
</view>
//js
data: {
props:{
userName:"gss",
userAge:1000
}
},
把这个内部参数传给子组件
看上去可能有点复杂,有以下的点需要注意
1.默认app.wxss的样式影响不到组件内的样式
2.组件可以在要挂载的页面上注册,也可以在app.js里面进行全局注册,这样的话可以直接引用
第四部分 组件的通信和事件
这个和vue当中有点相似,这里重点的应该是子向父的通信
我们在这里的son组件内部绑定一个函数,使用triggerEvent的方式调用父级的函数,同时我们还要带上一个参数
<!--components/son/son.wxml-->
<view>这是son组件</view>
<button type="primary" bindtap="handleson" >点击触发自定义事件</button>
js部分
methods: {
handleson(event){
console.log("son向父亲求救");
this.triggerEvent("myevent",{name:"haufheng"},{})
// 三个参数,第二个参数是事件处理参数,第三个是冒泡之类的选项
}
}
看一下父组件部分
<son bind:myevent="onmyevent" />
js部分
onmyevent(event){
console.log(event.detail.name);
// 拿到了那边传过来的参数
console.log("为父帮助了孩儿");
},
原生事件传入的参数是放在event的detail部分
第五部分 在组件中使用插槽slot
这一部分跟vue还是十分相似的。
这里说一下多个插槽的写法,首先需要在当前的组件的js部分写下配置内容
Component({
options: {
multipleSlots: true // 在组件定义时的选项中启用多 slot 支持
},
properties: { /* ... */ },
methods: { /* ... */ }
})
然后可以使用name的标签对插槽进行区分
<view>
<view>我是slot-test组件</view>
<view class="father">
<slot name="father"></slot>
</view>
<view class="son">
<slot name="son"></slot>
</view>
</view>
最后在主页面上引入
<slot-test>
<view slot="father">父亲大人</view>
<view slot="son">儿子</view>
</slot-test>
我这个组件就叫slot-test
实际上和vue差不多
第六部分 behaviour
翻译过来叫行为,实际上官网都说了这个就是mixin,共享一些重复的组件的js部分的内容,有这玩意,谁愿意多写代码啊,我们来看一下他的结构
module.exports = Behavior({
behaviors: [],
properties: {
myBehaviorProperty: {
type: String
}
},
data: {
myBehaviorData: {}
},
attached: function(){},
methods: {
myBehaviorMethod: function(){}
}
})
看来是一个大对象,其中也有behaviors的选项,也就是说这玩意也是可以嵌套的,hhh
下面写一个例子测试嵌套和覆盖规则
首先是被嵌套的behavior2
module.exports=Behavior({
data:{
gf:"none"
}
})
还是一个模块化的写法,在大对象中定义了一个data数据,下面我们要将这个behavior2融合到behavior1中,看一下behavior1的文件
var behavior2=require("./behavior2")
module.exports=Behavior({
behaviors:[behavior2],
properties:{
myname:String
},
data:{
name:"黄烽",
age:18
},
methods:{
saysth(){
console.log("我是behavior1");
},
// 因为有behavior-test当中有同名属性,所以这个函数被覆盖了
dosth(){
console.log("我是behavior1模块的dosth,",`${this.data.gf}:${this.data.name},你真是个${this.data.myname}`);
// 实际上这个properties当中的属性一旦上传是会放到data中的
}
}
})
这里开头有一个require的引入,并且定义了其他的需要融合的属性,下面把behavior1和组件融合
// components/behavior-test/behavior-test.js
var behavior1=require("../../behavior/")
Component({
behaviors:[behavior1],
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
saysth(){
console.log("我是组件原来的数据");
}
}
})
我们这边特地给了一个同名的saysth函数,这样的话就可以测试同名属性的操作(实际上无论啥mixin之类的,都会保留原生的同名属性),看一下我们组件的页面结构
<view>
<view>我是behaviour-test组件</view>
<button type="primary" bindtap="saysth">点击触发saysth</button>
<button type="primary" bindtap="dosth">点击触发saysth</button>
</view>
挂载到组件之后依次点击按钮试试看
组件部分的内容真是太多了,写前端其实万变不离其宗,你学的越多,站得越高,对现阶段前端的理解也就越全面,这就是一个学习的过程,相对应的,前端一定要去学习后端,否则是不能完整地理解项目。
by the way,我这边有时候会报错,但我这没写错,这个小程序的原生编辑器可能会有点问题,有时候我还需要切换小程序的版本。
其余部分包括生命周期,样式隔离啊等等,后期再写吧,这篇文章写下去太多了