vue部分知識記錄

ps: 一直總結在電腦上vue簡單知識點,今天加班更新下,錯誤之處歡迎大家指導

MVVM模式

  • Model: 代表數據模型, 數據和業務邏輯都在model層中定義
  • View: 代表ui視圖,負責數據的展示
  • ViewModel: 負責監聽Model中數據的改變並且控制視圖的更新, 處理用戶交互操作

安裝vue

vue init webpack my-project4

 vue init webpack-simple //簡單版,需配置
 //注意: 安裝默認沒有添加, 模擬器下會出現, 如6s下 980*1743, 需添加以下meta
 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1">

常用

npm i style-loader css-loader -D
npm i file-loader url-loader -D
npm install less less-loader -D
npm install node-sass sass-loader -D
npm install axios -S
npm install vue-lazyload -D
npm install moment -S
npm install vue-router -S

vant配置

npm i vant -S


# 安裝 babel-plugin-import 插件
npm i babel-plugin-import -D.babelrc中配置
["import", {
    "libraryName": "vant",
    "libraryDirectory": "es",
    "style": true
}, "vant"],
    "syntax-dynamic-import"   //按需加載用

ES6 轉 ES5

1、es6 轉 es5【藉助babel】
參考:https://babeljs.cn/docs/setup/#installation

1.1、安裝包  npm i babel-core babel-loader babel-preset-env -D

1.2、在webpack.config.prod.js的module中配置
	{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }

1.3、在項目根目錄創建一個.babelrc的文件,裏面寫上
    {
        "presets": ["env"]
    }

vue-cli相關配置

省略後綴

配置:build--->webpack.base.conf.js
	extensions: ['.vue', '.js', '.json', '.scss' ,'*'],

按需加載

npm i babel-plugin-syntax-dynamic-import -D

配置:.babelrc文件
"plugins": [
    "syntax-dynamic-import"
]

//路由中使用
const Foo = () => import('./Foo.vue')

圖片路徑問題

配置:config--->index.js
	build: {
		assetsPublicPath: './',  //圖片路徑, 注意加 .
		productionSourceMap: false,  //不生成map文件
	}

打包後背景圖片不顯示

配置:build--->utils.js
	if (options.extract) {
	  return ExtractTextPlugin.extract({
		use: loaders,
		publicPath: '../../',  //新增publicPath, 解決背景圖片無法顯示問題
		fallback: 'vue-style-loader'
	  })
	} else {
	  return ['vue-style-loader'].concat(loaders)
	}

vue快速原型開發 | 環境配置

官方文檔

環境配置

  1. 安裝 Node.js 全部使用默認的設置,下一步即可

  2. 打開命令行工具,輸入命令 node –v 以及 npm -v 檢查是否安裝成功

  3. 通過命令 npm install -g @vue/cli-service-global安裝一個小工具

運行文件

  1. 保證 環境配置 成功之後

  2. .vue 文件所在的路徑下打開終端 輸入 vue serve 文件名

  3. 等待 解析,然後在瀏覽器訪問出現的地址 即可

  4. node版本

注意:

  1. template中必須有一個根節點

  2. script 中的 data 寫成函數,內部返回一個對象

  3. 如果要使用寫好的樣式,直接 import 即可

filter

刪除數據, 過濾

//應用場景: 刪除數據過濾 就不用再次請求接口更新數據列表
this.collectData = this.collectData.filter(item => item.goods_id !== instance.goodsId);

//demo
let params = {goods_id:  instance.goodsId}
 collectStauts(params).then((response) => {
     this.fav = response.data.fav;
     if(response.data.fav == false) {
         this.collectData = this.collectData.filter(item => item.goods_id !== instance.goodsId);
         this.$toast('刪除成功');
     }
})

*號代替手機號中間4位

// 全局  main.js
Vue.filter('fmt',(val)=>{
    return `${val.substring(0,3)}****${val.substring(val.length-4)}` 
})

// 使用
<li>轉賬賬戶:{{mobile | fmt}}</li>

保留兩位小數

// 全局
Vue.filter('twoNum', (value) =>{
    value = Number(value);
    return value.toFixed(2);
})


