[总结]vue开发常见知识点及问题资料整理(持续更新)
package.json中的dependencies與devDependencies之間的區(qū)別
–save-dev 和 –save 的區(qū)別
我們?cè)谑褂胣pm install 安裝模塊或插件的時(shí)候,有兩種命令把他們寫入到 package.json 文件里面去,比如:
-
–save-dev 安裝的 插件,被寫入到 devDependencies 對(duì)象里面去
-
–save 安裝的 插件 ,被寫入到 dependencies 對(duì)象里面去
devDependencies 是只會(huì)在開發(fā)環(huán)境下依賴的模塊,生產(chǎn)環(huán)境不會(huì)被打入包內(nèi)。
dependencies 是不僅在開發(fā)環(huán)境使用,在生成環(huán)境也需要。
注:可通過NODE_ENV=developement或NODE_ENV=production指定開發(fā)還是生產(chǎn)環(huán)境。
(webpack)vue-cli構(gòu)建的項(xiàng)目如何設(shè)置每個(gè)頁(yè)面的title
在路由里每個(gè)都添加一個(gè)meta
[{path:'/login',meta: {title: '登錄頁(yè)面'},component:'login' }]鉤子函數(shù):
在main.js中添加如下代碼
router.beforeEach((to, from, next) => {window.document.title = to.meta.title;next() })vue項(xiàng)目中使用axios上傳圖片等文件
首先安裝axios:
1.利用npm安裝npm install axios –save
2.利用bower安裝bower install axios –save
3.直接利用cdn引入
一般情況上傳照片有兩種方式:
- 1.本地圖片轉(zhuǎn)換成base64,然后通過普通的post請(qǐng)求發(fā)送到服務(wù)端。操作簡(jiǎn)單,適合小圖,以及如果想兼容低版本的ie沒辦法用此方法
- 2.通過form表單提交。form表單提交圖片會(huì)刷新頁(yè)面,也可以時(shí)form綁定到一個(gè)隱藏的iframe上,可以實(shí)現(xiàn)無刷新提交數(shù)據(jù)。
這里只講解一下第二種方式:
html代碼:
js代碼:
import axios from 'axios' // 添加請(qǐng)求頭 update (e) { // 上傳照片var self = this let file = e.target.files[0] /* eslint-disable no-undef */ let param = new FormData() // 創(chuàng)建form對(duì)象 param.append('file', file) // 通過append向form對(duì)象添加數(shù)據(jù) param.append('chunk', '0') // 添加form表單中其他數(shù)據(jù) console.log(param.get('file')) // FormData私有類對(duì)象,訪問不到,可以通過get判斷值是否傳進(jìn)去 let config = { headers: {'Content-Type': 'multipart/form-data'} } // 添加請(qǐng)求頭 axios.post('http://172.19.26.60:8081/rest/user/headurl', param, config) .then(response => { if (response.data.code === 0) { self.ImgUrl = response.data.data } console.log(response.data) }) }qs.stringify() 和JSON.stringify()的區(qū)別以及在vux中使用post提交表單數(shù)據(jù)需要qs庫(kù)序列化
qs庫(kù)的npm地址:https://www.npmjs.com/package/qs
功能雖然都是序列化。假設(shè)我要提交的數(shù)據(jù)如下
var a = {name:'hehe',age:10};qs.stringify序列化結(jié)果如下
name=hehe&age=10
而JSON.stringify序列化結(jié)果如下:
"{"a":"hehe","age":10}"
vux中使用post提交表單數(shù)據(jù):
this.$http.post(this.$sign.config.url.loginUrl,this.$qs.stringify({"phone":this.phoneNumber, "vCode":this.loginCode, "smsCode":this.phoneCode }) ) .then(response=>{ console.log(response.data); if(response.data.httpCode == 200){ }else{ } })在firebug中可以看到傳遞的參數(shù):
phone=15210275239&vCode=8vsd&smsCode=1534
在vue中使用axios:
this.$axios.post(loginUrl, {"email": this.email,"password": this.password }, { transformRequest: (data) => { return this.$qs.stringify(data) }, }).then(res => { if(res.data.resultCode == RESULT_CODE_SUCCESS){ console.log('登錄成功'); this.$router.push({name:"home"}) }else{ console.log('登錄失敗'); } }).catch(err => { console.log('登登錄出現(xiàn)錯(cuò)誤'); })?vue中實(shí)現(xiàn)全局的setCookie,getCookie以及delCookie方法筆記
import Vue from 'vue' import Vuex from 'vuex' import VueRouter from 'vue-router' import App from '../component/App.vue' import Login from '../component/Login.vue' import UserInfo from '../component/UserInfo.vue' //狀態(tài)管理 Vue.use(Vuex)//路由 Vue.use(VueRouter)//路由配置 //如果需要加菜單,就在這里添加路由,并在UserMenu.vue添加入口router-link const router = new VueRouter({routes: [{path: '/login',component: Login}, {path: '/user_info',component: UserInfo}] })//Vuex配置 const store = new Vuex.Store({state: {domain:'http://test.example.com', //保存后臺(tái)請(qǐng)求的地址,修改時(shí)方便(比方說從測(cè)試服改成正式服域名)userInfo: { //保存用戶信息nick: null,ulevel: null,uid: null,portrait: null}},mutations: {//更新用戶信息updateUserInfo(state, newUserInfo) {state.userInfo = newUserInfo;}} })//設(shè)置cookie,增加到vue實(shí)例方便全局調(diào)用 Vue.prototype.setCookie = (c_name, value, expiredays) => {var exdate = new Date(); exdate.setDate(exdate.getDate() + expiredays); document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString()); }//獲取cookie Vue.prototype.getCookie = (name) => {var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");if (arr = document.cookie.match(reg))return (arr[2]);elsereturn null; }//刪除cookie Vue.prototype.delCookie =(name) => {var exp = new Date();exp.setTime(exp.getTime() - 1);var cval = this.getCookie(name);if (cval != null)document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();}//vue實(shí)例 var app = new Vue({data: {},el: '#app',render: h => h(App),router,store,watch:{"$route" : 'checkLogin'},created() {this.checkLogin();},methods:{checkLogin(){//檢查是否存在sessionif(!this.getCookie('session')){this.$router.push('/login');}else{this.$router.push('/user_info');}}} })webpack中alias配置中的“@”是什么意思?
如題所示,build文件夾下的webpack.base.conf.js
resolve: {extensions: ['.js', '.vue', '.json'],alias: {'vue$': 'vue/dist/vue.esm.js','@': resolve('src')}}其中的@的意思是:
只是一個(gè)別名而已。這里設(shè)置別名是為了讓后續(xù)引用的地方減少路徑的復(fù)雜度。
webpack proxyTable 代理跨域
webpack 開發(fā)環(huán)境可以使用proxyTable 來代理跨域,生產(chǎn)環(huán)境的話可以根據(jù)各自的服務(wù)器進(jìn)行配置代理跨域就行了。在我們的項(xiàng)目config/index.js 文件下可以看到有一個(gè)proxyTable的屬性,我們對(duì)其簡(jiǎn)單的改寫
proxyTable: {'/api': {target: 'http://api.douban.com/v2',changeOrigin: true,pathRewrite: {'^/api': '' } } }這樣當(dāng)我們?cè)L問localhost:8080/api/movie的時(shí)候 其實(shí)我們?cè)L問的是http://api.douban.com/v2/movie這樣便達(dá)到了一種跨域請(qǐng)求的方案。
當(dāng)然我們也可以根據(jù)具體的接口的后綴來匹配代理,如后綴為.shtml,代碼如下:
proxyTable: {'**/*.shtml': {target: 'http://192.168.198.111:8080/abc',changeOrigin: true} }可參考地址:
webpack 前后端分離開發(fā)接口調(diào)試解決方案,proxyTable解決方案
http-proxy-middleware
如何在 vue 項(xiàng)目里正確地引用 jquery 和 jquery-ui的插件
使用vue-cli構(gòu)建的vue項(xiàng)目,webpack的配置文件是分散在很多地方的,而我們需要修改的是build/webpack.base.conf.js,修改兩處的代碼
// 在開頭引入webpack,后面的plugins那里需要 var webpack = require('webpack') // resolve module.exports = { // 其他代碼... resolve: { extensions: ['', '.js', '.vue'], fallback: [path.join(__dirname, '../node_modules')], alias: { 'src': path.resolve(__dirname, '../src'), 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components'), // webpack 使用 jQuery,如果是自行下載的 // 'jquery': path.resolve(__dirname, '../src/assets/libs/jquery/jquery.min'), // 如果使用NPM安裝的jQuery 'jquery': 'jquery' } }, // 增加一個(gè)plugins plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ], // 其他代碼... }這樣就可以正確的使用jQuery了,比如我要引入Bootstrap,我們?cè)趘ue的入口js文件src/main.js開頭加入
// 使用Bootstrap import './assets/libs/bootstrap/css/bootstrap.min.css' import './assets/libs/bootstrap/js/bootstrap.min'這樣Bootstrap就正確的被引用并構(gòu)建。
在比如使用toastr組件,只需要在需要的地方import進(jìn)來,或者全局引入css在需要的地方引用js,然后直接使用
參考:
-
Managing Jquery plugin dependency in webpack
-
如何在vue項(xiàng)目里正確地引用jquery和jquery-ui的插件
vue-cli webpack全局引入jquery
1.首先在package.json里加入,
dependencies:{"jquery" : "^2.2.3" }然后 npm install
2.在webpack.base.conf.js里加入
var webpack = require("webpack")3.在module.exports的最后加入
plugins: [new webpack.optimize.CommonsChunkPlugin('common.js'),new webpack.ProvidePlugin({jQuery: "jquery", $: "jquery" }) ]4.然后一定要重新 run dev
5.在main.js 引入就ok了
import $ from 'jquery'參考: vue-cli怎么引入jquery
在.vue文件中引入第三方非NPM模塊
var Showbo = require("exports?Showbo!./path/to/showbo.js");參考: exports-loader
vue-cli引入外部文件
在 webpack.base.conf.js 中添加externals
externals 中 swiper 是鍵,對(duì)應(yīng)的值一定的是插件 swiper.js 所定義的變量 Swiper :
之后再在根目錄下的index.html文件里引入文件:<script src="static/lib/swiper.js"></script>
這樣子就可以在需要用到swiper.js的文件里加入這行代碼:import Swiper from 'swiper',這樣就能正常使用了。
參考: https://segmentfault.com/q/1010000005169531?_ea=806312
?vue和mintui-Loadmore結(jié)合實(shí)現(xiàn)下拉刷新,上拉加載 (待優(yōu)化)
mintui是餓了么團(tuán)隊(duì)針對(duì)vue開發(fā)的移動(dòng)端組件庫(kù),方便實(shí)現(xiàn)移動(dòng)端的一些功能,這里只用了Loadmore功能實(shí)現(xiàn)移動(dòng)端的上拉分頁(yè)刷新,下拉加載數(shù)據(jù).
mintui官網(wǎng):http://mint-ui.github.io/#!/zh-cn
PS:有個(gè)坑一定要注意就是注釋里說的iPhone里loadmore和-webkit-overflow-scrolling屬性沖突無法上拉問題
可參考另外一個(gè)插件,沒有使用過,《簡(jiǎn)單靈活且強(qiáng)大的Vue下拉刷新組件:vue-pull-to》
vue非父子組件通信
如果2個(gè)組件不是父子組件那么如何通信呢?這時(shí)可以通過eventHub來實(shí)現(xiàn)通信.
所謂eventHub就是創(chuàng)建一個(gè)事件中心,相當(dāng)于中轉(zhuǎn)站,可以用它來傳遞事件和接收事件.
組件1觸發(fā):
<div @click="eve"></div> methods: {eve() {Hub.$emit('change','hehe'); //Hub觸發(fā)事件 } }組件2接收:
<div></div> created() {Hub.$on('change', () => { //Hub接收事件this.msg = 'hehe';}); }?可參考:vue非父子組件怎么進(jìn)行通信
方式二:
把中轉(zhuǎn)站數(shù)據(jù)存放到根實(shí)例下面,如下:
// 根組件(this.$root) new Vue({el: '#app',router,render: h => h(App),data: {// 空的實(shí)例放到根組件下,所有的子組件都能調(diào)用Bus: new Vue()} })組件1觸發(fā):
<div @click="eve"></div> methods: {eve() {this.$root.Bus.$emit('change','hehe'); } }組件2接收:
<div></div> created() {this.$root.Bus.$on('change', () => { //接收事件this.msg = 'hehe';}); }官方推薦的eventbus 解決方案的缺陷在于, 在數(shù)據(jù)傳遞過程中,兩個(gè)組件必須都已經(jīng)被渲染過。
vue項(xiàng)目中在使用vue-router切換頁(yè)面的時(shí)候滾動(dòng)條怎樣自動(dòng)滾動(dòng)到頂部?
有時(shí)候我們需要頁(yè)面滾動(dòng)條滾動(dòng)到某一固定的位置,一般使用Window scrollTo() 方法。
語(yǔ)法就是:scrollTo(xpos,ypos)
xpos:必需。要在窗口文檔顯示區(qū)左上角顯示的文檔的 x 坐標(biāo)。
ypos:必需。要在窗口文檔顯示區(qū)左上角顯示的文檔的 y 坐標(biāo)。
例如滾動(dòng)內(nèi)容的坐標(biāo)位置100,500:
window.scrollTo(100,500);好了,這個(gè)scrollTop這兒只是簡(jiǎn)單介紹一下,下面我們介紹下veu-router中的滾動(dòng)行為。
使用前端路由,當(dāng)切換到新路由時(shí),想要頁(yè)面滾到頂部,或者是保持原先的滾動(dòng)位置,就像重新加載頁(yè)面那樣。 vue-router 能做到,而且更好,它讓你可以自定義路由切換時(shí)頁(yè)面如何滾動(dòng)。
注意: 這個(gè)功能只在 HTML5 history 模式下可用。
當(dāng)創(chuàng)建一個(gè) Router 實(shí)例,你可以提供一個(gè) scrollBehavior 方法:
const router = new VueRouter({routes: [...],scrollBehavior (to, from, savedPosition) {// return 期望滾動(dòng)到哪個(gè)的位置 } })scrollBehavior 方法接收 to 和 from 路由對(duì)象。第三個(gè)參數(shù) savedPosition 當(dāng)且僅當(dāng) popstate 導(dǎo)航 (通過瀏覽器的 前進(jìn)/后退 按鈕觸發(fā)) 時(shí)才可用。
這個(gè)方法返回滾動(dòng)位置的對(duì)象信息,長(zhǎng)這樣:
- { x: number, y: number }
- { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)
如果返回一個(gè) falsy (譯者注:falsy 不是 false,參考這里)的值,或者是一個(gè)空對(duì)象,那么不會(huì)發(fā)生滾動(dòng)。
舉例:
scrollBehavior (to, from, savedPosition) {return { x: 0, y: 0 } }對(duì)于所有路由導(dǎo)航,簡(jiǎn)單地讓頁(yè)面滾動(dòng)到頂部。
返回 savedPosition,在按下 后退/前進(jìn) 按鈕時(shí),就會(huì)像瀏覽器的原生表現(xiàn)那樣:
scrollBehavior (to, from, savedPosition) {if (savedPosition) {return savedPosition} else { return { x: 0, y: 0 } } }如果你要模擬『滾動(dòng)到錨點(diǎn)』的行為:
scrollBehavior (to, from, savedPosition) {if (to.hash) {return {selector: to.hash}} }我們還可以利用路由元信息更細(xì)顆粒度地控制滾動(dòng)。
routes: [{ path: '/', component: Home, meta: { scrollToTop: true }},{ path: '/foo', component: Foo },{ path: '/bar', component: Bar, meta: { scrollToTop: true }} ]完整的例子:
import Vue from 'vue' import VueRouter from 'vue-router'Vue.use(VueRouter)const Home = { template: '<div>home</div>' } const Foo = { template: '<div>foo</div>' } const Bar = {template: `<div> bar <div style="height:500px"></div> <p id="anchor">Anchor</p> </div> ` } // scrollBehavior: // - only available in html5 history mode // - defaults to no scroll behavior // - return false to prevent scroll const scrollBehavior = (to, from, savedPosition) => { if (savedPosition) { // savedPosition is only available for popstate navigations. return savedPosition } else { const position = {} // new navigation. // scroll to anchor by returning the selector if (to.hash) { position.selector = to.hash } // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { // cords will be used if no selector is provided, // or if the selector didn't match any element. position.x = 0 position.y = 0 } // if the returned position is falsy or an empty object, // will retain current scroll position. return position } } const router = new VueRouter({ mode: 'history', base: __dirname, scrollBehavior, routes: [ { path: '/', component: Home, meta: { scrollToTop: true }}, { path: '/foo', component: Foo }, { path: '/bar', component: Bar, meta: { scrollToTop: true }} ] }) new Vue({ router, template: ` <div id="app"> <h1>Scroll Behavior</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/foo">/foo</router-link></li> <li><router-link to="/bar">/bar</router-link></li> <li><router-link to="/bar#anchor">/bar#anchor</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')在網(wǎng)上查了一下,網(wǎng)友說還可以試試在main.js入口文件配合vue-router寫這個(gè)
router.afterEach((to,from,next) => {window.scrollTo(0,0); });IE9報(bào)vuex requires a Promise polyfill in this browser問題解決
因?yàn)槭褂昧?ES6 中用來傳遞異步消息的的Promise,而IE低版本的瀏覽器不支持。
如圖所示:
解決方法
第一步: 安裝 babel-polyfill 。 babel-polyfill可以模擬ES6使用的環(huán)境,可以使用ES6的所有新方法
npm install --save-dev babel-polyfill
第二步: 在 Webpack/Browserify/Node中使用
在webpack.config.js文件中
把
module.exports = {entry: {app: './src/main.js'} }替換為:
module.exports = {entry: {app: ["babel-polyfill", "./src/main.js"]} };注意:在配置文件中不要使用const,let。在IE9低版本瀏覽器不支持該語(yǔ)法(打包的時(shí)候有可能引入了配置文件的內(nèi)容)。
當(dāng)然還有其它兩種引入方式:
- require("babel-polyfill");
- import "babel-polyfill";
在main.js中監(jiān)聽微信返回按鈕的操作,讓其返回不了
if(from.name == 'staffInfo' && to.name == 'Login'){next({path:'/staffInfo',query:{redirect:from.fullPath}}); }else if(from.name == 'acountFill' && to.name == 'Login'){next({path:'/acount/acountFill',query:{redirect:from.fullPath}}); }啟動(dòng)Vue項(xiàng)目時(shí)提示: [BABEL] ... max of "500KB".
在項(xiàng)目的根目錄下找到 .babelrc 文件,增加 "compact": false ,如:
{"compact": false,"presets": ["env", "react", "stage-0"],"plugins": ["transform-runtime"] }如果不存在則手動(dòng)創(chuàng)建該文件,并填寫內(nèi)容如:
{"compact": false }pdf.js默認(rèn)不顯示電子簽章(數(shù)字簽名)問題解決
1. pdfjs 舊版本
pdf.worker.js 找到
注解上面代碼.
2. pdfjs 新 版本v1.10.88
pdf.worker.js 找到
?后臺(tái)返回pdf的base64編碼到前端預(yù)覽,如果pdf中有中文,顯示有問題解決辦法
有可能是有pdf不支持的字體格式,引入pdf.js的字體試試
const CMAP_URL = 'https://unpkg.com/pdfjs-dist@2.0.489/cmaps/'; pdfjsLib.getDocument({data: pdfData,cMapUrl: CMAP_URL,cMapPacked: true,})?解決Vue引入百度地圖JSSDK:BMap is undefined 問題
export default {init: function (){//console.log("初始化百度地圖腳本...");const AK = "AK密鑰";const BMap_URL = "https://api.map.baidu.com/api?v=2.0&ak="+ AK +"&s=1&callback=onBMapCallback";return new Promise((resolve, reject) => {// 如果已加載直接返回if(typeof BMap !== "undefined") {resolve(BMap);return true;}// 百度地圖異步加載回調(diào)處理window.onBMapCallback = function () {console.log("百度地圖腳本初始化成功...");resolve(BMap);};// 插入script腳本let scriptNode = document.createElement("script");scriptNode.setAttribute("type", "text/javascript");scriptNode.setAttribute("src", BMap_URL);document.body.appendChild(scriptNode);});} }說明:
- 直接使用官網(wǎng)提供的引用地址:http://api.map.baidu.com/api?v=2.0&ak=您的密鑰
- 啟用 callback 參數(shù),異步加載必須使用此參數(shù)才可以生效
- 啟用 https 配置,通過 s=1 參數(shù)實(shí)現(xiàn)
- API版本為2.0,經(jīng)測(cè)試使用,發(fā)現(xiàn)3.0版本在HTTPS環(huán)境下是有問題的,腳本內(nèi)部某些請(qǐng)求固定使用HTTP,無法正常使用。
參考地址:https://segmentfault.com/a/1190000012815739
轉(zhuǎn)載于:https://www.cnblogs.com/moqiutao/p/8017340.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的[总结]vue开发常见知识点及问题资料整理(持续更新)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。