vue實戰積累-純技術

vue打包部署

1先提前備份之前的包文件,然後刪除之前的文件,複製新的包文件

vue 本地可以運行,打包到服務運行報錯,

1問題背景:本地運行不需要服務器環境,打包到服務器,服務器的二級域名的地址可能改變了

比如:服務器的目錄是msupplier/wx/

config的地址配置文件路徑:

assetsPublicPath: '/mssupplier/wx/',

導致資源文件找不到,導致項目運行報錯 

vue cannot get / 報錯

問題:當前項目從node8升級node10,導致npm的包的版本不兼容有問題

解決:需要重新安裝對應版本的npm包 ,node-sass的版本不兼容,卸載重新安裝

原來的版本,

 "node-sass": "^4.5.2"

改成

"node-sass": "^4.14.1",

再安裝下新的版本,cnpm run dev

微信js掃一掃,掃條碼去掉code_128

wx.scanQRCode({
    needResult: 0, // 默認爲0,掃描結果由微信處理,1則直接返回掃描結果,
    scanType: ["qrCode","barCode"], // 可以指定掃二維碼還是一維碼,默認二者都有
    success: function (res) {
        var result = res.resultStr; // 當needResult 爲 1 時,掃碼返回的結果
        var barCode = getBarCode(result);
    }
});
function getBarCode(resultStr){
        var serial = resultStr.split(",");
        var barCode = serial[serial.length-1];
        return barCode;
} 

微信js掃描二維碼 ios系統掃碼沒返回結果-官方解決方案

        mounted()
        {
            this.getShopInfo();               // 獲取供應商信息

            if(!security.isIOS())
            {
                security.getSignature();     // 獲取微信簽名
            }
        },

        methods:
        {
            getScanQRCode()
            {
                let self = this

                wx.ready(()=>
                {
                    wx.checkJsApi
                    ({
                        jsApiList: ['scanQRCode'],
                        success:(checkRes)=>
                        {
                            wx.scanQRCode
                            ({
                                needResult: 1,                  // 默認爲0,掃描結果由微信處理,1則直接返回掃描結果,
                                scanType: ["qrCode","barCode"], // 可以指定掃二維碼還是一維碼,默認二者都有
                                success:(res)=>
                                {
                                    // ios系統掃碼官方解決方案
                                    setTimeout(()=>
                                    {
                                        let scanCode = res.resultStr.split('=')[1]; // 當needResult 爲 1 時,掃碼返回的結果  scanCode

                                        self.$router.push({ path: '/scanDetail', query:{ "oid": scanCode}});
                                    },1000)
                                }
                            });
                        }
                    });
                })
            },

            // 微信簽名
            getSignature()
            {
                let self = this,
                    params = 
                    {
                        'url': location.href.split('#')[0]
                    };

                signature
                ({
                    params:params,

                    success: (res)=>
                    {
                        wx.config
                        ({
                            debug: false,                  // 開啓調試模式
                            appId: res.appId,              // 必填,唯一標識
                            timestamp: res.timestamp,      // 必填,時間戳
                            nonceStr: res.noncestr,        // 必填,隨機串
                            signature: res.signature,      // 必填,簽名
                            jsApiList: ['checkJsApi','scanQRCode']      // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
                        });
                    },
                    failure: (message)=>
                    {
                        alert(message);
                    }
                }) 
            },

        }

vue使用iconfont

下載資源:

https://www.iconfont.cn/api/project/download.zip?ids=6889246|-1&ctoken=6DcOjHva_wd1-dBW4OCgseHX

main.js引入

import './assets/iconfont/iconfont.js'

使用:

<template>
    <div>
      <div>taobao</div>
      <svg class="icon" aria-hidden="false">
        <use xlink:href="#icon-taobao"></use>
      </svg>
    </div>
</template>

<script>
    export default {
        name: "PostOne"
    }
</script>

<style scoped>
    .icon {
      width: 40px;
      height: 40px;
      fill: red;
    }
</style>

symbol引用參考:https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.16&helptype=code

使用vue+better-scroll實現橫向滾動效果

重點:必須使用li

http://www.imooc.com/article/272021

<template>
    <div class="container">
        <div class="one">
            <div>111</div>
        </div>
        <div class="personTap">
            <div class="person-wrap" ref="personWrap">
                <ul class="person-list" ref="personTab">
                    <li class="person-item">1</li>
                    <li class="person-item">2</li>
                    <li class="person-item">3</li>
                    <li class="person-item">4</li>
                    <li class="person-item">5</li>
                </ul>
            </div>
        </div>
        <div class="two">
            <div>222</div>
        </div>
    </div>