// 局部
filters: {
    function test(val, n = 2) {
	    return (val / 100).toFixed(n);
    }
}

相關插件

jQuery

npm i jquery -S
	配置: build--->webpack.dev.conf.js 或 prod 根據需要
	new webpack.ProvidePlugin({
		$: "jquery",
		jQuery: "jquery"
	})

圖片壓縮

npm i imagemin-webpack-plugin -D 壓縮圖片
	配置: build---> prod.config.js
	
	const ImageminPlugin = require('imagemin-webpack-plugin').default

	/ 12/4  壓縮圖片
    new ImageminPlugin({
        disable: process.env.NODE_ENV !== 'production', // Disable during development
        pngquant: {
            quality: '95-100'
        },
        gifsicle: {
            optimizationLevel: 2,
            interlaced: true
        },
        optipng: {
            optimizationLevel: 4,
        },
        jpegtran: {
            progressive: true
        }
    })

lrz

引入


//圖片上傳   lrz

  /*
  引入外部上傳壓縮圖片js
  第一:在webpack.base.conf.js的module.exports中resolve中進行引用:
  第二:在 alias中加入  'lrz':resolve('src/assets/uploadjs/lrz.bundle.js'), 加別名
  第三:在組件中引入lrz
   */
   
  resolve: {
    extensions: ['.vue', '.js', '.json', '.scss' ,'*'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'lrz':resolve('src/assets/uploadjs/lrz.bundle.js')
    }
  },
  
  
 # 注意: 引入 all的文件兼容性好

import lrz from 'lrz'  //引入別名

使用

<div class="headBox">
                <img :src="userInfoList.avatar" alt="" v-if="userInfoList.avatar !=''">
                <img src="../../assets/images/icon/default.png" alt="" v-else>
                <input class="form-control input1" type="file" accept="image/*" @change="chooseFile($event)">
                <p>點擊更換頭像</p>
            </div>


data() {
    return {
        config: {  //壓縮圖片控制
            width: 60,
            height: 60,
            quality: 0.6
        },
        file_data: '', //保存返回文件流
        base64Data: {}
    }
},
   
methods: {
	//change事件,得到file文件
    chooseFile(e) {
        var self = this
        var file = e.target.files[0];
        this.file_data = file;
        lrz(file, self.config).then(function (rst) {
            //返回是base64格式
            // self.base64Data = rst.base64; //這裏使用了修改後後端返回的圖片,調接口
            self.updateHead();
        }) .catch(function (err) {
            this.$toast('修改失敗');
        })
    },
    updateHead() {
        //這裏使用表單提交
        let params = new FormData() // 創建form對象
        params.append('avatar', this.file_data)

        // console.log('updateHead',this.file_data);
        // let params = {
        //     avatar: this.file_data
        // }
        
		//請求接口修改圖片
        this.axios.updateHeadImg(params).then((response) =>{
            if(response.data.code == 0) {
                // this.userInfoList.avatar = this.base64Data;
                 //圖片使用用戶上傳後臺返回, 清晰度高些
                this.userInfoList.avatar = response.data.data;
                this.$toast('修改成功');
            }else {
                this.$toast(response.data.msg);
            }
        })
    },
 }

vue-lazyload

//安裝
npm i vue-lazyload -D

// main.js中引用
import VueLazyLoad from 'vue-lazyload'

Vue.use(VueLazyLoad,{
    loading: require('./assets/images/icon/lazy.jpg'),
    error: require('./assets/images/icon/lazy.jpg'),
    preLoad	: 1.3
})

// 使用 把scr替換成 v-lazy="" 即可
 <img v-lazy="index(goods.projectPictures)" alt="">

moment

//安裝
npm i moment -S

// main.js中引用
import moment from 'moment'

//全局過濾器
Vue.filter('dateFmt',(input,formatString="YYYY-MM-DD")=>{
    // const lastFormatString = formatString || "YYYY-MM-DD"
    return input==''? '' :moment(input).format(formatString)
})

// 使用
<div>{{time | dateFmt('YYYY-MM-DD HH:mm:ss')}}</div>

