From 3f51efcebe16a5a4e6ffe98e4eaa5f2479765bad Mon Sep 17 00:00:00 2001 From: Ankkaya Date: Tue, 11 Jun 2024 18:33:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=95=86=E5=93=81sku)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manifest.json | 75 +- pages/index/product.vue | 283 ++++--- pages/index/redirect.vue | 7 +- pages/product/components/item.vue | 166 ++-- pages/product/js/config.js | 24 + pages/product/js/sku.js | 352 +++++--- pages/product/manageGoods.vue | 785 ++++++++++-------- pages/product/sku.vue | 220 ++--- peach/api/trade/goods.js | 6 +- .../p-goods-column/p-goods-column.vue | 369 ++++---- peach/components/p-picker/p-picker.vue | 212 ++--- uni_modules/piaoyi-editor/changelog.md | 10 + .../components/piaoyi-editor/color-picker.vue | 784 +++++++++++++++++ .../components/piaoyi-editor/iconfont.css | 123 +++ .../components/piaoyi-editor/iconfont.ttf | Bin 0 -> 6564 bytes .../components/piaoyi-editor/iconfont.woff | Bin 0 -> 4076 bytes .../components/piaoyi-editor/iconfont.woff2 | Bin 0 -> 3296 bytes .../piaoyi-editor/piaoyi-editor.vue | 516 ++++++++++++ uni_modules/piaoyi-editor/package.json | 15 + uni_modules/piaoyi-editor/readme.md | 101 +++ 20 files changed, 2988 insertions(+), 1060 deletions(-) create mode 100644 uni_modules/piaoyi-editor/changelog.md create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/color-picker.vue create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.css create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.ttf create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.woff create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.woff2 create mode 100644 uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue create mode 100644 uni_modules/piaoyi-editor/package.json create mode 100644 uni_modules/piaoyi-editor/readme.md diff --git a/manifest.json b/manifest.json index e3e30b9..c76963d 100644 --- a/manifest.json +++ b/manifest.json @@ -1,28 +1,31 @@ { - "name" : "mall-app-t", - "appid" : "__UNI__B201544", - "description" : "", - "versionName" : "1.0.0", - "versionCode" : "100", - "transformPx" : false, + "name": "mall-app-t", + "appid": "__UNI__B201544", + "description": "", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx": false, /* 5+App特有相关 */ - "app-plus" : { - "usingComponents" : true, - "nvueStyleCompiler" : "uni-app", - "compilerVersion" : 3, - "splashscreen" : { - "alwaysShowBeforeRender" : true, - "waiting" : true, - "autoclose" : true, - "delay" : 0 + "app-plus": { + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + "compatible": { + "ignoreVersion": true }, /* 模块配置 */ - "modules" : {}, + "modules": {}, /* 应用发布信息 */ - "distribute" : { + "distribute": { /* android打包配置 */ - "android" : { - "permissions" : [ + "android": { + "permissions": [ "", "", "", @@ -41,32 +44,32 @@ ] }, /* ios打包配置 */ - "ios" : {}, + "ios": {}, /* SDK配置 */ - "sdkConfigs" : {} + "sdkConfigs": {} } }, /* 快应用特有相关 */ - "quickapp" : {}, + "quickapp": {}, /* 小程序特有相关 */ - "mp-weixin" : { - "appid" : "wx64387dc8bba916ec", - "setting" : { - "urlCheck" : false + "mp-weixin": { + "appid": "wx64387dc8bba916ec", + "setting": { + "urlCheck": false }, - "usingComponents" : true + "usingComponents": true }, - "mp-alipay" : { - "usingComponents" : true + "mp-alipay": { + "usingComponents": true }, - "mp-baidu" : { - "usingComponents" : true + "mp-baidu": { + "usingComponents": true }, - "mp-toutiao" : { - "usingComponents" : true + "mp-toutiao": { + "usingComponents": true }, - "uniStatistics" : { - "enable" : false + "uniStatistics": { + "enable": false }, - "vueVersion" : "3" + "vueVersion": "3" } diff --git a/pages/index/product.vue b/pages/index/product.vue index 670eaa5..65ac93c 100644 --- a/pages/index/product.vue +++ b/pages/index/product.vue @@ -1,21 +1,43 @@ diff --git a/pages/index/redirect.vue b/pages/index/redirect.vue index cafbb83..b1157ac 100644 --- a/pages/index/redirect.vue +++ b/pages/index/redirect.vue @@ -1,15 +1,14 @@ diff --git a/pages/product/js/config.js b/pages/product/js/config.js index 3b99d36..f9b7475 100644 --- a/pages/product/js/config.js +++ b/pages/product/js/config.js @@ -8,3 +8,27 @@ export const SPEC_TYPE = [ value: true, }, ] + +// sku 相关属性校验 +export const SKU_RULE_CONFIG = [ + { + name: 'stock', + rule: (arg) => arg >= 0, + message: '商品库存必须大于等于 1 !!!', + }, + { + name: 'price', + rule: (arg) => arg >= 0.01, + message: '商品销售价格必须大于等于 0.01 元!!!', + }, + { + name: 'marketPrice', + rule: (arg) => arg >= 0.01, + message: '商品市场价格必须大于等于 0.01 元!!!', + }, + { + name: 'costPrice', + rule: (arg) => arg >= 0.01, + message: '商品成本价格必须大于等于 0.00 元!!!', + }, +] diff --git a/pages/product/js/sku.js b/pages/product/js/sku.js index 195cbdc..9560202 100644 --- a/pages/product/js/sku.js +++ b/pages/product/js/sku.js @@ -1,179 +1,277 @@ -import { ref, computed } from "vue"; -import { onLoad } from "@dcloudio/uni-app"; -import peach from "@/peach"; -import GoodsApi from "@/peach/api/trade/goods"; -import { SPEC_TYPE } from "./config"; +import { ref, computed } from 'vue' +import { onLoad } from '@dcloudio/uni-app' +import peach from '@/peach' +import GoodsApi from '@/peach/api/trade/goods' +import { SPEC_TYPE, SKU_RULE_CONFIG } from './config' -const pickerRef = ref(null); +const pickerRef = ref(null) // 多属性商品 sku 列表 -const skus = ref([]); +const skus = ref([]) -const propertyList = ref([]); +const propertyList = ref([]) -const goodsPropertyList = ref([]); +const goodsPropertyList = ref([]) -const propertyListRef = ref(null); +const propertyListRef = ref(null) -const canEdit = computed(() => peach.$store("trade").canEdit); +const canEdit = computed(() => peach.$store('trade').canEdit) const formData = ref({ - specType: true, - specText: SPEC_TYPE[0].label, -}); + specType: true, + specText: SPEC_TYPE[0].label, +}) async function showPropertyList() { - await getGoodsProperty(); - propertyListRef.value.onOpen(); + await getGoodsProperty() + propertyListRef.value.onOpen() } function onRDPickerConfirm(e) { - peach.$store("trade").specType = SPEC_TYPE[e.value[0]].value; - formData.value.specText = SPEC_TYPE[e.value[0]].label; - formData.value.specType = SPEC_TYPE[e.value[0]].value; + formData.value.specType = SPEC_TYPE[e.value[0]].value + formData.value.specText = SPEC_TYPE[e.value[0]].label + + // 如果商品规格不一致,则需要重新初始化 sku 列表 + initSku() + + peach.$store('trade').specType = SPEC_TYPE[e.value[0]].value } function pickerProperty() { - if (canEdit.value) { - let index = specType.value ? 1 : 0; - pickerRef.value.onOpen([index]); - } + if (canEdit.value) { + let index = formData.value.specType ? 1 : 0 + + console.log(index) + + pickerRef.value.onOpen([index]) + } } async function onPropertyConfirm(e) { - await getGoodsProperty(); - console.log(e); + await getGoodsProperty() + console.log(e) } function onConfirm() { - console.log(skus.value); + console.log(skus.value) } async function getGoodsProperty() { - let { data } = await GoodsApi.getHistoryProperty(); + let { data } = await GoodsApi.getHistoryProperty() - // 把 propertyList 中 id 相同的属性合并,并去重 - propertyList.value = peach.$store("trade").selectedProperty; + // 把 propertyList 中 id 相同的属性合并,并去重 + propertyList.value = peach.$store('trade').selectedProperty - console.log(propertyList.value); + console.log(propertyList.value) - // 根据已经选择数据,设置默认选中 - data.forEach((item) => { - // 判断属性是否已经选中 - let propertyParent = propertyList.value.find( - (sitem) => sitem?.id === item.id - ); + // 根据已经选择数据,设置默认选中 + data.forEach((item) => { + // 判断属性是否已经选中 + let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id) - item.checked = propertyParent ? true : false; + item.checked = propertyParent ? true : false - // 如果属性已经选中,查询子类中是否有选中 - if (item.checked) { - item.propertyValues.forEach((child) => { - let childResult = propertyParent?.children.some( - (schild) => schild === child.id - ); - child.checked = childResult ? true : false; - }); - } - }); + // 如果属性已经选中,查询子类中是否有选中 + if (item.checked) { + item.propertyValues.forEach((child) => { + let childResult = propertyParent?.children.some((schild) => schild === child.id) + child.checked = childResult ? true : false + }) + } + }) - goodsPropertyList.value = data; - console.log(goodsPropertyList.value); + goodsPropertyList.value = data + console.log(goodsPropertyList.value) } function changeSubProperty() { - // 修改子属性状态,需要同步更新 skus 的显示 - console.log(goodsPropertyList.value); - // 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容 - let temp = JSON.parse( - JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)) - ); - temp.forEach((item) => { - item.propertyValues = item.propertyValues.filter((child) => child.checked); - }); + // 修改子属性状态,需要同步更新 skus 的显示 + console.log(goodsPropertyList.value) + // 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容 + let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))) + temp.forEach((item) => { + item.propertyValues = item.propertyValues.filter((child) => child.checked) + }) - let result = temp.map((item) => { - return item.propertyValues.map((child) => ({ - propertyId: item.id, - propertyName: item.name, - valueId: child.id, - valueName: child.name, - })); - }); + let result = temp.map((item) => { + return item.propertyValues.map((child) => ({ + propertyId: item.id, + propertyName: item.name, + valueId: child.id, + valueName: child.name, + })) + }) - let tempSkus = []; + let tempSkus = [] - for (let item of reduceArr(result)) { - let obj = { - picUrl: "", - barCode: "", - price: 0, - marketPrice: 0, - costPrice: 0, - stock: 0, - weight: 0, - volume: 0, - properties: item, - }; - tempSkus.push(obj); - } + for (let item of reduceArr(result)) { + let obj = { + picUrl: '', + barCode: '', + price: 0, + marketPrice: 0, + costPrice: 0, + stock: 0, + weight: 0, + volume: 0, + properties: item, + } + tempSkus.push(obj) + } - skus.value = tempSkus; + skus.value = tempSkus +} + +/** + * @author Ankkaya + * @description 新增商品初始化商品 sku + * @param {Type} - + * @returns {Type} + */ +function initSku() { + // 单规格 + if (!formData.value.specType) { + let obj = { + picUrl: '', + barCode: '', + price: 0, + marketPrice: 0, + costPrice: 0, + stock: 0, + weight: null, + volume: null, + properties: [ + { + propertyId: 0, + propertyName: '默认', + valueId: 0, + valueName: '默认', + }, + ], + } + + skus.value = [obj] + } else { + // 多规格 + skus.value = [] + } +} + +/** + * @author Ankkaya + * @description 确认属性 + * @param {Type} - + * @returns {Type} + */ +function submitProperty() { + try { + validateSku(skus.value) + peach.$store('trade').skus = skus.value + peach.$router.back() + } catch (e) { + console.log(skus.value) + console.log(e, '校验失败') + } +} + +function validateSku(skus) { + let warningInfo = '请检查商品各行相关属性配置,' + let validateStatue = true + let skusValue = skus ?? peach.$store('trade').skus + for (const sku of skusValue) { + for (const rule of SKU_RULE_CONFIG) { + const arg = getValue(sku, rule.name) + if (!rule.rule(arg)) { + validateStatue = false + warningInfo += rule.message + break + } + } + if (!validateStatue) { + uni.showToast({ + title: warningInfo, + icon: 'none', + duration: 4000, + }) + throw new Error(warningInfo) + } + } +} + +function getValue(obj, arg) { + const keys = arg.split('.') + let value = obj + for (const key of keys) { + if (value && typeof value === 'object' && key in value) { + value = value[key] + } else { + value = undefined + break + } + } + return value } function reduceArr(arr) { - return arr.reduce((acc, cur) => { - let tempAcc = []; + return arr.reduce((acc, cur) => { + let tempAcc = [] - if (acc.length < 1) { - cur.forEach((item, index) => { - if (tempAcc[index]) { - tempAcc[index].push(item); + if (acc.length < 1) { + cur.forEach((item, index) => { + if (tempAcc[index]) { + tempAcc[index].push(item) + } else { + tempAcc[index] = [item] + } + }) } else { - tempAcc[index] = [item]; - } - }); - } else { - acc.forEach((item, index) => { - cur.forEach((sitem, sindex) => { - tempAcc.push([...item, sitem]); - }); - }); + acc.forEach((item, index) => { + cur.forEach((sitem, sindex) => { + tempAcc.push([...item, sitem]) + }) + }) - if (cur.length < 1) { - tempAcc = acc; - } - } - return tempAcc; - }, []); + if (cur.length < 1) { + tempAcc = acc + } + } + return tempAcc + }, []) } -const specType = computed(() => peach.$store("trade").goodsInfo.specType); +const specType = computed(() => peach.$store('trade').goodsInfo?.specType || false) function initial() { - onLoad(() => { - formData.value.specType = specType.value ? true : false; - formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label; - skus.value = peach.$store("trade").skus; - if (specType.value) { - getGoodsProperty(); - } - }); + onLoad(() => { + formData.value.specType = specType.value ? true : false + formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label + skus.value = JSON.parse(JSON.stringify(peach.$store('trade').skus)) + // 如果新增商品 sku,并且是单规格,初始化 sku + + if (!skus.value) { + initSku() + } + if (specType.value) { + getGoodsProperty() + } + }) } export { - initial, - canEdit, - skus, - pickerRef, - pickerProperty, - onConfirm, - propertyListRef, - formData, - onRDPickerConfirm, - onPropertyConfirm, - propertyList, - showPropertyList, - goodsPropertyList, - changeSubProperty, -}; + initial, + canEdit, + skus, + pickerRef, + pickerProperty, + validateSku, + onConfirm, + submitProperty, + propertyListRef, + formData, + onRDPickerConfirm, + onPropertyConfirm, + propertyList, + showPropertyList, + goodsPropertyList, + changeSubProperty, +} diff --git a/pages/product/manageGoods.vue b/pages/product/manageGoods.vue index 0376f3e..dc1029b 100644 --- a/pages/product/manageGoods.vue +++ b/pages/product/manageGoods.vue @@ -1,187 +1,285 @@ diff --git a/pages/product/sku.vue b/pages/product/sku.vue index 7cb9ee9..507e249 100644 --- a/pages/product/sku.vue +++ b/pages/product/sku.vue @@ -1,45 +1,68 @@ diff --git a/peach/components/p-picker/p-picker.vue b/peach/components/p-picker/p-picker.vue index 829d16a..e906ec6 100644 --- a/peach/components/p-picker/p-picker.vue +++ b/peach/components/p-picker/p-picker.vue @@ -1,35 +1,47 @@ diff --git a/uni_modules/piaoyi-editor/changelog.md b/uni_modules/piaoyi-editor/changelog.md new file mode 100644 index 0000000..ff29b42 --- /dev/null +++ b/uni_modules/piaoyi-editor/changelog.md @@ -0,0 +1,10 @@ +## 1.1.0(2024-04-19) +解决不存在问题 +## 1.0.9(2024-02-04) +更新使用文档说明 +## 1.0.8(2023-12-28) +修改文档使用注意事项 +## 1.0.7(2023-12-05) +优化 +## 1.0.6(2023-12-05) +优化 diff --git a/uni_modules/piaoyi-editor/components/piaoyi-editor/color-picker.vue b/uni_modules/piaoyi-editor/components/piaoyi-editor/color-picker.vue new file mode 100644 index 0000000..ac6c30c --- /dev/null +++ b/uni_modules/piaoyi-editor/components/piaoyi-editor/color-picker.vue @@ -0,0 +1,784 @@ + + + + + diff --git a/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.css b/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.css new file mode 100644 index 0000000..9c5ab99 --- /dev/null +++ b/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.css @@ -0,0 +1,123 @@ +@font-face { + font-family: "iconfont"; /* Project id 4040150 */ + src: url('iconfont.woff2?t=1682491617906') format('woff2'), + url('iconfont.woff?t=1682491617906') format('woff'), + url('iconfont.ttf?t=1682491617906') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-checklist:before { + content: "\e600"; +} + +.icon-zitiyanse:before { + content: "\e646"; +} + +.icon-formatheader1:before { + content: "\e860"; +} + +.icon-formatheader2:before { + content: "\e861"; +} + +.icon-undo:before { + content: "\e787"; +} + +.icon-redo:before { + content: "\e788"; +} + +.icon-indent:before { + content: "\e7f3"; +} + +.icon-outdent:before { + content: "\e7f4"; +} + +.icon-zitijiacu:before { + content: "\ec83"; +} + +.icon-zuoyouduiqi:before { + content: "\ec87"; +} + +.icon-Character-Spacing:before { + content: "\ed91"; +} + +.icon-format:before { + content: "\e6da"; +} + +.icon-font-size:before { + content: "\e7b9"; +} + +.icon-duanhouju:before { + content: "\e61a"; +} + +.icon-duanqianju:before { + content: "\e61b"; +} + +.icon-shanchuxian:before { + content: "\e602"; +} + +.icon-charutupian:before { + content: "\e603"; +} + +.icon-fengexian:before { + content: "\e60e"; +} + +.icon-juzhongduiqi:before { + content: "\e620"; +} + +.icon-wuxupailie:before { + content: "\e63e"; +} + +.icon-youduiqi:before { + content: "\e64b"; +} + +.icon-youxupailie:before { + content: "\e64c"; +} + +.icon-zitixiahuaxian:before { + content: "\e657"; +} + +.icon-zitixieti:before { + content: "\e658"; +} + +.icon-zuoduiqi:before { + content: "\e65a"; +} + +.icon-LineHeight:before { + content: "\e624"; +} + +.icon-editor-background-color:before { + content: "\e829"; +} + diff --git a/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.ttf b/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..712351d5979807814b291be524691dcbb3b5020a GIT binary patch literal 6564 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 literal 0 HcmV?d00001 diff --git a/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.woff b/uni_modules/piaoyi-editor/components/piaoyi-editor/iconfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..26895902e2d6092791e1cd6d1f5ad604ade7468a GIT binary patch literal 4076 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 literal 0 HcmV?d00001 diff --git a/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue b/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue new file mode 100644 index 0000000..857f4bd --- /dev/null +++ b/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue @@ -0,0 +1,516 @@ + + + + + diff --git a/uni_modules/piaoyi-editor/package.json b/uni_modules/piaoyi-editor/package.json new file mode 100644 index 0000000..9f75a32 --- /dev/null +++ b/uni_modules/piaoyi-editor/package.json @@ -0,0 +1,15 @@ +{ + "id": "piaoyi-editor", + "name": "多功能富文本编辑器", + "displayName": "多功能富文本编辑器", + "version": "1.1.0", + "description": "富文本编辑器,内置上传图片以及更改颜色, 多样化等功能", + "keywords": [ + "富文本编辑器", + "上传图片", + "字体颜色" + ], + "dcloudext": { + "type": "component-vue" + } +} \ No newline at end of file diff --git a/uni_modules/piaoyi-editor/readme.md b/uni_modules/piaoyi-editor/readme.md new file mode 100644 index 0000000..6c26cf5 --- /dev/null +++ b/uni_modules/piaoyi-editor/readme.md @@ -0,0 +1,101 @@ +### piaoyiEditor 富文本编辑器 + +**使用方法:** + +``` + + + + + + +``` + +#### 事件说明 + +1、**使用上传图片功能时需要注意查看代码里面的uni.uploadFile方法,因为它的返回值取决于自己后端接口的值,所以可以根据实际情况就行更改即可** + +| 事件名 | 返回值 | 描述 | +| :---------: | :----: | :------------: | +| @saveContens | {html: html片段, length: html长度} | 文本框内容回调 | + +#### Prop + +| 参数名称 | 默认值 | 描述 | +| -------- | ------------------------------ | +| maxlength| 300 | 输入最大长度 | +| readOnly | false | 是否只读 | +| api | 空 | 上传图片接口地址 | +| photoUrl | 空 | 服务器图片域名或者ip | +| name | 'file' | 上传图片接口的key | +| values | '' | 富文本编辑器默认值 | + +### 注:近期收到使用用户反馈,存在以下四个问题(如有好的建议,期待私信,谢谢) + +1、当组件在页面中部或者底部的时候,进入页面,页面会自动滚动到富文本编辑器的区域 +属于正常现象; +官网文档有这么一句话:编辑器聚焦时页面会被上推,系统行为以保证编辑区可见; +作者建议这种情况,进入页面初始设置富文本编辑器为只读,然后页面滚动到一定距离的时候取消这个只读; + +2、组件粘贴文字出现软键盘闪烁,导致文字粘贴不了 +目前暂未发现解决方法,本插件是在官方的editor基础上开发的,这个组件存在这个问题; +经测试长按出现粘贴后,手不松开滑动到粘贴字样上就不会出现闪烁,然后松开手,点击粘贴就可以; + +3、有些上传图片接口是需要token的,接口需要token的话可以在组件内搜索uni.uploadFile,加上headers头部参数 + +4、H5有时候会出现插件异常情况,不要慌,查看[editor组件官网](https://uniapp.dcloud.net.cn/component/editor.html)官网下的注意事项(原话是:H5 端需要动态引入 quill.min.js、image-resize.min.js 依赖,默认情况下浏览器会从 unpkg.com 加载。如果依赖加载较慢或失败,uni-app 建议使用通过测试的 js 依赖保证效果一致,访问 github.com 或者 gitee.com 选择下载。可以放入 static 目录进行托管,或者使用 CDN 服务商。为了保证服务的稳定性,推荐开发者将所有前端资源使用 uniCloud 前端网页托管 服务进行托管,然后在 自定义模板 的 head 标签内引入相关 js 依赖。) + + (1)上面H5这种情况我推荐一种方法进行测试:把所需要的静态资源下载到本地,在APP.vue里面的onLunch下进行dom操作插入这些静态资源 + (2)使用官方提供的自定义模板(hx新建项目的Hello uni-app模板里面有示例):使用官方的自定义模板引入静态资源,亲测引入静态资源成功了(即引入js和css都是本地的静态资源,不再请求远程CDN文件),但是原来页面样式全丢失了,目前还没有找到问题所在没有成功的朋友欢迎加群交流一下,谢谢 + +### 可接定制化组件开发 +### 右侧有本人代表作小程序二维码,可以扫码体验 +### 如使用过程中有问题或有一些好的建议,欢迎加QQ群互相学习交流:120594820 \ No newline at end of file