</template>
<script>
import BScroll from 'better-scroll';
export default {
    name: "Traffic",
    data() {
        return {
            a: ''
        }
    },
    created() {
        this.$nextTick(() => {
            this.personScroll();
        });
    },
    mounted() {

    },
    computed: {},
    methods: {
        personScroll() {
            // 默認有六個li子元素,每個子元素的寬度爲120px
            let width = 6 * 120;
            this.$refs.personTab.style.width = width + "px";
            // this.$nextTick 是一個異步函數,爲了確保 DOM 已經渲染
            this.$nextTick(() => {
                if (!this.scroll) {
                    this.scroll = new BScroll(this.$refs.personWrap, {
                        startX: 0,
                        click: true,
                        scrollX: true,
                        // 忽略豎直方向的滾動
                        scrollY: false,
                        eventPassthrough: "vertical"
                    });
                } else {
                    this.scroll.refresh();
                }
            });
        }
    },
}

</script>
<style scoped>
.container {
    width: 375px;
    height: 100%;
}

.personTap {

    width: 375px;
    height: 100px;
    background: rgba(246, 245, 250, 1);
    border-radius: 15px 15px 0px 0px;
    margin-top: 10px;
    background: red;
    touch-action: none;

}

li,
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

.person-item {
    display: inline-block;
    width: 120px;
    height: 90px;
    background: rgba(255, 255, 255, 1);
    box-shadow: 0px 2px 16px 0px rgba(127, 127, 127, 0.22);
    border-radius: 7px;
    margin-left: 15px;
    text-align: center;
}

.one {
    display: flex;
    width: 375rpx;
    height: 50px;
    background: #0f0;
}


.two {
    display: flex;
    width: 375rpx;
    height: 50px;
    background: #0f0;
}

</style>

移動端字體放大導致佈局錯亂的解決方案

解決方案:

1.頁面限制用戶縮放【防止頁面被縮小和放大】

<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>

針對iOS,調整字體大小本身只是改變body的css屬性,因此可以通過覆蓋樣式來控制。

body {
    -webkit-text-size-adjust: 100% !important;
}

Android微信瀏覽器:

在編寫本文時,通過網上一些資料,發現在Android微信中,也可以藉助WeixinJSBridge對象來阻止字體大小調整。實測也有效。

justSize: function () {
        if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
          this.handleFontSize();
        } else {
          document.addEventListener("WeixinJSBridgeReady", this.handleFontSize, false);
        }
      },
      handleFontSize: function () {
        // 設置網頁字體爲默認大小
        WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0});
        // 重寫設置網頁字體大小的事件
        WeixinJSBridge.on('menu:setfont', function () {
          WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0});
        });
      },

 

vuex中遇到 [vuex] unknown action type: xxx報錯

最後找出是store導出錯誤

export default new Vuex.Store({

state,

actions,//action錯誤寫法

mutations//mutations也會容易出現此類問題,需要避免

})

 

vue單獨給頁面設置body屬性

因項目需求:用戶個人詳細信息頁面設置背景色,之前在這個頁面設置最外層div發現不行。因爲app.vue影響了它。後來直接在頁面上用body設置樣式,發現影響了其他頁面。

後來想了通過vue的生命週期來解決。這個頁面創建前設置我的樣式,銷燬之前移除我設置的樣式。

代碼如下:

//創建前設置
beforeCreate () {
      document.querySelector('body').setAttribute('style', 'background-color:#efeff4;')
},
//銷燬前清除
beforeDestroy () {
      document.querySelector('body').removeAttribute('style')
},

vue項目中解決type=”file“ change事件只執行一次的問題

問題描述

在最近的項目開發中遇到了這樣的一個問題,當我上傳了一個文件時,我將獲取到的文件名清空後,卻無法再次上傳相同的文件

因爲我只是將data中的屬性值清空而已,文件名沒有變當然會不出發change事件

目前網上有好多解決辦法,但基本上都無法在vue上使用,於是我想到了v-if

v-if 是“真正”的條件渲染,因爲它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷燬和重建。

於是在代碼中加入了一個小的開關,喚起change事件時就將他銷燬

事件結束時再將它重建,這樣問題就輕鬆的解決了

