「cssrem.rootFontSize」: root font-size (unit: px), 默認爲: 16;
「cssrem.fixedDigits」: px轉rem小數點最大長度,默認:6;
「cssrem.autoRemovePrefixZero」:自動移除0開頭的前綴,默認:true;複製代碼
項目中配置:
css
"cssrem.fixedDigits": 2,//px轉化爲rem保留2位小數
"cssrem.rootFontSize":75//px轉化爲rem基準複製代碼
lib-flexible爲移動端彈性佈局適配解決方案。不少的大公司,如網易,淘寶等,都在用它做爲移動端佈局。html
npm install lib-flexible --save複製代碼
import 'lib-flexible'複製代碼
vue-touch其實封裝了 hammer.js的方法,針對觸屏的6大事件進行監聽。官網。前端
npm install vue-touch@next複製代碼
var VueTouch = require('vue-touch')
Vue.use(VueTouch, {name: 'v-touch'})複製代碼
//左劃 默認渲染爲div data爲參數
<v-touch v-on:swipeleft="onSwipeLeft(data)">Swipe me!</v-touch>
//點擊 渲染爲一個a標籤
<v-touch tag="a" v-on:tap="onTap">Tap me!</v-touch>
//點擊 渲染爲p標籤
<v-touch tag="p" v-on:tap="onTap">Tap me!</v-touch>經常使用的事件有:swiper(滑動事件)、tap(短期內的點擊事件)、press(事件大於tap的按壓事件)複製代碼
swiperleft: function () {
this.$router.push({'path':'/queuehistory'});
}複製代碼
vee-validate爲適用於vue項目中表單驗證插件.引入vee-validate,會更加方便咱們進行表單驗證。 官方網址.vue
npm install vee-validate@next --save
複製代碼
import Vue from 'vue'
import VeeValidate,{ Validator } from 'vee-validate'
import zh_CN from 'vee-validate/dist/locale/zh_CN' //引入中文包,提示信息能夠以中文形式顯示
Validator.addLocale(CN) // 設置提示信息中文方式顯示
Vue.use(VeeValidate, { locale: 'zh_CN'})
複製代碼
Validator.extend('phone',
{ messages:{
zh_CN: field => '請輸入正確手機號'
},
validate: value => {
return /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/.test(value)
}
});
Validator.extend('isCard', {
messages: {
zh_CN: field => '請輸入正確身份證號'
},
validate: value => {
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value)
}
})複製代碼
const dictionary = {
zh_CN: {
messages: {
required: (val) => {
let msg = ''
switch (val) {
case 'ownerPhone':
msg = '手機號'
break
}
msg = msg + '不能爲空哦'
return msg
},
numeric: (val) => {
let msg = ''
switch (val) {
case 'houseShi':
msg = '居室'
break
}
msg = msg + '只能爲數字'
return msg
}
}
}}
Validator.updateDictionary(dictionary)複製代碼
<form class="form" autocomplete="off" @submit.prevent="validateBeforeSubmit">
<div class="form-item">
<input type="number" placeholder="請輸入你的手機號" v-model="params.ownerPhone" v-validate="'required|ownerPhone'" name="ownerPhone">
<span v-show="errors.has('ownerPhone')" class="help is-danger">
{{ errors.first('ownerPhone') }}
</span>
</div>
<button class="form-btn bg-blue" type="submit">登陸</button>
</form>複製代碼
安裝方法java
npm install --save better-scroll;
複製代碼
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- 這裏能夠放一些其它的 DOM,但不會影響滾動 -->
</div>複製代碼
import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper)複製代碼
export default {
methods:{
async getMyBillList() {
const res = await getMyBillList(reqData);
if (res.status.code == "200") {
this._houseScroll(); // 結合接口初始化scroll數據
}else{
console.log("接口調用失敗~");
}
},
_houseScroll(){
this.$nextTick(() => {
if (!this.houseScroll) {
let wrapper = document.querySelector('.wrapper'); // scroll容器
// new Bscroll(),初始化容器;
this.houseScroll = new Bscroll(wrapper,{
scrollY: true,
probeType: 3,
click: true,
pullUpLoad: {
threshold: -100 // 在上拉到超過底部 20px 時,觸發 pullingUp 事件
}
}
);
// 初始化上拉刷新加載更多方法
this.houseScroll.on("pullingUp", () => {
this.pageNo++;
if (this.totalPage >= this.pageNo) {
this.pageNo++; // 經過pageNo增長,加載第二頁的數據
this.getMyBillList();
this.loading = true;
} else {
this.loading = false;
this.loadingOver = true;
}
});
} else {
this.houseScroll.finishPullUp();
this.houseScroll.refresh();
}
});
}
}
}
複製代碼
移動端項目中,在某些機型某些瀏覽器下,存在click事件300ms延遲的問題,影響用戶滿意度。緣由是:從點擊屏幕上的元素到觸發元素的 click 事件,移動瀏覽器會有大約 300 毫秒的等待時間,由於它想看看你是否是要進行雙擊(double tap)操做。webpack
vue項目中,能夠經過引入fastclick第三方依賴包來解決。
ios
安裝方法:git
npm install --save fastclick
複製代碼
使用方法:es6
在main.js中
github
import fastclick from 'fastclick'
fastclick.attach(document.body)
複製代碼
也能夠直接下載fastclick.js,在相應頁面直接引用。
移動端項目,因爲在移動端沒法打開控制檯,因此沒法像pc端chrome控制檯那樣直觀查看console信息;不過咱們可使用
vConsole插件
進行調試。
使用方法以下:
安裝vConsole:
npm install vconsole --save-dev
複製代碼
在main.js中引用並實例化:
import VConsole from 'vconsole';const vConsole = new VConsole(); // 不使用的時候,能夠將這句屏蔽掉;複製代碼
此時可使用console.log
原理:改寫了console.log,重寫了實現,用vConsole代理
結果就會出現如圖 浮動的按鈕,點開以後,就能夠看到裏面的console信息了;
在平時項目的開發環境中,常常會遇到跨域的問題,尤爲是使用vue-cli這種腳手架工具開發時,因爲項目自己啓動本地服務是須要佔用一個端口的,因此必然會產生跨域的問題。在使用webpack作構建工具的項目中,使用proxyTable代理實現跨域是一種比較方便的選擇。
proxyTable相關配置及使用說明:
當咱們用vue-cli構建項目時,須要在config/index.js文件中,找到dev對象下proxyTable對象進行跨域設置,配置以下:
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
cssSourceMap: false,
proxyTable: {
'/api': {
target: 'http://www.abc.com', //目標接口域名
changeOrigin: true, //是否跨域
secure: false, // 容許https請求 pathRewrite: {
'^/api': '/api' //重寫接口
}
}
}複製代碼
proxyTable配置的意思爲:使用字符串"/api"來代替目標接口域名;若是接口地址爲"user/getUserInfo",咱們能夠在全部的接口地址前面加上"/api/"用於設置代理;如:
'http://localhost:8080/api/user/getUserInfo' ===> 'http://www.abc.com/api/user/getUserInfo'複製代碼
若是你不想每次請求地址中都帶有"/api/",則能夠設置
pathRewrite: {
'^/api': '' // 後面可使重寫的新路徑,通常不作更改
}複製代碼
表現結果爲:
'http://localhost:8080/api/user/getUserInfo' ===> 'http://www.abc.com/user/getUserInfo'複製代碼
另一種狀況是,咱們不須要在每一個接口地址前添加"/api/",只須要用接口自己的地址,不須要從新路徑便可。若是接口爲:"/v2/cotton/get_app_list",使用"/v2"作代理;以下:
dev: {
proxyTable: {
'/v2': {
target: 'http://www.abc.com', //目標接口域名
changeOrigin: true, //是否跨域
secure: false, // 容許https請求
// 這裏去掉了從新設置新路徑,由於接口地址自己就是以"/v2/"開頭的;
}
}複製代碼
'http://localhost:8080/v2/cotton/get_app_list' ===> 'http://www.abc.com/v2/cotton/get_app_list'
// http://localhost:8080/v2表示http://www.abc.com複製代碼
默認狀況下,不接受運行在 HTTPS 上,且使用了無效證書的後端服務器。若是你想要接受,修改配置以下:
proxy: {
"/api": {
target: "https://www.abc.com",
secure: false
}
}
複製代碼
/**父組件代碼:**/
<template>
<header-box :title="text"></header-box>
</template>
<script>
import HeaderBox from './header'
export default {
name: 'index',
components: {
HeaderBox
},
data () {
return {
text: '首頁'
}
}
}
</script>
複製代碼
/**子組件代碼**/
<template>
<header>
{{thisTitleTxt}}
</header>
</template>
<script>
export default {
name: 'headerbox',
props: {
text: String
},
data () {
return {
thisTitleTxt: this.text
}
}
}
</script>複製代碼
子組件向父組件傳遞分爲兩種類型。
一、子組件改變父組件傳遞的props(你會發現經過props中的Object類型參數傳輸數據,能夠經過子組件改變數據內容。這種方式是可行的,可是不推薦使用,由於官方定義prop是單向綁定);
二、經過$on和$emit;即子組件中經過$emit()來觸發事件;父組件中經過依附在組價元素上的:on方法來響應事件。
*經過$on,$emit*
**父組件代碼**
<template>
<div id="counter-event-example">
<p>{{ total }}</p>
<!--父組件中經過v-on:key="function"來觸發方法的執行-->
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
import ButtonCounter from './buttonCounter'
export default {
name: 'index',
components: {
'button-conuter': ButtonCounter
},
data () {
return {
total: 0
}
},
methods: {
incrementTotal () {
this.total++
}
}
}
</script>複製代碼
**子組件代碼**
<template>
<button @click="incrementCounter">{{counter}}</button>
</template>
<script>
export default {
name: 'button-counter',
data () {
return {
counter: 0
}
},
metheds: {
incrementCounter () {
this.$emit('increment');// 子組件中經過this.$emit('key',value)觸發事件信號
this.counter++
}
}
}
</script>複製代碼
經過使用一個空的Vue實例做爲中央事件總線。
**main.js**
let bus = new Vue()
Vue.prototype.bus = bus;複製代碼
this.bus.$emit("toChangeTitle","首頁");
複製代碼
mounted(){
this.bus.$on('toChangeTitle', function (title) {
console.log(title)
})
}複製代碼
ref
被用來給元素或子組件註冊引用信息。引用信息將會註冊在父組件的 $refs
對象上。
若是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;若是用在子組件上,引用就指向組件實例:
<div id="app">
<input type="text" ref="input1" v-model="name"/>
<button @click="add">添加</button>
<!-- `vm.$refs.child` will be the child component instance -->
<child-component ref="child"></child-component>
</div>
<script>
export default{
data(){
return {
name:"xiaoming"
}
},
created(){
this.$nextTick(()=>{
console.log(this.$refs.input1.value);
});
},
methods:{
add(){
this.$refs.input1.value = "22"; //this.$refs.input1 減小獲取dom節點的消耗
}
}
}
</script>複製代碼
當 v-for
用於元素或組件的時候,引用信息將是包含 DOM 節點或組件實例的數組。
關於 ref 註冊時間的重要說明:由於 ref 自己是做爲渲染結果被建立的,在初始渲染的時候你不能訪問它們 - 它們還不存在!$refs
也不是響應式的,所以你不該該試圖用它在模板中作數據綁定。
經過在引用的子組件上使用ref屬性實現父組件調用子組件的方法及屬性
在父組件中引用子組件並定義ref
<
v-food
ref="selectfood"></
v-food
>
調用定義在子組件中的方法show
this.$refs.selectfood.show();//同時也能夠調用子組件中的屬性
在vue中使用setTimeout或者setInterval,若是按照在原來js的中方法,如
setTimeout(function(){
this.isFlag = true;
},3000);
複製代碼
會發現data中定義的變量isFlag是獲取不到的;解決方法以下:
import { setTimeout } from "timers";
<script>
export default{
data(){
return {
time:"",
isFlag:false
}
},
methods:{
add(){
clearTimeout(this.time);
this.time = setTimeout(() =>{
this.isFlag = true;
},2000)
}
}
}
</script>複製代碼
methods:{
add(){
let self = this;
clearTimeout(this.time);
this.time = setTimeout(function(){
self.isFlag = true;
},2000)
}
}
複製代碼
咱們會發現利用例子的第一種方法,使用this來獲取變量,會報錯。這就是老生常談的javaScript 的this 的問題。
由於用的一個function(){} 這裏的 獨立的做用域 this指向了全局(這裏是window)並且window裏沒有myFunc這個函數,所報了錯。
使用es6的->寫法,this繼承外部對象,this指向爲vue實例,即(new Vue);
$nextTick 是在下次 DOM 更新循環結束以後執行延遲迴調,鼠標滾動事件須要經過window.addEventListener("scroll",'')進行監聽。
<script>
mounted(){
// 監聽滾動事件
this.$nextTick(function () {
window.addEventListener('scroll', this.needToTop); //滾動事件監聽
});
},
methods:{
needToTop(){
let curHeight = document.documentElement.scrollTop || document.body.scrollTop; // 滾動條距離頂部的距離
let bgareaHeight = this.$refs["bgarea"].offsetHeight; // 背景總高度
let opacity = curHeight/bgareaHeight;
this.$refs["title"].style.background = "rgba(255, 255, 255, "+opacity+")";
this.$refs["title"].style.boxShadow = "0 0 .27rem rgba(204, 204, 204, "+opacity+")";
}
}
</script>
複製代碼
經過new FormData(),建立form對象,經過append向form對象添加數據。
html代碼以下:
<div class="txarea">
<input type="file" class="txfile" name="file" id="upimg" accept="image/*" @change="fileChange($event)">
<p class="tx" @click="chooseType">點擊上傳頭像</p>
</div>
<script>
export default{
methods:{
// 獲取用戶圖像
chooseType() {
document.getElementById('upimg').click();
},
fileChange(e) {
let file = e.target.files[0];
let param = new FormData(); //建立form對象
param.append('file',file,file.name);//經過append向form對象添加數據
let config = {
headers:{'Content-Type':'multipart/form-data'} //添加請求頭
};
this.axios.post(uploadUrl,param,config)
.then(response=>{
// 已經獲取到圖片地址,再調接口,保存到數據庫便可;
let reqData = {
phone: this.loginInfo.phone,
pic:response.data.url // 大圖地址
}
this.setUserInfo(reqData);
})
},
setUserInfo(){ // 保存用戶圖像
...
}
}
}
</script>
複製代碼
應該是 Vue 對函數調用表達式額外用了一個函數作了層包裝。
加與不加括號的區別在於事件對象參數 event 的處理。
不加括號時,函數第一個參數默認爲 event;加了括號後,須要手動傳入 $event 才能得到事件對象。
<template>
<div class="btn-item">
<button class="btn btn-success" @click="sure($event)">肯定</button>
<button class="btn btn-default" @click="quit">取消</button>
</div>
</template>
<script>
export default{
name:'test',
data(){
return {
}
},
methods:{
sure(e){
console.log(e.target);
},
quit(e){
console.log(e.target);
}
}
}
</script>複製代碼
<template>
<textarea class="textArea" ref="textArea" placeholder="輸入正文" v-model="postList.content" @input="setPostContent"></textarea></template>
mounted(){
this.$nextTick(() => {
let textarea = document.querySelector('.textArea');
this.makeExpandingArea(textarea);
});
},
methods:{
setPostContent(){ // 設置正文內容
this.$refs.textArea.style.color = '#666666';
},
makeExpandingArea(el) {
var setStyle = function(el) {
el.style.height = 'auto';
el.style.height = el.scrollHeight + 'px';
}
var delayedResize = function(el) {
window.setTimeout(function() {
setStyle(el)
}, 0);
}
if (el.addEventListener) {
el.addEventListener('input',function() {
setStyle(el)},false);
setStyle(el)
} else if (el.attachEvent) {
el.attachEvent('onpropertychange',function() { setStyle(el)
});
setStyle(el)
}
if (window.VBArray && window.addEventListener) { //IE9
el.attachEvent("onkeydown",function() {
var key = window.event.keyCode;
if (key == 8 || key == 46) delayedResize(el); });
el.attachEvent("oncut",function() {
delayedResize(el);
}); //處理粘貼
}
}
複製代碼
mounted() { this.$nextTick(() => { document.getElementById("postDetail").onscroll = this.scrollBottom; }); }, methods:{ scrollBottom() { // 獲取 滾動高度 滾動距離 當前屏幕高度 let scrollHeight = document.getElementById("postDetail").scrollHeight, scrollTop = document.getElementById("postDetail").scrollTop, clientHeight = this.getClientHeight(); // 獲取離底部的距離 let bottomHeight = scrollHeight - scrollTop - clientHeight; // 傳送滾動到sendComments 組件 this.bottomHeight = scrollTop; // 若是距離底部小於5 請求數據 if (bottomHeight < 5) { this.pageNo++; if (this.totalPage >= this.pageNo) { // 說明還有更多的數據 this.loadings = true; this._getPostCommentList(); // 分頁獲取評論數據;回覆完評論,滾動條會自動到最底部,因此會加載第二頁的數據; } else { this.loadings = false; this.loadingOver = true; } } }} 複製代碼
項目實踐:基於vue2.0 +vuex+ element-ui後臺管理系統
後面會更新第二篇文章:
第二篇文章以下:乾貨分享:vue2.0作移動端開發用到的相關插件和經驗總結(2)
百度地圖api在vue項目中的使用:
vue2.0項目中如何使用百度地圖api
vue2如何給地圖添加房源覆蓋物;
如何給地圖添加自定義定位控件並更換控件的圖標;
如何給地圖添加自定義當前位置定位標註
幾個經常使用的api(地圖縮放,拖拽,獲取當前位置)等功能的實現;
歡迎加入討論組,一塊兒來學習用vue,vuex,element,express,mongodb來構建後臺管理系統;
一塊兒來用項目實戰加深本身對知識的理解。