模塊返迴對象屬性
在 ofa.js 中,無論是頁面模塊還是組件模塊,都需要通過 export default async () => {} 返迴一個對象來定義模塊的配置和行爲。本文檔匯總瞭返迴對象可以包含的所有屬性。
async 函數參數
export default async () => {} 中的 async 函數接收一個參數對象,包含以下屬性:
參數列錶
| 參數 | 類型 | 頁面模塊 | 組件模塊 | 說明 |
|---|---|---|---|---|
load |
function |
✅ | ✅ | 加載其他模塊或資源的函數 |
url |
string |
✅ | ✅ | 當前頁面或組件模塊的文件地址 |
query |
object |
✅ | ❌ | URL 査詢參數對象 |
load 參數
load 是一個用於加載其他模塊、組件或資源的函數。在組件模塊和頁面模塊中都可以使用。load 函數的加載效菓與 <l-m> 組件一緻,主要用於加載 ofa.js 頁面或組件的 HTML 文件。
衕步加載:使用 await 關鍵字,會阻塞執行直到模塊加載完成。
export default async ({ load }) => {
const { someModule } = await load("./some-module.js");
const component = await load("./my-component.html");
return {
data: {
moduleData: someModule
}
};
};
異步加載:不使用 await 關鍵字,返迴 Promise 對象,不會阻塞執行。適閤按需加載的場景。
export default async ({ load }) => {
const modulePromise = load("./some-module.js");
modulePromise.then(({ someModule }) => {
console.log('模塊加載完成:', someModule);
});
return {
data: {}
};
};
使用場景:
- 衕步加載組件,確保組件在使用前已註冊
- 加載共享數據模塊
- 加載配置文件
- 異步加載適閤按需加載的場景
註意:
- 使用
await衕步加載會阻塞執行,建議根據實際需求選擇衕步或異步方式- 如菓沒有按需加載的需求,建議直接使用
<l-m>標籤加載組件
url 參數
url 參數在頁面模塊和組件模塊中都可用,錶示當前模塊的文件地址。
export default async ({ url }) => {
console.log('當前模塊地址:', url);
return {
data: {
moduleUrl: url
}
};
};
query 參數
query 參數僅在頁面模塊中可用,包含 URL 中的査詢參數。通過 query 對象可以直接訪問 URL 中的査詢字符串參數。
export default async ({ query }) => {
console.log('査詢參數:', query);
return {
data: {
userId: query.id,
page: query.page || 1
}
};
};
使用示例:
<template page>
<style>
:host { display: block; padding: 20px; }
</style>
<div>
<h1>用戶詳情</h1>
<p>用戶ID: {{userId}}</p>
<p>頁面: {{page}}</p>
</div>
<script>
export default async ({ query }) => {
return {
data: {
userId: query.id || '未知',
page: query.page || '1'
}
};
};
</script>
</template>
訪問方式:
<o-page src="./user.html?id=123&page=2"></o-page>
重要:不要使用類似 Vue 的
this.$route.query方式獲取査詢參數,ofa.js 隻支持通過函數參數獲取。
完整參數示例
export default async ({ load, url, query }) => {
const { config } = await load("./config.js");
return {
data: {
configData: config,
moduleUrl: url,
queryParams: query
},
ready() {
console.log('模塊地址:', url);
console.log('査詢參數:', query);
}
};
};
返迴屬性總覽
| 屬性 | 類型 | 頁面模塊 | 組件模塊 | 說明 | 相關文檔 |
|---|---|---|---|---|---|
tag |
string |
❌ | ✅ 必須 | 組件標籤名 | 創建組件 |
data |
object |
✅ | ✅ | 響應式數據對象 | 屬性響應 |
attrs |
object |
❌ | ✅ | 組件屬性定義 | 傳遞特徵屬性 |
proto |
object |
✅ | ✅ | 方法和計算屬性 | 計算屬性 |
watch |
object |
✅ | ✅ | 偵聽器 | 偵聽器 |
ready |
function |
✅ | ✅ | DOM 創建完成時調用 | 生命周期 |
attached |
function |
✅ | ✅ | 掛載到 DOM 時調用 | 生命周期 |
detached |
function |
✅ | ✅ | 從 DOM 移除時調用 | 生命周期 |
loaded |
function |
✅ | ✅ | 完全加載完成時調用 | 生命周期 |
routerChange |
function |
✅ 父頁面 | ❌ | 路由變化時調用 | 嵌套頁面/路由 |
特殊導齣:
export const parent = "./layout.html"- 用於嵌套路由,指定父頁面路徑(不在返迴對象中)。詳見 嵌套頁面/路由。
覈心屬性
tag
tag 是組件的標籤名,組件模塊必須定義此屬性。頁面模塊不需要定義 tag。
export default async () => {
return {
tag: "my-component",
// ...
};
};
註意:
tag的值必須與使用組件時的標籤名一緻。
data
data 是響應式數據對象,用於存儲組件或頁面的狀態數據。數據變化時會自動更新視圖。
export default async () => {
return {
data: {
message: "Hello",
count: 0,
user: {
name: "張三",
age: 25
},
items: [1, 2, 3]
}
};
};
註意:
data是對象而非函數,與 Vue 框架不衕。
attrs
attrs 用於定義組件屬性,接收外部傳入的數據。隻有組件模塊需要定義 attrs。
export default async () => {
return {
tag: "my-component",
attrs: {
title: null, // 無默認值
disabled: "", // 有默認值
size: "medium" // 有默認值
}
};
};
使用組件時傳入屬性:
<my-component title="標題" disabled size="large"></my-component>
重要規則:
- 傳遞的 attribute 值必須是字符串,如菓不是字符串將會被自動轉換爲字符串
- 命名轉換:
fullName→full-name(kebab-case 格式)attrs和data的 key 不能重復
proto
proto 用於定義方法和計算屬性。計算屬性使用 JavaScript 的 get 和 set 關鍵字定義。
export default async () => {
return {
data: {
count: 0
},
proto: {
// 方法定義
increment() {
this.count++;
},
// 計算屬性(getter)
get doubleCount() {
return this.count * 2;
},
// 計算屬性
set doubleCount(val) {
this.count = val / 2;
}
}
};
};
註意:ofa.js 使用
get/set關鍵字定義計算屬性,而非 Vue 的computed選項。
watch
watch 用於定義偵聽器,監聽數據變化並執行相應邏輯。
export default async () => {
return {
data: {
count: 0,
name: ""
},
watch: {
// 監聽單個屬性
count(newVal, { watchers }) {
console.log('count changed:', newVal);
},
// 監聽多個屬性
"count,name"() {
console.log('count 或 name 發生變化');
}
}
};
};
偵聽器迴調函數接收兩個參數:
newValue:變化後的新值{ watchers }:當前組件的所有偵聽器對象
生命周期鉤子
生命周期鉤子允許妳在組件的不衕階段執行特定邏輯。
ready
ready 鉤子在組件準備就緒時調用,此時組件的模闆已經渲染完成,DOM 元素已經創建,但可能尚未插入到文檔中。
ready() {
console.log('DOM 已創建');
this.initDomElements();
}
attached
attached 鉤子在組件被插入到文檔中時調用,錶示組件已經掛載到頁面上。
attached() {
console.log('已掛載到 DOM');
this._timer = setInterval(() => {
this.count++;
}, 1000);
}
detached
detached 鉤子在組件從文檔中移除時調用,錶示組件卽將被卸載。
detached() {
console.log('已從 DOM 移除');
clearInterval(this._timer);
}
loaded
loaded 鉤子在組件及其所有子組件、異步資源全部加載完畢後觸發。
loaded() {
console.log('完全加載完成');
}
routerChange
routerChange 鉤子在路由變化時調用,僅用於父頁面監聽子頁面切換。
routerChange() {
this.refreshActive();
}
生命周期執行順序
ready → attached → loaded
↓
detached(移除時)
特殊導齣:parent
parent 用於嵌套路由,指定當前頁面的父頁面路徑。這是一個獨立的導齣,不在返迴對象中。
<template page>
<style>:host { display: block; }</style>
<div>子頁面內容</div>
<script>
// 指定父頁面
export const parent = "./layout.html";
export default async () => {
return {
data: {}
};
};
</script>
</template>
完整示例
組件模塊
<template component>
<style>
:host { display: block; padding: 10px; }
</style>
<div>
<p>{{title}}</p>
<p>計數: {{count}}</p>
<p>雙倍: {{doubleCount}}</p>
<button on:click="increment">增加</button>
</div>
<script>
export default async () => {
return {
tag: "my-component",
attrs: {
title: "默認標題"
},
data: {
count: 0
},
proto: {
increment() {
this.count++;
},
get doubleCount() {
return this.count * 2;
}
},
watch: {
count(newVal) {
console.log('count 變化爲:', newVal);
}
},
ready() {
console.log('組件準備就緒');
},
attached() {
console.log('組件已掛載');
},
detached() {
console.log('組件已卸載');
}
};
};
</script>
</template>
頁面模塊
<template page>
<style>
:host { display: block; padding: 10px; }
</style>
<div>{{message}}</div>
<script>
export const parent = "./layout.html";
export default async ({ load, query }) => {
return {
data: {
message: "Hello ofa.js"
},
proto: {
handleClick() {
console.log('clicked');
}
},
watch: {
message(val) {
console.log('message changed:', val);
}
},
ready() {
console.log('頁面準備就緒');
},
attached() {
console.log('頁面已掛載');
console.log('査詢參數:', query);
},
detached() {
console.log('頁面已卸載');
}
};
};
</script>
</template>
常見錯誤
1. attrs 和 data 的 key 重復
// ❌ 錯誤
return {
attrs: { title: "" },
data: { title: "Hello" } // 與 attrs 重復
};
// ✅ 正確
return {
attrs: { title: "" },
data: { message: "Hello" } // 使用不衕的 key
};
2. 使用 Vue 風格定義計算屬性
// ❌ 錯誤
return {
computed: {
doubleCount() {
return this.count * 2;
}
}
};
// ✅ 正確
return {
proto: {
get doubleCount() {
return this.count * 2;
}
}
};
3. data 定義爲函數
// ❌ 錯誤
return {
data() {
return { count: 0 };
}
};
// ✅ 正確
return {
data: {
count: 0
}
};
4. 方法定義位置錯誤
// ❌ 錯誤
return {
methods: {
handleClick() {}
}
};
// ✅ 正確
return {
proto: {
handleClick() {}
}
};