注意要引入n-zepto:

npm install n-zepto --save-dev

<template>
 <div class="hello">
   <input type="button" value="上傳文件" name="" id="" @click="updata">
   <input v-if="ishowFile" type="file" style="display:none" @change="getFile" id="input-file">
   <div v-if="fileName">
    <p>上傳的文件名:{{fileName}}</p>
    <button @click="delFile">清空文件</button>
   </div>
 </div>
</template>
 
<script>
import $ from 'n-zepto'
export default {
 name: 'HelloWorld',
 data () {
  return {
   fileName: '',
   ishowFile: true,
  }
 },
 methods:{
  updata(){ // 喚起change事件
   $('#input-file').click()
   this.ishowFile = false // 銷燬
  },
  getFile(e){ // change事件
   this.doSomething()
   this.ishowFile = true // 重建
  },
  doSomething(){ // do something
   this.fileName = e.target.files[0].name
  },
  delFile(){
   this.fileName=''
  }
 }
}
</script>

input type = file 取消事件

問題描述

點擊了取消,下次再點擊不會觸發上傳圖片的方法

解決:

組件被銷燬的邏輯寫在用戶點擊了圖片的邏輯中

<template>
 <div class="hello">
   <input type="button" value="上傳文件" name="" id="" @click="updata">
   <input v-if="ishowFile" type="file" style="display:none" @change="getFile" id="input-file">
   <div v-if="fileName">
    <p>上傳的文件名:{{fileName}}</p>
    <button @click="delFile">清空文件</button>
   </div>
 </div>
</template>
 
