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({}),
                ],
            },
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章