• 记:使用vue全家桶 + vux组件库 打包成 dcloud 5+ app 开发过程中遇到的问题


    vue-cli 版本:2.9.6  

    webpack 版本:3.6.0

    1. vue-cli 安装好之后,不是自动打开默认浏览器

    在 config文件夹 ---> dev选项中,有个 autoOpenBrowser 。把它置为 true 即可。

    2. 使用less(或者sass)全局变量

    起因: 因为想定义一些常用的工具样式。类似:超过一行隐藏字体并用省略号显示,清除浮动,主题颜色等。就考虑不用每个页面都引入,能直接使用定义的工具样式。

      第一步: 安装  npm install sass-resources-loader --save-dev 对的,你没有看错,要使用less全局变量,就要安装 sass-resources-loader 这个包

      第二步: 配置:找到build文件夹下面的utils.js 找到  exports.cssLoaders  中的最下面的 return {},然后在less配置项中配置以下代码

    配置前:

    return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus')
    } 

    配置后:

    return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less').concat({ 
          loader: 'sass-resources-loader', 
          options: { 
              resources: path.resolve(__dirname, '../src/assets/css/public.less') 
          } 
        }),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus')
    }

    (1) 配置的 less文件路径就是你自己的 工具样式 less 文件路径。用相对路径

    (2) 如果是 想要使用 sass的 工具样式。只需要在 同样配置 sass 的地方,后面添加 concat 即可。内容也是一样,除了工具样式 sass文件路径名。

    3.  vux组件库安装后报错:you may need an appropriate loader to handle this file type

    即  三点 ...  这种没有用 适当的 loader 来处理。这样的错误,是因为使用了vux 2x版本,所以先要安装 vux-loader 

      第一步:安装:  npm install vux-loader --save-dev 

      第二步:配置:在 build ---> webpack.base.conf.js  里修改。原来的 module.exports  使用 let originalConfig = xxx 来替换 。配置好后重启项目就能使用了

    修改前: 

    ...
    module.exports = { ... }

    修改后: 

    ...
    let originalConfig  = { ... }

    //下面的代码放到最底部 const vuxLoader = require('vux-loader') module.exports = vuxLoader.merge(originalConfig , { plugins: ['vux-ui'] })

    4.  import vux 组件,导致 栈溢出: Maximum call stack size exceeded

    产生这个的原因是: 引入的组件名 和当前 .vue文件中  export default 的name 值 相同,而且是 不区分大小写的相同

    修改方法: 把 name 值改成其它不相同的即可。

    5. 修改vux 组件库某些组件的样式。

    第一种方法: 如果是修改组件中,提供的 样式变量 这种官方提供的样式修改。那么,可以使用下面的这种办法:

      第一步: 在上面第三个安装报错问题处,修改成以下代码:

    ...
    let originalConfig  = { ... }
    
    
    //下面的代码放到最底部
    const vuxLoader = require('vux-loader')
    
    module.exports = vuxLoader.merge(originalConfig , {
        plugins: ['vux-ui', 'progress-bar', 'duplicate-style', {name: 'less-theme', path: 'src/style/vux_theme.less'}]
    })

      第二步: src下新建style文件夹,再新建vux_theme.less文件,然后里面加入需要修改的样式变量比如: @tabbar-text-active-color: #09BB07; 

      第三步:重启项目即可。如果把样式放到自己的 less 文件中,我发现还是没起作用。所以还是乖乖的按照上面的步骤来弄。

    第二种方法: 也是个人推荐的一种方式

      就是:在 style 中不使用 scoped 属性。那么这样当前页面的 样式就相当于全部公用了。为了防止样式污染,那么就需要在当前 .vue 组件中,最外层 div 加一个class 或者 id 值。这样利用优先级去修改样式即可。

    第三种方式: 深度选择器 /deep/ <<<

      大家都知道:如果使用了scoped属性,那么会在组件外层加上一个data-v的标识,导致修改不了组件内部的样式,除非使用 /deep/ 或者 <<< 深度选择器。但是深度选择器不支持less,但是可以转换一种方法来写就可以支持:

    @deep: ~'>>>'; 
    .parent-custom { 
    @{deep} .child-title { 
            font-size:20px;
            color: red; 
        } 
    }

    (1) 注意 深度选择器 >>>  前面一定要加上  波浪符号 ~  。这样表示不编译后面的内容,全部以字符串输出

    (2) 这种深度选择器,也可以用于修改 v-html 的内容中的样式。

    6.  使用 px2rem 之后,不编译第三方UI组件库的px单位的方法:

      第一步: 不要安装 px2rem-loader 。需要安装 npm i postcss-px2rem-exclude –save  

      第二步: vue-cli搭建的环境中,有个.postcssrc.js文件,然后在这个文件修改成如下的代码:

    module.exports = {
      "plugins": {
        "postcss-import": {},
        "postcss-url": {},
        // to edit target browsers: use "browserslist" field in package.json
        "autoprefixer": {},
      // 需要添加的内容
    'postcss-px2rem-exclude': { remUnit: 75, exclude: /node_modules|folder_name/i // 忽略node_modules目录下的文件 } } }

    (1) 因为第三方 ui 库的meta 都是   <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  ,使用 flexible 之后会自动添加 meta,当meta 缩放是0.5的时候,就会缩小。

    (2) remUnit 在这里要根据 lib-flexible 的规则来配制,如果设计稿是750px的,用75就刚刚好。

    (3) 如果不想 让 px 编译成 rem 。可以在这个样式后,加上/*no*/ 。例如  border:1px solid #ccc;/*no*/  

    (4) 注意,px2rem 插件 不能让 行内样式 和 js动态加入的 px单位转变成 rem。 如果实在要让 js 中的px单位转换成 rem,那么,可以用 设计稿中的 大小 来除以 remUnit 的大小,得到的就是 正常的 rem值。比如,我 750px 设计图上是 200的宽度,那么 rem 就是 200 / 75 = 2.666666。最后再拼接'rem'成字符串即可。

    在第二步中还有的说法是:在 package.json 中配置如下代码:

    "postcss": {
        "plugins": {
            "autoprefixer": {},
            "postcss-px2rem-exclude": {
                "remUnit": 75,
                "exclude": "/node_modules|folder_name/i"
            }
        }
    }    

    不过,配置过后并未起作用。所以建议还是用前面的方法

    7.  使用 lib-flexible 之后,在index.html中不要添加缩放的那个meta,插件会自动添加。否则会出现将 “将根据已有的meta标签来设置缩放比例” 的警告。

    8.  dcloud 5+ app 之分享功能。分享总共分三步(记住要先在 manifest.json 文件中的SDK配置中,把申请的分享的各种 appid、appkey等内容填写好):

      第一步:是获取分享服务列表,即 获取 qq,新浪微博,微信。这三个分享服务

      第二步:判断该服务是否授权。如果授权就进入分享的函数,否则去获取授权

      第三步:在授权成功的情况下,就进行分享。

    完整的代码如下:

    html 部分
    <div v-for="(i,idx) in list" :key="'share_'+idx" @click="judegeAuthorize(list[idx].id)"></div>
    
    js 部分
    data:function(){
      let curPath = (location.origin + location.pathname).replace('index.html',''); //因为是打包成app,所以没有网络路径,如果要分享本地图片,就必须用这种方式来拼接本地图片的路径。
      let imgPath = curPath + 'static/image/public/defaultHeader.png'; //分享的图片的路径
      return{
        shareLink:'http://www.baidu.com', //分享链接  list: [ { id:
    "weixin", imgurl: "static/image/public/msg_share_weixin.png", title: "微信", ex:'WXSceneSession' }, { id: "weixinFriends", imgurl: "static/image/public/msg_share_friends.png", title: "朋友圈", ex:'WXSceneTimeline' }, { id: "qq", imgurl: "static/image/public/msg_share_qq.png", title: "QQ" }, { id: "sinaweibo", imgurl: "static/image/public/msg_share_weibo.png", title: "微博" }  ],  shareOptions:{}, //分享渠道:微信、QQ、新浪微博 //qq分享的内容选项 qqOptions:{ title:'这是QQ分享的标题', //(必填,最长30个字符) content:'这是QQ分享的内容', //(可选,最长40个字符) thumbs: [imgPath], // 数组类型 href:this.shareLink }, //微信分享的内容选项 weixinOptions:{ title:'这是微信好友分享的标题', content:'这是微信好友分享的内容', thumbs: [imgPath], href:this.shareLink, extra:{ scene:"WXSceneSession" } }, // 微信朋友圈分享的内容选项 weixinFriendsOptions:{ title:'这是微信朋友圈分享的标题', content:'这是微信朋友圈分享的内容', thumbs: [imgPath], href:this.shareLink, extra:{ scene:"WXSceneTimeline" } }, //新浪微博分享的内容选项 sinaweiboOptions:{ content:'这是新浪微博分享的内容', href:this.shareLink, pictures: [imgPath] } } }, created:function(){ var that = this; if(window.plus){ // 扩展API加载完毕,现在可以正常调用扩展API plus.share.getServices(function(data){ var shareObj = {}; for(var i in data){ shareObj[ data[i].id ] = data[i]; } that.shareOptions = shareObj; }, function(){ plus.nativeUI.toast('获取分享服务列表失败') }) } }, methods:{ //处理分享功能 shareHandler:function(target,config){ target.send(config, function(msg){ plus.nativeUI.toast("分享到"+target.description+"成功"); },function(e){ console.log(e) let msg = e.code == -2 ? '已取消分享' : "分享到"+target.description+"失败"; plus.nativeUI.toast(msg); }); }, //判断是否授权 judegeAuthorize:function(id){ var target = this.shareOptions; if(JSON.stringify(target) == '{}'){ plus.nativeUI.toast("分享组件未准备好,请稍后再试"); return } let config = null; switch(id){ case 'weixin': config = this.weixinOptions; break; case 'weixinFriends': config = this.weixinFriendsOptions; id = 'weixin'; break; case 'qq': config = this.qqOptions; break; case 'sinaweibo': config = this.sinaweiboOptions; break; } var that = this; if(target[id].authenticated){ this.shareHandler(target[id],config); }else{ target[id].authorize( function(){ plus.nativeUI.toast("授权成功"); that.shareHandler(target[id],config); }, function(e){ plus.nativeUI.toast("授权失败"); }); } } }

    注意事项:

    (1) 朋友圈和微信好友的区别就是 扩展内容 extra 里的 scene 不同。

    (2) 分享的图片路径,都是数组类型。

    (3) 微信的分享,如果是直接返回,并没有分享,但是结果返回也是分享成功。新浪微博获取不了分享是否成功的状态,不知道是否我哪里弄错了。如果qq分享失败,查看参数是否正确,或者图片是否是数组类型。

    (4) 可以不用官方的 document.addEventListener('plusready',function(){})  来判断 plus是否准备好。可以直接判断 window.plus 来看plusready是否准备好。

    9. 引入 mui.js 报错

    引入:在 main.js 中导入  import mui from './assets/js/mui.js'  。然后报错了。 may not be accessed on strict mode

    产生这样的原因是因为: vue-cli 使用了 babel 把es6 转成es5 ,默认的是使用的严格模式。解决的办法:在 .babelrc 文件中修改

      增加忽略babel编译的文件:在与 plugins 同级的位置添加:  "ignore":["./src/assets/js/mui.min.js"]    后面的就是 mui.min.js 的文件位置 

    然后就可以 把 mui 挂在到 Vue 原型上了。

    10.  设置沉浸式导航栏

    if(window.plus){
          console.log('设置状态栏')
          plus.navigator.setStatusBarBackground('#fff');//设置状态栏背景颜色
          plus.navigator.setStatusBarStyle('light');//设置状态栏字体颜色
    }

    (1) 状态栏字体颜色 只支持 light 和 dark 两个值。

    (2) 如果在设置了 keep-alive 的组件页面中,有可能前面的页面会影响当前页面。那么可以在 activated,deactivated 的 方法里面再设置一次。

    11.  打包成app之后,安卓后退键的处理。有两种方式:

      第一种: 使用 5+ 监听安卓后退按钮。在vue的生命周期中调用

    document.addEventListener('plusready', function() {
          var first = null;
          var webview = plus.webview.currentWebview();
          plus.key.addEventListener('backbutton', function() {
            webview.canBack(function(e) {
              if (e.canBack) {
                webview.back(); //这里不建议修改自己跳转的路径
              } else {
                //首次按键,提示‘再按一次退出应用’
                if (!first) {
                  first = new Date().getTime(); //获取第一次点击的时间戳
                  plus.nativeUI.toast('再按一次退出应用', {
                    duration: 'short'
                  }); 
                  setTimeout(function() {
                    first = null;
                  }, 1000);
                } else {
                  if (new Date().getTime() - first < 1000) {
                    //获取第二次点击的时间戳, 两次之差 小于 1000ms 说明1s点击了两次,
                    plus.runtime.quit(); //退出应用
                  }
                }
              }
            })
          });
        })

    (1) 这种不支持用 mui.openWindow 打开的页面的返回。除非 再去判断 是否有 指定ID 打开的webview  plus.webview.getWebviewById('自定义的页面id')  。然后再去关闭指定ID的webview页面。 plus.webview.close('jmyc') 

    (2) 这种方式也有点问题,两次的点击时候需要小于1s才能后退。

      第二种: 引入 mui 。在vue的生命周期中调用:

    data:{
        openWebView:false, //是否打开了页面
    },
    created:function(){
      this.$mui.init({
          beforeback: function(){
            if(_this.openWebView){
              //获得列表界面的webview jmyc
              var viewObj = plus.webview.getWebviewById('jmyc');
              //canBack查询窗口是否可退
               viewObj.canBack((event) => {
                var canBack = event.canBack;  
                if(canBack) {//如可退,则返回上一页面
                  viewObj.back();
                } else {//如不可退,则退出窗口
                  plus.webview.close('jmyc')
                  _this.openWebView = false;
                }
              })
              return false;
            }
            return true;
          }
       });  
    }

    (1) 前提是mui已经在 main.js 中引入,并且挂在到了vue 原型上 

    import mui from './assets/js/mui.min.js'
    Vue.prototype.$mui = mui

    (2) 这种方式的好处就是,不用去判断是否超过一秒。

    12. 路由的懒加载,实现按需加载。

    // 实现路由懒加载
    function lazyLoad(filename){
      return () => import(`@/page/${filename}/index.vue`);
    }
    
    export default new Router({
      routes: [
        {
          path: '/index',
          name: 'indexToo',
          component: lazyLoad('index'),
          meta: {
            keepAlive: true // 需要被缓存
          },
        {
          path: '*',
          name: 'z_page404',  //404页面 , 必须放在最底部
          component: lazyLoad('z_page404')
        }    
      ]
    })

    (1) 上面这种写法,是因为 每个 page 都新建了一个 index.vue 文件当做页面,然后文件夹以不同的名称来区分。

    13.  需要缓存的页面的处理:

    第一步: 需要缓存的才使用 keep - alive 

    <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>

    第二步: 在 router.js中配置 meta 

    export default new Router({
      routes: [
        {
          path: '/index',
          name: 'index',
          component: lazyLoad('index'),
          meta: {
            keepAlive: true // 需要被缓存
          }    
      ]
    })

    如果想某些页面动态来判断是否缓存: 比如,当前页面是 A ,需要缓存,但是从 B 页面返回来之后,A页面需要更新内容就不能缓存。在与 created 生命周期 同级上写。

    // 如果路由进入前,是从 B页面返回来的,那么就设置当前 A 页面不缓存,否则缓存
      beforeRouteEnter(to, from, next) {
        if(from.path == '/B'){
          to.meta.keepAlive = false; 
        }else{
          to.meta.keepAlive = true;
        }
        next();
     },

    (1) 最后一定要调用 next() 方法。

    14. 打包成app 之后,图片,css,js等路径不正确

      如果没有修改其它的路径什么的,多半是config文件夹中index.js里面,buildassetsPublicPath路径为” /” 是绝对路径,把它改为相对路径 “./” 就可以了。然后重新打包

      项目中,不管是img标签中的图片,还是 css中的背景图片,都需要使用相对路径

    15.  如果想更方便的调试 5+ plus的效果:

      建议在 5+ app 的 index.html 添加一个 a标签,href就是当前 项目运行的网络路径。 这样只用在基座上运行一次,然后项目每次修改,都可以看到效果。

      如果是自定义基座,运行了之后,怕看不到控制台的内容,hbuilderX 自带有 webview 调试。运行之后,有个链接可以点击,就可以使用谷歌的 inspect 来调试

      或者 使用 Vconsole 来调试

    16. 断网的处理

    data:{
        networkStatus: false
    },
    created:function(){  
        let that = this;
        document.addEventListener("netchange", function () { //监听网络变化事件  
          // 延迟二秒获取网络状态
          setTimeout( () => {
            let target = plus.networkinfo.getCurrentType();
            // 0 表示不认识的网络。 1表示未连接网络
            if ( target == 0 || target == 1) {  
              console.log('无网络连接',target)
              that.networkStatus = true;
              that.$store.commit('changeNetworkStatus',true);
            }else{
              that.networkStatus = false;
              that.$store.commit('changeNetworkStatus',false);
            }
          },2000)        
        }, false);  
    }

    (1) 用了vuex存放了当前网络状态。一般把断网的显示内容封装成一个组件,然后在这个组件里写入上面的内容。

    (2) 然后在 APP.vue 中引入 组件。然后再根据 vuex中网络的状态,决定是否显示断网组件。

  • 相关阅读:
    redis如何实现数据同步
    mysql调优学习笔记
    介绍一个好用的dao层与mybatis互跳的idea插件MyBatisCodeHelperPro
    springboot执行流程
    zookeeper
    (原创) cocos2dx使用Curl连接网络(客户端)
    (转) Eclipse连接MySQL数据库(傻瓜篇)
    (原创)cocos2dx使用jsoncpp的正确姿势
    Java web开发(17)SpirngMVC 详解
    PLC 程序和仿真
  • 原文地址:https://www.cnblogs.com/zjjDaily/p/11414108.html
Copyright © 2020-2023  润新知