<script>
import $ from 'n-zepto'
export default {
 name: 'HelloWorld',
 data () {
  return {
   fileName: '',
   ishowFile: true,
  }
 },
 methods:{
  updata(){ // 喚起change事件
   $('#input-file').click()
   
  },
  getFile(e){ // change事件
   this.doSomething()
   this.ishowFile = true // 重建
  },
  doSomething(){ // do something
    //用戶選擇了圖片
   this.ishowFile = false // 銷燬
   this.fileName = e.target.files[0].name

   //上傳圖片的邏輯
let reader = new FileReader();
        let $this = this;
        this.ishowFile = false // 銷燬
        //文件預覽
        reader.onload = function (evt) {
          $this.fp = evt.target.result;
        };
        reader.readAsDataURL(file);
        //上傳文件
        if (!/image\/\w+/.test(file.type)) {
          $this.$toast("請選擇圖片");
          return false;
        }
        // 原生ajax實現文件上傳
        let form = new FormData();
        form.append("file", file);
        let xhr = null; //得到xhr對象
        if (XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        } else {
          xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xhr.open("post", g.baseUrl + "/core/wechatpublic/upload", true);//設置提交方式,url,異步提交
        xhr.onload = function () {
          let obj = JSON.parse(xhr.responseText);
          $this.imgName = obj.data;
          $this.isUpdateImg=true;
          console.log('$this.isUpdateImg='+$this.isUpdateImg);
          console.log('$this.imgName='+$this.imgName);
        };
        xhr.send(form)
        xhr.cancel=function () {
          console.log('xhr.cancel')
        }
  },
  delFile(){
   this.fileName=''
  }
 }
}
</script>

vue打包後部分功能無效果,換臺電腦有效果

1,清理npm緩存

2 清理代碼緩存

 

監聽手機返回鍵事件

window.addEventListener("popstate", function (e) {
  //根據自己的需求實現自己的功能
 
}, false);

監聽手機鎖屏

 window.addEventListener('visibilitychange', () => {
   if (document.hidden) {
     console.log("離開頁面了")
     this.massage = "離開頁面了"
   } else {
     console.log('進入頁面')
     // this.msg="進入頁面"
   }
 })

@click是點擊事件,那麼如何觸發vue長按事件

1,觸屏事件

touchstart: //手指放到屏幕上時觸發

touchmove: //手指在屏幕上滑動式觸發

touchend: //手指離開屏幕時觸發

touchcancel: //系統取消touch事件的時候觸發,這個好像比較少用

由於這次不需要計算移動的距離,所以一隻用touchstart和touchend這兩個事件

<div @touchstart="touchin()" @touchend="cleartime()" />

@touchstart.prevent是阻止瀏覽器的默認行爲,如果不需要的話,就不用添加了,根據自己的實際情況

2,直接在methods裏寫長按方法和點擊事件

 

一定在data裏聲明Loop =0;不然不管用
 data() {
      return {
        Loop : 0
        }
    }

500表示觸屏時間,可以根據實際情況寫,只要達到這個時間就會觸發setTimeout裏的事件

touchin(){
        var that=this;
        this.Loop = setTimeout(function() {
          that.Loop = 0;
          //執行長按事件要執行的內容,如彈出菜單
        
        }, 500);
        
      },
觸屏離開的事件
cleartime() {
        var that=this;
        clearTimeout(this.Loop);
        if(that.Loop!=0){
          //這裏寫點擊要執行的內容(就像@onclick事件)
         
        }
        return false;

      },

vue query param 兩種傳參方式區別

param:

父組件中:通過路由屬性中的name來確定匹配的路由,通過params來傳遞參數。

       this.$router.push({
          name: 'Describe',
          params: {
            id: id
          }
        })

對應路由配置: 注意這裏不能使用:/id來傳遞參數了,因爲父組件中,已經使用params來攜帶參數了。

   {
     path: '/describe',
     name: 'Describe',
     component: Describe
   }

子組件中: 這樣來獲取參數

this.$route.params.id

query:

父組件:使用path來匹配路由,然後通過query來傳遞參數
這種情況下 query傳遞的參數會顯示在url後面?id=?

    this.$router.push({
          path: '/describe',
          query: {
            id: id
          }
        })

對應路由配置:

   {
     path: '/describe',
     name: 'Describe',
     component: Describe
   }

對應子組件: 這樣來獲取參數

this.$route.query.id

最重要的一點,既然要傳參肯定是要一直使用的,我們不能保證用戶不去刷新頁面吧,所以還是用 query傳參吧,param傳參刷新頁面後無效,query反之

vue路由回退到指定頁面

A頁面->B頁面->C頁面,點返回的時候,需要返回到A頁面

在B頁面:

router.replace('/C');
// 不會記錄路由,回退的話,是回退不到上一個頁面,適合單頁面的切換;

 

vue項目引入字體-使用字體.ttf

 1.把字體文件放到assets目錄font下
bahnschrift.ttf

設置less樣式:
font.less

@font-face {
  font-family: 'Bahnschrift-Regular';  //重命名字體名
  src: url('bahnschrift.ttf');  //引入字體
  font-weight: normal;
  font-style: normal;
}

main.js引入:

import './assets/font/font.less'

 第一次引入如果報錯:

Module not found: Error: Can't resolve 'less-loader' in

原因:這個less是需要安裝的,

cnpm install --save-dev less-loader less

https://blog.csdn.net/lilongwei4321/article/details/81364727

Vue-cli引用有fonts字體的組件,打包後路徑不正確

字體文件沒有效果

解決
主要是需要單獨爲 css 配置 publicPath 。
ExtractTextWebpackPlugin 提供了一個 options.publicPath 的 api,可以爲css單獨配置 publicPath 。
更改 build/utils.js 文件中 ExtractTextPlugin 插件的options 配置:

 publicPath: '../../', 

if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    publicPath: '../../',         // 注意配置這一部分,根據目錄結構自由調整
    fallback: 'vue-style-loader'
  })
} else {
  return ['vue-style-loader'].concat(loaders)
}

 

鏈接:https://www.jianshu.com/p/0d8883f339f5
 

'@/'路徑和'./'路徑是什麼意思

在vue項目中,我們常遇到以下路徑引用的方式:

@import './common/var.scss';

@import '../../scss/common/var';

@import '~@/scss/common/var';

其中, 
* ./ 表示當前目錄下 
* ../ 表示父級目錄下 
* @/ 是webpack設置的路徑別名,代表什麼路徑,要看webpack的build文件夾下webpack.base.conf.js裏面對於@是如何配置

resolve: {
    // 路徑別名
    alias: {
      'public': path.resolve(__dirname, '../public'),
      'vue': 'vue/dist/vue.js',
      '@': path.resolve('src'),
    }
  },


上述例子 @/ 代表着到src這個文件夾的路徑。

原文:https://blog.csdn.net/qq_28319203/article/details/81004836 
 

v-for

:key提高性能,保障每項key值不同

v-if和v-show

v-show = true時顯示,false時是在標籤內加入一個display=none,不是刪除這一標籤。

<!--v-show是改變div標籤中的style屬性值display:none。適合多次顯示隱藏,性能更高-->

