网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

微信小程序組件化的解決方案(上)

發布時間:2018-05-04 16:07 所屬欄目:小程序開發教程

從小程序基礎庫版本 1.6.3 開始,小程序支持簡潔的組件化編程。查看自己使用的小程序基礎庫版本,可以通過在開發者工具右側點擊詳情查看:

最基本的組件

小程序的組件,其實就是一個目錄,該目錄需要包含4個文件:

  1. xxx.json
  2. xxx.wxml
  3. xxx.wxss
  4. xxx.js

聲明一個組件

首先需要在 json 文件中進行自定義組件聲明(將 component 字段設為 true 可這一組文件設為自定義組件)


{
  "component": true
}

其次,在要引入組件的頁面的json文件內,進行引用聲明


{
  "usingComponents": {
    //自定義的組件名稱     : 組件路徑,注意是相對路徑,不能是絕對路徑  
    "component-tag-name": "path/to/the/custom/component"
  }
}

 

這樣,在主頁面就可以使用了。

相比于vue的組件引入,小程序的方案更簡潔。vue組件引入是需要 import 之后,同時在 components 里面注冊,而小程序的組件只需要在 .json 里面注冊,就可以在 wxml 里面使用。

使用slot

和vue 相同,小程序也有slot概念。

單一slot

在組件模板中可以提供一個 <slot> 節點,用于承載組件引用時提供的子節點。


// 主頁面內,<addlike>是組件
<addlike item="item" my_properties="sssss">
    <text>我是被slot插入的文本</text>
</addlike>
 
// addlike 組件
<view class="container">
    <view>hello, 這里是組件</view>
    <view>hello, {{my_properties}}</view>
    <slot></slot>
</view>
 
// 渲染后
<view class="container">
    <view>hello, 這里是組件</view>
    <view>hello, {{my_properties}}</view>
    <text>我是被slot插入的文本</text>
</view>

多個slot

如果需要在組件內使用多個slot, 需要在組件js中聲明啟用:


Component({
  options: {
    multipleSlots: true // 在組件定義時的選項中啟用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

使用:


// 主頁面
<addlike item="item" my_properties="sssss">
    // 在普通的元素上加入 slot 屬性,指定slotname, 就可以變成子元素的slot了
    <text slot="slot1">我是被slot1插入的文本</text>
    <text slot="slot2">我是被slot2插入的文本</text>
</addlike>
 
// 子頁面
<view class="container">
    <view>hello, 這里是組件</view>
    <view>hello, {{my_properties}}</view>
    <slot name="slot1"></slot>
    <slot name="slot2"></slot>
</view>

 

Component構造器

 剛才我們說了,一個組件內應該包括js,  wxml, wxss, json 四個文件。wxml 相當于是 HTML,wxss 相當于是 css, 那么js 里面應該寫什么呢?

微信官方提供的案例中:


Component({
 
  behaviors: [],
 
  properties: {
   
  },
  data: {}, // 私有數據,可用于模版渲染
 
  // 生命周期函數,可以為函數,或一個在methods段中定義的方法名
  attached: function(){},
  moved: function(){},
  detached: function(){},
 
  methods: {
    onMyButtonTap: function(){
     
    },
    _myPrivateMethod: function(){
     
    },
    _propertyChange: function(newVal, oldVal) {
 
    }
  }
})

里面調用了一個Component構造器。Component構造器可用于定義組件,調用Component構造器時可以指定組件的屬性、數據、方法等。具體 Component里面可以放什么東西,如下所示:

組件與數據通信

組件化必然要涉及到數據的通信,為了解決數據在組件間的維護問題,vue, react,angular 有不同的解決方案。而小程序的解決方案則簡潔很多。

主頁面傳入數據到組件

properties相當于vue的props,是傳入外部數據的入口。


// 主頁面使用組件
<a add_like="{{add_like}}">
</a>
 
// 組件a.js 內
Component({
    properties:{
        add_like:{
            type:Array,
            value:[],
            observer:function(){
                
            }
        }
    }
})

注意: 傳入的數據,不管是簡單數據類型,還是引用類型,都如同值復制一樣(和紅寶書里面描述js函數參數傳入是值復制還不一樣,紅寶書里面的意思是:簡單數據類型直接復制數值,引用類型復制引用,也就是說在函數內修改參數對象的屬性,會影響到函數外對象的屬性)。

如果是Vue的props, 則可以通過 .sync 來同步,而在小程序子組件里面,調用this.setData()修改父組件內的數據,不會影響到父組件里面的數據, 也就是說,子組件property的修改,仿佛和父組件沒有任何關系。那么,如果是在子組件內修改父組件的數據,甚至是修改兄弟組件內的數據,有沒有簡單的方法呢?下面會有講到

 

組件傳出數據到主頁面

和vue類似,組件間交互的主要形式是自定義事件。

組件通過 this.triggerEvent() 觸發自定義事件,主頁面在組件上 bind:component_method="main_page_mehod" 來接收自定義事件。

其中,this.triggerEvent() 方法接收自定義事件名稱外,還接收兩個對象,eventDetail 和 eventOptions。


// 子組件觸發自定義事件
ontap () {
    // 所有要帶到主頁面的數據,都裝在eventDetail里面
	var eventDetail = {
		name:'sssssssss',
		test:[1,2,3]
	}
	// 觸發事件的選項 bubbles是否冒泡,composed是否可穿越組件邊界,capturePhase 是否有捕獲階段
	var eventOption = {
		composed: true
	}
	this.triggerEvent('click_btn', eventDetail, eventOption)
}
 
// 主頁面里面
main_page_ontap (eventDetail) {
    console.log(eventDetail)
    // eventDetail
    // changedTouches
    // currentTarget
    // target
    // type
    // ……
    // detail   哈哈,所有的子組件的數據,都通過該參數的detail屬性暴露出來
}

組件之間數據通信

和vue提出的vuex的解決方案不同,小程序的組件間的通訊簡單小巧。你可以和主頁面與組件通訊一樣,使用自定義事件來進行通訊,當然更簡單方便的方法,是使用小程序提供的relations.

relations 是Component 構造函數中的一個屬性,只要兩個組件的relations 屬性產生關聯,他們兩個之間就可以捕獲到對方,并且可以相互訪問,修改對方的屬性,如同修改自己的屬性一樣。


Component({
   relations:{
    './path_to_b': {                 // './path_to_b'是對方組件的相對路徑
        type: 'child',               //  type可選擇兩組:parent和child、ancestor和descendant
        linked:function(target){  }  // 鉤子函數,在組件linked時候被調用 target是組件的實例,
        linkChanged: function(target){}
        unlinked: function(target){}
        }
    },
})

比如說,有兩個組件如代碼所示:


// 組件a slot 包含了組件b
<a>
    <b></b>
</a>

他們之間的關系如下圖所示:

 

兩個組件捕獲到對方組件的實例,是通過 this.getRelationNodes('./path_to_a')方法。既然獲取到了對方組件的實例,那么就可以訪問到對方組件上的data, 也可以設置對方組件上的data, 但是不能調用對方組件上的方法。

 


// 在a 組件中
Component({
    relations:{
        './path_to_b': {
            type: 'child',
            linked:function(target){  }  // target是組件b的實例,
            linkChanged: function(target){}
            unlinked: function(target){}
        }
    },
    methods:{
        test () {
            var nodes = this.getRelationNodes('./path_to_b')
            var component_b = nodes[0];
            
            // 獲取到b組件的數據
            console.log(component_b.data.name)
            
            // 設置父組件的數據
            // 這樣的設置是無效的
            this.setData({
                component_b.data.name:'ss'
            })
            // 需要調用對方組件的setData()方法來設置
            component_b.setData({
                name:'ss'
            })
        }
    }
})
 
// 在b 組件里面
Component({
    relations:{
        './path_to_a': {                      //注意!必須雙方組件都聲明relations屬性
            type:'parent'
        }
    },
    data: {
        name: 'dudu'
    }
})

 

注意:1. 主頁面使用組件的時候,不能有數字,比如說 <component_sub1> 或 <component_sub_1>,可以在主頁面的json 里面設置一個新名字


{
    "usingComponents":{
        "test_component_subb": "../../../components/test_component_sub2/test_component_sub2"
    }
}

2. relations 里面的路徑,比如說這里:

?

是對方組件真實的相對路徑,而不是組件間的邏輯路徑。

3. 如果relations 沒有關聯,那么 this.getRelationNodes 是獲取不到對方組件的

4. 本組件無法獲取本組件的實例,使用this.getRelatonsNodes('./ path_to_self ') 會返回一個null

4. type 可以選擇的 parent 、 child 、 ancestor 、 descendant 



易優小程序(企業版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/24243.html 復制鏈接 如需定制請聯系易優客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×