使用默認圖片替代異常圖片

 <img :src="imginfo(image.img)" :onerror="errpic" @click="onClickview(image.activityUrl)"/>
    
 data() {
     return {
         errpic: 'this.src="' + require('../../assets/images/index/banner_place.jpg') + '"',
     }
 },

better-scroll

api文檔

官方案例

1. npm better-scroll -S

2. import BScroll from 'better-scroll';
   Vue.prototype.$BScroll = BScroll;(可忽略)

3.
<div class="wrapper">
  <ul class="content">
    <li>...</li>
    <li>...</li>
    ...
  </ul>
  <!-- you can put some other DOMs here, it won't affect the scrolling -->
</div>

demo

<template>
    <div class="ordered">
         <div class="vHeader" :class="searchBarFixed == true ? 'isFixed' :''" v-show="isShow">
            <div class="vHeader-left">測試一</div>
            <div class="vHeader-right">測試二</div>
        </div>

        <div class="list-wrapper" ref="listWrapperL">
            <ul>
				<li>
            		lorem
				</li>
				<li id="boxItem" ref="boxItem">
					滾動到此位置固定
				</li>
				<li> 
				   
				</li>
					lorem
				</li>
            </ul>
        </div>

    </div>
</template>


<script>
  import axios from 'axios'
  import BScroll from 'better-scroll';

  export default {
    data(){
      return{
          isShow: false,
          searchBarFixed: false,
          scrollY: '',
      }
    },
    created () {
        this.initScoll();
       
    },
    methods: {
       initScoll() {
           this.$nextTick(()=>{
				if(!this.listScroll) {
					this.listScroll=new BScroll(this.$refs.listWrapperL,{
						probeType: 3,
                        scrollY: true,
                        click: true,
                        useTransition:false,  // 防止iphone微信滑動卡頓
                        bounce:true,
                        momentumLimitDistance: 5
					});
				
					this.listScroll.on('scroll', (pos) => {
						// console.log('pos.x-->'+pos.x + '====pos.y-->' + pos.y)
						// var boxTop = document.querySelector("#boxItem").offsetTop;
						var tops = this.$refs.boxItem.offsetTop;
						// console.log('boxTop===?'+boxTop);
						// 使用abs絕對值(否則 pos.y拿到值是負數)
						this.scrollY = Math.abs(Math.round(pos.y));
						console.log(this.scrollY);
						if(this.scrollY > tops) {
							console.log("我進來了》》》");
							this.isShow = true;
						}else {
							this.isShow = false;
						}
					})
				}else {
					this.listScroll.refresh()
				}
            });
       }
    }
  }
</script>


<style lang="scss" scoped>
  .ordered {
    .list-wrapper {
      position: absolute;
      width: 100%;
      top: 0px;
      left: 0;
      right: 0;
      bottom: 45px;
      overflow: hidden;
      z-index: 30;
    }

     .isFixed {
		position: fixed;
		background-color: #fff;
		top: 0;
		z-index: 999;
		transition: all 0.5s;
	}
}
</style>

vue-amap

參考

// 安裝
npm install vue-amap --save

// main.js
import VueAMap from "vue-amap";
import { lazyAMapApiLoaderInstance } from 'vue-amap';
Vue.use(VueAMap);

VueAMap.initAMapApiLoader({
    key: '88b10ee2745229c3628156c5b63862de',
    plugin: ['AMap.Geolocation', 'AMap.Geocoder', 'AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor'],
    uiVersion: '1.0', // ui庫版本,不配置不加載,
    // 默認高德 sdk 版本爲 1.4.4
    v: '1.4.4'
});

//使用見文檔

vue分享微信、朋友圈

參考文檔

//分享微信、朋友圈等

// 安裝
npm install weixin-js-sdk --save

// 組件引入
import wx from 'weixin-js-sdk'
 // 使用demo

