uni-app常见问题解决办法

easycom组件模式是怎么回事

官方文档:https://uniapp.dcloud.io/collocation/pages?id=easycom

easycom组件就是符合components/组件名称/组件名称.vue目录结构的组件。

简单说,只要听从官方的约定,那么无需引入、无需注册,可以实现开发时全局使用、打包时按需打包。

注意事项:

  1. 官方文档说的注意事项我就不重复了。

  2. 小程序原生组件要放到/wxcomponents/里面,并不是放到components里面,也不适用easycom。

  3. 符合components/组件名称/组件名称.vue目录结构,只要存放,无需其他任何操作就会被HBuilderX认出,但现实中几乎没人这么存,因为我们可能要使用多个组件库,这时候怎么办?你可以到pages.json去明确注册一下,这样存放路径就不那么受限了。例如:

// pages.json
{
    "easycom": {
        "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
    },
    
    // 以下为pages.json本身已有的内容
    "pages": [
        // ......
    ]
}

我们就看这行,它其实类似于正则替换,以u-开头的组件名,都会自动去@/uview-ui/components里面找。

"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"

如果还有一个组件库也是以u-开头作为组件名呢?怎么解决冲突?

首先看哪个组件库是低使用频率的,然后pages.json注册它的时候,不要写^u-(.*),改成别的前缀,比如^ux-(.*),使用的时候也注意要使用这个前缀就行了,比如<ux-button></ux-button>

vue语法 this.$emit('update:xxx') 在小程序不生效?

似乎就是不生效,可以用另外的写法:

this.$emit('update:fieldValue', e.detail.value);
// 改成:
this.$emit('update', e.detail.value);

其中fieldValue是prop名,由于父组件里要显式声明自定义事件,所以改成省略。

然后,父组件里需要显式声明自定义事件:

// 给组件加上
@update="password=$event"

页面间传递数据、调用方法的几种方式

URL传参

就不说了。

向navigateTo的页面传递数据、调用方法

这个是小程序的基础知识,在此简单说一下。比如,我想调用后一个页面的xxxToast方法,做法是:

A页面:

    methods: {
      onTap() {
        uni.navigateTo({
          url: '/pages/mine/index',
          success: (res) => {
            res.eventChannel.emit('xxxToast', { title: 'TOAST的标题' });
          }
        })
      }
    }

mine页面:

    onLoad() {
      const eventChannel = this.getOpenerEventChannel();
      eventChannel.on('xxxToast', ({title}) => {
        uni.showToast({
          title
        })
      }),
    },

向navigateBack的前一页传递信息

有这样一个场景,从文章列表页打开某个详情页,详情页有个删除按钮,点击删除,则文章被删除,并跳回列表页,列表页应重新ajax,或者从内存中的列表数组中删掉该文章。让列表页更新数据不允许无脑更新,必须是有指令才更新,没指令则不更新。我们分析一下:

  • 似乎需要用navigateBack,但是navigateBack的success不具有res.eventChannel能力。

  • navigateBack没有url属性,无法URL传参。

  • 换用navigateTo的话,被删除的详情页会留存在页面栈,手机回退会重新进入被删除的详情页,肯定不允许。

  • 换用redirectTo的话,虽然详情页被杀掉,因此不会重新进入详情页,但是进入列表页之后,手机回退会又进一次列表页,也不允许。

所以,我们依然需要用navigateBack,然后用某种方式传递信息,怎么办呢?

可以利用getCurrentPages()获取页面栈,然后执行前一页的方法即可。

A页面:

    methods: {
      list() {
        // ...
      }
    }

mine页面(也就是B页面):

原理是利用页面栈调用其他页面的方法。但不同平台又有区别。

  • H5和小程序必须先调用页面栈的方法,再回退,也就导致,页面栈要找倒数第二个页面。

  • APP可以有2个选择,那么采用上方的方法,要么是先回退,再调用页面栈的方法。

综合说,应当全平台统一采用先调页面栈、后回退的方式。

然后区分.$vm

    methods: {
      onTap() {
            let pages = getCurrentPages();
            let prevPage = pages[pages.length - 2];
            // #ifdef H5
            prevPage.list();
            // #endif
            // #ifndef H5
            prevPage.$vm.list();
            // #endif
            uni.navigateBack()
      }
    }

A页面调用uni原生方法,B页面显示

现在,我们不跨页调用自定义方法,只是调用uni原生方法, 这时候最简单,直接写到success就行了。适用于所有路由方法。不适用于H5,因为H5一旦路由变化就终止一切后续代码。

        uni.navigateBack({
          success: () => {
            uni.showToast({
              title: '哈哈哈'
            })
          }
        });

引用本地图片作为背景图

本地背景图片的引用路径推荐使用以~@开头的绝对路径。

动态添加右上角按钮

          // #ifdef APP-PLUS
            var wv = plus.webview.currentWebview();
            wv.setStyle({
                titleNView: {  
                    titleText: '删除'  
                }  
            });
          // #endif

同样的,plus.webview.currentWebview()可以做很多事,参看:

https://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject

引入Vant组件报postcss-loader错的解决办法

如果引入Vant Weapp来开发小程序,不会有报错,但是如果同时发布到H5,就会报错“postcss-loader”相关错误,这个问题解决起来其实很简单,关键是看你知不知道。

打开@vant/weapp/icon/index.wxss,前几行是:

@import '../common/index.wxss';@font-face{font-weight:400;font-family:vant-icon;font-style:normal;font-display:auto;src:url(https://img.yzcdn.cn/vant/vant-icon-96970a.woff2) format("woff2"),url(https://img.yzcdn.cn/vant/vant-icon-96970a.woff) format("woff"),url(https://img.yzcdn.cn/vant/vant-icon-96970a.ttf) format("truetype")}

在里面找format("woff2"),urlformat("woff"),url,问题就出在这了。

给每个url前面敲一个空格,保存。重新编译,故障解除!

但是,这种跨端发布的操作,不一定永远能成功,因为Vant开发者没打算让你跨端使用。

同样,在H5开发中引入Vant 2,也会报同样的错误,也可用这种方法解决。如果你把vant 2安装在了node_modules里,无妨,把/lib/index.css拷出来,修改,引用这个css就行了。

解决APP环境没有navigator变量的问题

H5组件库往往使用navigator来判断浏览器是安卓还是iOS环境,以便做出不同的兼容,但是APP平台根本没有这个变量,组件库直接报错。怎么办?我们创建一个顶级navigator就可以了。

if (!window) {
  global.navigator = {
    userAgent: plus.navigator.getUserAgent()
  }
}

其中global相当于windowplus.navigator.getUserAgent()是H5 plus提供的API。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345