在 UniApp 開發中,我們經常需要通過?uni.request
?獲取服務器返回的 JSON 數據,并將其綁定到頁面或進行邏輯處理。
但在?UniApp X(基于 UTS)?中,由于引入了?強類型語言特性,處理 JSON 數據的方式與 JS 有明顯不同。如果你還停留在 JS 的開發習慣中,很容易踩坑。
本文將帶你從 JS 的 JSON 處理方式出發,逐步過渡到 UTS 的兩種主流處理方式:
- ??UTSJSONObject:兼容 JS 的靈活方式
- ??type + 泛型:強類型推薦方案
🧩 一、JS 中的 JSON 處理方式(回顧)
在 JS 中,uni.request
?獲取的 JSON 數據可以直接使用?.屬性名
?的方式訪問:
uni.request({url: "https://example.com/api",success: (res) => {console.log(res.data.data[0].plugin_name);}
});
但這種方式在?UTS 中會報錯,因為:
UTS 是強類型語言,res.data 是 any 類型,不能安全訪問未定義的屬性。
🛠? 二、UTS 中處理 JSON 的兩種方式
方式一:UTSJSONObject(兼容 JS 的靈活方式)
1. 基本用法:通過下標訪問屬性
uni.request({url: "https://example.com/api",success: (res) => {const data = res.data as UTSJSONObject;const pluginName = (data["data"] as UTSJSONObject[])[0]["plugin_name"];console.log(pluginName);}
});
2. 使用 keypath 訪問深層屬性(推薦)
UTSJSONObject 支持 keypath 寫法,穿透訪問嵌套屬性:
const pluginName = data.getString("data[0].plugin_name");
console.log(pluginName); // 輸出:插件名稱A
3. 其他 keypath 方法
方法名 | 返回類型 | 說明 |
---|---|---|
getString(path: string) | string | 獲取字符串 |
getNumber(path: string) | number | 獲取數字 |
getBoolean(path: string) | boolean | 獲取布爾值 |
getJSON(path: string) | UTSJSONObject | 獲取對象 |
getArray(path: string) | UTSJSONObject[] | 獲取數組 |
getAny(path: string) | any | 獲取任意類型 |
???缺點:沒有類型提示、需要手動處理類型轉換、性能略差。
方式二:type + 泛型(強類型推薦方式)
1. 定義數據類型(使用 HBuilderX 自動生成)
將服務器返回的 JSON 數據粘貼到 HBuilderX 的 JSON 編輯器中,右鍵選擇?“轉 type”,自動生成類型定義。
例如服務器返回如下數據:
{"code": 200,"desc": "","data": [{"plugin_id": 123,"plugin_name": "插件名稱A"}]
}
生成的類型為:
type Data = {plugin_id: number;plugin_name: string;
};type IRootType = {code: number;desc: string;data: Data[];
};
2. 使用泛型調用?uni.request
uni.request<IRootType>({url: "https://example.com/api",success: (res) => {if (res.data && res.data.data.length > 0) {console.log(res.data.data[0].plugin_name); // 直接使用 . 操作符}}
});
3. 泛型寫法說明
- ??泛型寫法:
uni.request<IRootType>(...)
,告訴編譯器期望返回的數據類型。 - ??數組類型:如果?
res.data
?是數組,應寫為?uni.request<IRootType[]>(...)
- ??安全訪問:使用?
?.
?防止空值訪問錯誤,如?res.data?.data
🧠 三、type 與泛型的常見問題
1. type 要寫在?export default
?之前
為了在?data()
?或?computed
?中使用類型定義,必須把?type
?寫在?export default
?之前:
type Data = {plugin_id: number;plugin_name: string;
};export default {data() {return {dataList: [] as Data[]};}
};
2. 屬性可能缺失怎么辦?
使用??
?表示該屬性可為空:
type Data = {plugin_id: number;plugin_name?: string; // plugin_name 可能不存在age: number | null; // age 可為 null
};
3. 泛型支持情況
- ? 當前版本支持傳入?
type
?作為泛型 - ? 不支持動態泛型,如將泛型作為函數參數傳遞
- ? Web 端目前僅支持類型校驗,不支持實例化
📦 四、實戰案例:網絡請求 + 數據綁定 + 分頁加載
<template><list-view style="flex: 1;" @scrolltolower="loadData"><template v-for="(item, index) in dataList" :key="index"><list-item style="flex-direction: row; padding: 10px;"><text>{{ item.plugin_name }}</text></list-item></template><list-item v-if="loadingText"><text>{{ loadingText }}</text></list-item></list-view>
</template><script lang="uts">type Plugin = {plugin_id: number;plugin_name: string;};type ResponseType = {code: number;desc: string;data: Plugin[];};export default {data() {return {dataList: [] as Plugin[],loading: false,isEnded: false,currentPage: 1};},computed: {loadingText(): string {if (this.loading) return "加載中...";if (this.isEnded) return "沒有更多了";return "";}},onLoad() {this.loadData();},methods: {loadData() {if (this.loading || this.isEnded) return;this.loading = true;uni.request<ResponseType>({url: "https://example.com/api",data: {page: this.currentPage,pageSize: 10},success: (res) => {if (res.data?.data?.length) {this.dataList.push(...res.data.data);this.currentPage++;} else {this.isEnded = true;}},fail: (err) => {console.error("加載失敗", err);},complete: () => {this.loading = false;}});}}};
</script>
🧪 五、UTS JSON 處理對比表
特性 | UTSJSONObject | type + 泛型 |
---|---|---|
類型提示 | ? 無 | ? 有 |
代碼可讀性 | ?? 略差 | ? 好 |
類型安全 | ? 弱 | ? 強 |
性能表現 | ?? 略差 | ? 好 |
使用難度 | ? 簡單 | ?? 稍復雜 |
適用人群 | 初學者 | 有 TS 經驗者 |
推薦指數 | ??? | ????? |
📌 六、注意事項
- ??
UTSJSONObject
?適用于鍵名動態或結構不穩定的數據 - ??
type + 泛型
?更適合結構固定、追求類型安全和代碼提示的項目 - ???
type
?中屬性名不能包含特殊字符如?:
、-
,否則需手動處理或改用?UTSJSONObject
- ?? 泛型不支持動態傳參,封裝?
request
?時建議使用?UTSJSONObject
🧠 最后一句話送大家:
“從 JS 到 UTS,不是語法的改變,而是對數據結構理解的升華。”
掌握好 JSON 數據的處理方式,你就能在 UniApp X 的世界里,寫出更穩定、更高效、更跨平臺的應用!
如果你覺得這篇文章對你有幫助,歡迎點贊、收藏、轉發給還在為 UTS JSON 問題發愁的小伙伴!