原生小程序小话题——自定义组件1

区别于内部组件,也就是小程序自己提供的写好的部分,这一部分讲的是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,我这边有时候会报错,但我这没写错,这个小程序的原生编辑器可能会有点问题,有时候我还需要切换小程序的版本。

其余部分包括生命周期,样式隔离啊等等,后期再写吧,这篇文章写下去太多了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值