<!--v-if是將hello world從div標籤中刪除然後在新增-->

 

vue 打包上線後 css3漸變屬性丟失的問題解決方案

 /*! autoprefixer: off */
        background: -webkit-gradient(linear, center bottom, center top, from(#146b22), to(#54e475));
        background: -webkit-linear-gradient(bottom,#146b22,#54e475);
        /* autoprefixer: on */
        background: -moz-linear-gradient(bottom,#146b22,#54e475);
        background: -o-linear-gradient(bottom,#146b22,#54e475);
        background: linear-gradient(bottom,#146b22,#54e475);

使用花生殼vue返回 invalid host header

問題:使用花生殼返回304,invalid host header

原因:新版的webpack-dev-server出於安全考慮,默認檢查hostname,如果hostname不是配置內的,將中斷訪問。

解決:webpack.dev.conf.js添加配置 disableHostCheck: true,

devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
    },
	disableHostCheck: true,
  },

原文:https://blog.csdn.net/renzhehongyi/article/details/80953319 
 

vue項目讓局域網能訪問

No 'Access-Control-Allow-Origin' header is present on the requested resource.'Ajax跨域訪問解決方案

1.我的項目路徑是http://192.168.0.234:4864/#/login 端口爲4864 
然後我設置了新的入站規則爲4864

解決辦法 
vue的配置文件config下面的index.js把host改成0.0.0.0就行了 

vue的config

參考:https://blog.csdn.net/qq_32340877/article/details/79738949

 

Vue項目中,防止頁面被縮放和放大

<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />

vue組件中使用iframe元素的方法示例

坑:href必須是帶http請求頭的地址

參考:http://www.php.cn/js-tutorial-382515.html

background-image 打包路徑問題

重點:修改打包後的路徑,不然圖片不展示

https://www.cnblogs.com/qiuyueding/p/8953396.html

npm install --save 與 npm install --save-dev 的區別

npm install -S -D -g 有什麼區別

 在安裝 npm 包時,有兩種方式把依賴包信息寫入 package.json 文件,一種是npm install --save,會把依賴包 dependencies,

另一個是 npm install --save-dev,則寫進devDependencies 

-D 即  --save-dev 是你開發環境依賴的東西

 -S 即  --save 是你線上環境依賴的東西

你開發一個前端項目,在項目中你需要使用gulp構建你的開發和本地運行環境,這時你就要放到dependencies裏。gulp是你用來壓縮代碼,打包等需要的工具,程序實際運行的時候並不需要,所以放到dev裏就ok了。

你寫程序要用element-ui,生產環境運行項目時肯定要用到element-ui,這時element-ui就應該安裝到dependencies中去。

效果:
單獨執行npm install的時候,會同時安裝devDependencies和dependencies字段中的依賴包,

當使用npm install - -production 或者註明NODE_ENV爲production時,只會安裝dependencies中的依賴包。

使用原則:

運行時需要用到的包使用–save,否則使用–save-dev。

 

npm 常用命令 查看版本、安裝、卸載

npm list  // 查看本地已安裝模塊清單
npm list [packageName] // 查看本地已安裝模塊版本
npm info [packageName] //查看模塊的詳細信息 包括各版本號等
npm view [packageName] version // 查看模塊遠程最新版本
npm view [packageName] versions // 查看模塊遠程所有版本

npm install [packageName] //安裝模塊
npm install [packageName]@xxx.xx //安裝模塊的指定版本
npm install [packageName]  -g //全局安裝模塊
npm install [packageName] --save 安裝好後寫入package.json的dependencies中(生產環境依賴)
npm install [packageName] --save-dev 安裝好後寫入package.json的devDepencies中(開發環境依賴)

npm uninstall [packageName] // 刪除模塊
npm uninstall [packageName] -g //卸載全局模塊
npm uninstall [packageName] --save  // 刪除模塊,同時刪除模塊留在package.json中dependencies下的對應信息
npm uninstall [packageName] --save-dev  // 刪除模塊,同時刪除模塊留在package.json中devDependencies下的對應信
 

拷貝相同項目npm run dev運行報錯

錯誤提示:webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

解決:原因是因爲你的node_modules有意外改動,導致依賴庫不完整。 
刪除項目下的node_modules,在你的項目目錄下,重新執行npm install,這會重新生成node_modules, 
執行npm run dev. 

參考:https://blog.csdn.net/m0_37948170/article/details/80694229

。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章