shareWx() {
    // alert(encodeURI(location.href.split('#')[0]));
    let params = {
        url: decodeURIComponent(location.href.split('#')[0])
    }
    this.axios.getShareSdk(params).then((response) =>{
        console.log("123", response);
        // wx.config(response.data);
        wx.config({
            debug: false, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
            appId: response.appId, // 必填,公衆號的唯一標識
            timestamp: response.timestamp, // 必填,生成簽名的時間戳
            nonceStr: response.nonceStr, // 必填,生成簽名的隨機串
            signature: response.signature,// 必填,簽名,見附錄1
            jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'updateAppMessageShareData', 'updateTimelineShareData'] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
        });



        /**
         * 通過ready接口處理成功驗證
         * config信息驗證成功後會執行ready方法
         * 需在用戶可能點擊分享按鈕前就先調用
        */
        wx.ready(function() { //
            let tel = getStore('account');  //從本地獲取                         

            // let imgs = 'https://common.cnblogs.com/images/wechat.png',
            let imgs = 'http://cell.yangyueyuan.com/cells/shareImg/linkImg.jpg',
                // links =  window.document.location.protocol + '//' + window.document.location.host + '/cells/?#/share?invite=' + tel;
                // 特別注意: 在安卓設備中微信會自動截取 #號 後面的內容, 導致無法分享, 所以在 #號前面加 ?號解決
                links = 'http://cell.yangyueyuan.com/cells/?#/share?invite='+ tel; // 分享鏈接
            let shareData = {
                title: '美好一天開始啦',
                desc: '好的東西我都想與你一起分享~',//這裏請特別注意是要去除html
                link: links,
                imgUrl: imgs,
            };
			
			// 兼容新老版本
            if(wx.onMenuShareAppMessage){ //微信文檔中提到這兩個接口即將棄用,故判斷
                wx.onMenuShareAppMessage(shareData);//1.0 分享到朋友
                wx.onMenuShareTimeline(shareData);//1.0分享到朋友圈
            }else{
                wx.updateAppMessageShareData(shareData);//1.4 分享到朋友
                wx.updateTimelineShareData(shareData);//1.4分享到朋友圈
            }

			//---------- 以下爲 調試代碼,可忽略 ----------------

            // wx.updateAppMessageShareData({ // 分享給朋友  ,在config裏面填寫需要使用的JS接口列表,然後這個方法纔可以用 
            //     title: '這裏是標題1', // 分享標題
            //     desc: 'This is a test!', // 分享描述
            //     link: 'http://cell.yangyueyuan.com/cells/#/share?invite='+ tel, // 分享鏈接
            //     imgUrl: '', // 分享圖標
            //     success() {
            //         // 用戶確認分享後執行的回調函數
            //         alert("分享給朋友成功1");
            //     },
            //     cancel() {
            //         // 用戶取消分享後執行的回調函數
            //         alert("分享給朋友取消1");
            //     },
            //     fail(res) {
            //         // alert(JSON.stringify(res));
            //     }
            // });
            // wx.updateTimelineShareData({ //分享朋友圈
            //     // title: '標題2', // 分享標題
            //     // link: 'http://www.mall.yangyueyuan.com/mobile',  // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公衆號JS安全域名一致
            //     // imgUrl: '', // 分享圖標
            //     shareData,
            //     success() {
            //         // 用戶確認分享後執行的回調函數
            //         alert("成功2");
            //     },
            //     cancel() {
            //         // 用戶取消分享後執行的回調函數
            //         alert("取消2");
            //     },
            //     fail(res) {
            //         // alert(JSON.stringify(res));
            //     }
            // });
            
        });
        wx.error(res =>{//通過error接口處理失敗驗證
            // config信息驗證失敗會執行error函數
            console.log(res);
        });
    })
},

js-md5

js參考鏈接

npm install js-md5 -D

import md5 from 'js-md5'
//例: 此demo在vue智護項目 攔截器中判斷, 所有post請求md5加密, 拼接格式按後臺要求

if(config.method == "post") {
    //上傳圖像是文件提交
    // if(config.url.indexOf("/order/repair") != -1){
    //   //表單提交
    //   config.data = qs.stringify(config.data);
    // }else{

    // 所有post請求, md5加密  1-3
    config.headers.post["Content-Type"]="application/json";

    let  appkey="VerificationSign2019"

    let listArr = config.data;
    let newkey = Object.keys(listArr).sort();

    //先用Object內置類的keys方法獲取要排序對象的屬性名,再利用Array原型上的sort方法對獲取的屬性名進行排序,newkey是一個數組
    let newObj = {};//創建一個新的對象,用於存放排好序的鍵值對
    for (var i = 0; i < newkey.length; i++) {//遍歷newkey數組
        newObj[newkey[i]] = listArr[newkey[i]];//向新創建的對象中按照排好的順序依次增加鍵值對
    }
    let connects = '';
    for(let item in newObj){
        connects += newObj[item];
    }
    // 拼接格式登錄: 15899999999123456VerificationSign2019  進行加密
    connects += appkey;
    config.data.sign = md5(connects);

    // }
}

