文章目錄
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快速原型開發 | 環境配置
環境配置
-
安裝
Node.js
全部使用默認的設置,下一步即可 -
打開命令行工具,輸入命令
node –v
以及npm -v
檢查是否安裝成功 -
通過命令
npm install -g @vue/cli-service-global
安裝一個小工具
運行文件
-
保證
環境配置
成功之後 -
在
.vue
文件所在的路徑下打開終端 輸入vue serve
文件名 -
等待
解析
,然後在瀏覽器訪問出現的地址
即可 -
node
版本
注意:
-
template
中必須有一個
根節點 -
script 中的 data 寫成函數,內部返回一個對象
-
如果要使用寫好的樣式,直接
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
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
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相關問題
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({}),
],
},
}