v-distpicker 三級聯動

參考: https://www.awesomes.cn/repo/jcc/v-distpicker

手動搭建webpack相關問題

webpack插件

html-webpack-plugin

使用 html-webpack-plugin 創建 & webpack-dev-server 打包運行

3.1.1、安裝 npm i html-webpack-plugin webpack webpack-dev-server -D
3.1.2、在項目根目錄下創建一個參考文件 template.html
		在template中,只需要寫id=app的div
3.1.3、在webpack.config.dev.js中配置plugins
        new HtmlWebpackPlugin({
            template:'./template.html', //參照文件的路徑
            filename:'index.html'
        })

webpack打包之壓縮html

參考配置

//在webpack.config.prod.js中, 對HtmlWebpackPlugin這個裏面增加一個minify的配置
new HtmlWebpackPlugin({
    template: './template.html', //參照文件的路徑
    filename: 'index.html',//最後發佈到node服務器上面的名稱
    minify:{
        removeComments:true,//壓縮註釋
        minifyJS:true,//壓縮js
        minifyCSS:true,//壓縮css
        collapseWhitespace:true,//去除空格
    }
}),

extract-text-webpack-plugin

把項目中用到的樣式文件,從bundle.js中抽離出去

1、安裝包 npm i extract-text-webpack-plugin -D
		
2、導入 extract-text-webpack-plugin

3、在webpack.config.prod.js的module更改原先css的配置
    {
        test: /\.css$/,
            use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: "css-loader"
            })
    }

4、在plugins中寫代碼
	new ExtractTextPlugin("styles.css"),
        

// 注意問題: 目前版本不支持webpack4 
需要安裝: npm install extract-text-webpack-plugin@next
解決參考: https://blog.csdn.net/u011215669/article/details/81269386

打包報錯

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

解決:打包時命令帶上--mode production
//例: package.json
"build": "webpack --progress --config webpack.config.prod.js --mode production"

打包,自動刪除dist插件

npm i clean-webpack-plugin -D

var CleanWebpackPlugin = require('clean-webpack-plugin')

//打包之前,刪除dist目錄,寫在其它插件前面
new CleanWebpackPlugin('dist'),

UglifyJsPlugin壓縮js

// webpack4已經升級不支持這種寫法
new webpack.optimize.UglifyJsPlugin({
    compress: {
        warnings: false, //去掉警告
        drop_debugger: true,
        drop_console: true //去除console.log
    },
    comments: false //去掉版權信息等註釋
})

//注意:webpack4壓縮js, package.json的script裏面寫成 "build": "webpack --mode production", 就自動壓縮了。

webpack4.0提取並壓縮css

參考:

// 提取css並壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const devMode = process.env.NODE_ENV == 'production'

		module: { //配置loader
        	rules: [
                {
                    test: /\.(sa|sc|c)ss$/,
                    use: [
                        devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader',
                        'sass-loader',
                    ],
                },
            ]
        }
    
        plugins: [
            new MiniCssExtractPlugin({
                // Options similar to the same options in webpackOptions.output
                // both options are optional
                filename: devMode ? 'style/[name].css' : 'style/[name].[hash].css',
                chunkFilename: devMode ? 'style/[id].css' : 'style/[id].[hash].css',
            })
        ]
        
        module.exports = {
            // 提取css單獨文件中,並壓縮,  注意: 跟plugins同級
            optimization: {
                minimizer: [
                    new UglifyJsPlugin({
                        cache: true,
                        parallel: true,
                        sourceMap: true
                    }),
                    new OptimizeCSSAssetsPlugin({}),
                ],
            },
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章