環境:vue的安裝方式使用vue-cli命令行自動生成一個項目css
已知知識:vue單文件將組件寫在了一個.vue後綴的文件中,有三部分<template> <script> css樣式,在該文件中使用ES6模塊的export導出這個組件的選項,提供其餘組件複用,最後使用webpack打包成一個正常的html+js的文件。
短期內初步掌握了vue、vue-router、webpack、Babel、ES6相關的知識但沒有很好的融會貫通致使有些東西感到迷惑html
困惑:使用webpack隱藏了太多東西,致使初學者初次看到這個vue-cli生成的項目徹底和vue官網提供的基礎教程有一些地方對應不起來,只能隱隱猜到一些東西,在這裏我對關於這個vue-cli構建項目感到一些迷惑的羅列出來前端
問題:vue
new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
這裏el指的是webpack提供的index.html模板的dom id
webpack會將在配置文件配置的主入口的main.js和其餘一些css文件打包成一個[name].js並生成一個index.html的文件,這個index.html文件會引用生成的[name].js,這時候index.html的<div id='app'>和[name].js中vue實例表示的組件<div> id='app'>分開成兩個文件,不會出現編譯錯誤,以前寫在同一個html中因此會引起編譯錯誤
這裏涉及的東西都比較多,在下面羅列須要知道的東西
一、在index.js下面使用了vue.use(Router),這個函數會執行Router這個對象下面的install函數,裏面作了什麼東西不用管,就是知道它是安裝Router,爲了能使用index.js裏面的Routerexport default new Router
就必須必須先安裝,安裝執行的邏輯在Router.install裏面,不是單單import導入Router的js就能夠的
二、index.js 導出的路由對象去哪裏使用了,這點以前很迷惑由於我看不到任何地方經過import導入這個index.js文件。如今在main.js中能夠看到下面一行代碼import router from './router'
在webpack中若是import的是一個目錄,那麼默認導出的是目錄下的index.js文件,注意一點換成其餘名字,那麼就到入不了了
三、爲何要將router做爲一個vue的一個選項。在main.js中發現router做爲一個選項放到了new Vue的參數對象中,這是爲了將router對象註冊到vue的全部組件中,在vue的子組件下能夠經過this.$router進行調用
四、明白了router那麼vuex就更好理解了,如何引入vuex? 在router目錄同級建立一個vuex目錄,在下面增長一個index.js文件,在index.js文件中導入vuex的js,而且須要安裝vuex(若是使用<script>引入cdn,會自動安裝就不須要vue.use,這點官網講得都很清楚),安裝完之後配置vuex的store。 寫好index.js文件之後須要將導出的store在vue實例中註冊,以便讓全部的vue子組件可使用,在main.js中導入vuex目錄(webpack會找到index.js文件)
最後附上兩篇寫的很好的文章 淺談Vue.use 、 關於Vue.use()詳解
它的功能和vue實例上的el和tempalte選項的功能一致,它會代替el和template提供一個操做dom的原生js寫法,關於 render函數第一個參數是 createElement方法,在這個createElement的第二個 參數配置表示建立元素的一些屬性,必須按照vue提供的規則來寫
vue-cli項目中使用了webpack這個框架進行打包,所以可使用它提供的api進行組件的導入,它支持ES六、AMD等導入api實現動態和靜態導入。詳情能夠查看 webpack官網的模塊方法部分,也能夠查看vue官網的 異步組件部分
一、在入口js文件main.js中經過import靜態引入須要的公共樣式
二、在webpack提供的模板index.html中引入(和傳統的引用方式一致)
三、在app.vue中引入<style>@import 'global.css'; / 引入公共樣式/</style>
github上第三方的組件在導入樣式的路徑中帶有~符號的路徑,這個符號表示模塊路徑的根路徑(node-modules),可是在使用webpack打包編譯的時候會在postcss-import裏面拋出一個Module build failed: Error: Failed to find錯誤,這是由於postcss-import不支持~的寫法。通過查找postcss-import的文檔發現有這麼一句描述:it can look into root directory (by default process.cwd()), web_modules, node_modules or local modules,默認查找node_modules,所以把它的~去掉再運行就能夠了
在webpack.config.js中咱們不能使用../ 以及./這種形式的路徑方式,而是經過 path.join 和 __dirname 這種形式來表示路徑,不然會報錯。另外: 在組件中,咱們會引用一些靜態文件,即static下的文件, 這時咱們就不能用 alias 下的配置了,而必須使用通常的配置方式
這篇文章寫得很清楚, Vue.js 定義組件模板的七種方式,看完之後對初學者來講不會再對在.vue文件中寫<template>標籤感到困惑
require(['./my-async-component'], resolve)
這行代碼的resolve方法Vue的註冊組件的api提供了一個function (resolve, reject)
的回調函數來異步定義本身的組件,看到它是否是很眼熟? 沒錯!它就是Promise構造函數中提供的回調函數,咱們只要在異步調用組件成功且返回組件選項的時候調用這個resolve,把組件選項傳遞過去就能夠了。Promise會做爲一個代理器把狀態和關聯的處理操做處理好,固然這裏對返回組件選項的處理操做由vue註冊組件的api提供。上面簡單來講就是使用resolve({/** 組件選項*/template: '<div>I am async!</div>'})
進行註冊組件。那麼有沒有更加簡單的寫法? 可使用 webpack提供的支持AMD的require(['./my-async-component'], resolve)的方法,這個方法會異步去加載第一個參數所提供的組件(可多個),把加載到的組件選項一個接一個的傳遞給resolve做爲參數(這樣就轉換成上面的resolve({/** 組件選項*/template: '<div>I am async!</div>'})
的寫法了)。Vue註冊組件還能夠接受一個Promise的對象,能夠在局部註冊中使用import去返回一個promise對象,以下代碼components: {firstModule: () => import('./FAsynchronousLoader'),secondModule: (resolve) => { require(['./SAsynchronousLoader'], resolve) },
:class="[{'grid_1': true}, [index == 0? 'alpha': ''], [index==navParams.navName.length-1? 'omega': ''], [navParams.clickIndex==index? 'active': ''], 'nav-item']"
vue的樣式能夠是一個數組,數組裏麪包含幾個樣式,好比['樣式一', '樣式2'],若是樣式一須要用條件判斷(好像只能三元表達式)那麼必須用數組包含,好比[條件? '樣式一': '']。也能夠用{}對象形式包含,這時候key做爲你的樣式,value是一個真假值,這個真假的值可使用data選項中定義的變量。 還能夠混合使用,相似上面的代碼中的樣式,須要注意的是無論是數組仍是對象,樣式須要用引號包含,否則的話vue會當作data選項中的變量,要求你用v-bind進行綁定
v-show使用的是display:none 這個元素會讓下面的子元素的動畫失效, v-if是壓根就沒有事先生成dom,從而沒有先後差別的比較,動畫天然不會產生。解決辦法,vue提供了動畫的樣式,參考 《進入/離開 & 列表過渡》
子組件props中的變量綁定的是父組件傳遞的綁定在子組件的屬性變量,只要父組件的這個屬性變量發生改變就會通知子組件的props的對應屬性,讓子組件進行重繪。子組件的這個綁定屬性經過某個操做發生更改之後只須要用this.$emit(事件名)通知父組件綁定在子組件的事件便可,這個事件名能夠隨意定義,父組件只須要在這個事件名後面指定的事件方法中更改傳遞給子組件的屬性變量便可,一旦屬性變量發生更改,子組件會立刻知道並重繪子組件對應的元素
webpack不能將import和module.exports混用,即便在一個DateUtil的js文件中沒有import導入只有一個module.exports導出,在example.vue文件中進行require導入這個DateUtil.js,因爲在example.vue中存在有import導入,仍是會報錯。解決辦法是在DateUtil中採用ES6的導出方法,這裏採用了export default {}的寫法。
還須要注意一點就是使用require進行導出這個DateUtil的時候返回的對象是{default:{test: 'test'}},因此引用時須要下面的寫法let dateUtil = require("./DateUtil") console.log(dateUtil.default.test)
,才能引用到
ref這個元素能夠定義在父組件引用子組件時的標籤上,隨意定義一個名字,好比sub-component,在父組件中經過this.$ref.sub-component就能夠訪問到子組件實例,具體參考 點擊
剛開始看到官網的api文檔(好比這: Model)有點懵。這裏api有兩種,一種是prototype原型上的方法,一種是Model.findById,這裏叫它靜態方法。第一種原型上的方法須要獲得Document實例才能使用(以Model的Api來看)。什麼是Document實例?,能夠是new Model(), 也能夠是具體回調函數返回的Document實例。 第二種靜態方法就更好理解了,它的方法只能經過類名+靜態方法的形式調用,好比Model.findById("{id: product._id}"),知道這些再去看API文檔能夠快速的選擇本身想要的方法進行操做
從java到IOS、Nodejs、Python,文件操做這一塊對本身來講都是難點,不但涉及api廣,並且框架一換各類問題一會兒冒出來,這裏不想說作重複工做爲何作的這麼有挑戰性,只想記錄一下使用multer搭配vue所遇到的坑。
背景:vue頁面上傳多個文件(視頻封面,視頻,專題封面)到nodejs後臺,由nodejs上傳文件到oss上面。剛開始啥也不知道就是幹
一、先後臺分離,不能用form提交,那麼怎麼提交表單數據
二、後臺如何從req中獲取,express.Router存在一個req.files屬性,那麼怎麼解析文件數據
三、這裏調用oss接口屢次,會執行屢次異步操做,那麼我怎麼處理單個文件上傳失敗時數據庫的數據回退以及什麼時候返回的報文給頁面
第一點:經過使用axios框架進行post提交,表單的數據封裝到FormData對象中。
坑一: multer經過文件名(fieldname)獲取req中的文件,這裏這個文件名就是formData的第一個參數。上傳三個文件時使用formData.append(「files」, [文件對象,文件對象,文件對象])是不對的,須要append('files', 文件對象)、 append('files', 文件對象) 才能經過後臺獲取到files數組。這裏最好把append的第一個參數值換成不一樣的fieldname,multer.array([])獲取,這樣作的好處是在後臺能夠區分究竟是那個文件,上傳oss返回的資源url才能保持數據庫對應的字段中
第二點:express4.0已經不支持req.files的取法,須要一箇中間件好比multer,若是上傳單文件就使用multer.single,多文件就使用multer.array. 由於oss能夠經過put方法直接傳遞一個buffer,而req.files[i]....buffer就符合要求。
坑2、oss的sdk返回的接口文檔在哪一個地方,debug後又多了一次錄入數據的操做
坑3、oss外網請求和下行流量都須要收費,只能買個阿里服務器,以服務器來代理外網oss數據請求
第三點、oss支持同步和異步的寫法,同步採用了ES6的generator,異步經過callback把控不住3次上傳後結束的時機,並且太複雜,仍是使用同步的寫法,在function*() {}方法體最後面把三次成功時的數據寫回頁面,若是出現異常在catch裏面作數據的回滾並返回錯誤信息給頁面
坑四:不要在express.router.post(){}方法體後面返回信息,由於存在異步操做,而它無論異步執行完沒有直接就返回報文給頁面了,返回信息由於寫在異步執行成功或者失敗的地方
mongoose官網幾乎沒有講解操做符這個概念致使很迷惑,通過查資料發現操做符的內容在mongodb的 官方文檔中,使用操做符能夠優雅的寫出複雜的查詢,是個好東西。在使用操做符須要注意的一個地方:在聚合表達式中使用操做符的語法是 操做符:表達式, 這裏的表達式使用field path 來訪問變量, 具體查看,須要加一個$符,如$user 內嵌:$user.name
在file的input元素上定義一個ref='fileEl' 將元素的實例綁定到fileEl中,在須要清空的地方使用this.$refs.fileEl.value = ''。 還有一個select也存在這種現象前面這行代碼替換成select無論用.表單問題仍是挺多的,好比select異步獲取數據第一次點擊顯示不出數據,表單清空問題等
最開始認爲:有些方法返回值是文檔對象,有些是文檔對象數組,有些直接就是model對象,官方文檔提供的方法只有一個調用架子,根本沒有寫清楚返回值的具體內容,每次執行出錯了都要dug查看具體返回內容。
慢慢發現:model對象是文檔對象的一個在原型上的擴展,能夠把model對象當作是一個文檔對象,直接使用model去獲取文檔對象中的屬性,關於_id經過debug看到的是ObjectId,這個類型是解決分佈式系統主鍵重複問題,產生一個惟一的主鍵,能夠操做model._id 會直接得到字符串類型的id. 關因而單個model(單個文檔對象),仍是數組,這裏看具體方法,那種語義上的ById方法獲取的確定就是單個model對象,語義上可能會查詢出多條的那麼必定是數組
一、拖拽節點時自動就插入一個節點,而無論後臺是否執行成功,提供的事件函數如何去阻止這個自動插入,而是由後臺執行狀態來控制
二、生成節點不提供一個由用戶控制的惟一性id,它本身存在一個id確實自動生成的,這個和數據庫惟一主鍵關聯不起來
解決:原來el-tree提供了一個node-key的屬性,能夠自定義一個標記節點的惟一鍵值來代替原先的id,這個自定義的變量能夠經過node.key來獲取。
能夠經過vue提供的data來操做樹節點的新增刪除,可是在操做樹節點的新增和刪除時須要涉及到數組和對象,而vue在這兩塊上存在的缺陷,極可能data的數據發生改變可是視圖沒有被渲染,這時候詳細查看 官網說明。使用data操做樹節點而且修改其中一個節點的isLeaf屬性不會發生視圖上的變化,這個問題不是vue的鍋,它確實使用{{}}打印能看到視圖上的變化,找不出緣由,只能經過el-tree提供的node.expend()方法展開
mongoose不容許對同一個文檔同時有2個以上的操做,會報錯,解決就在一個操做執行完的回調函數裏面處理第二個操做,或者避免同一時間操做2個以上
vue對於數組以及對象的更新檢測因爲js的限制致使不會響應到視圖上,數組的操做使用7種變異方法以及數組的從新賦值,對象的新增屬性使用$set方法, 官網詳細說明
使用vue-cli搭建的環境,須要把這插件配置在build/webpack.prod.conf.js裏面(配置在build/webpack.dev.conf.js是不起做用)而後運行npm run build
markdown 編輯器建立markdown語法,內容帶有一些markdown設定的符號,這時候須要用有個插件能解析這些符號轉化成標準的html,這個插件就是marked, 轉化出來的是原生的html語言的內容,這時候就須要用專門針對markdown的css來渲染,使用github-markdown.css來渲染。
單頁面的vue會將全部的.vue文件有webpack打包成一個html,這時候很容易發生樣式滲透問題,上一級的樣式(全局樣式)影響到了下一級的有些html元素,這時候就須要在每一個vue的<style scope></style>加入scope,表示當前引入的樣式僅對當前的vue的<template>裏面的內容有效
看這幾篇文章基本講明白了: Vue-cli中的靜態資源管理(src/assets和static/的區別) 、 config/index配置 、 webpack 打包、 vue-cli靜態資源引用
marked + Vue-markdown + highlight + github-markdown 。步驟使用Vue-markdown插件獲得markdown語法的內容保存數據庫,從數據庫取出使用marked編輯成html插入到頁面。這時候由於內容代碼高亮採用highlight插件,配置到marked中,代碼的marked格式爲,帶有一個具體highlight所支持的語言簡寫(以下圖的JavaScript),marked根據配置的highlight插件去解析選擇具體的渲染,配置代碼以下圖,最後還須要經過github-markdown樣式引入,在須要展示內容的地方指定一個值爲markdown-body的class
![]()
![]()
vue中不支持module.default = {} 和import的混用,因此在自定義的js文件中採用exprot或者export default這種ES6的模塊定義。好比我在個人DateUtil的js文件中定義了一個格式化時間的方法,而後須要導出這個方法:function formatDate (date, fmt) export {formatDate}
導出有默認導出和不默認兩種,這裏不默認導出在vue文件中引入須要注意一點,必需要用{}花括號解構導出的內容,如import {formatDate} from '../util/DateUtil.js'
export中有幾個key那麼在import後面的花括號裏面就可選幾個key,調用經過formatDate()來直接引用其中導出的方法.function formatDate (date, fmt) export default {formatDateOther}
這裏是默認導出,那麼在import中引用就不須要包括花括號,import defaultOption, {formatDate} from '../util/DateUtil.js'
這裏defaultOption表明的是整個默認導出的對象 {formatDateOther}調用經過defaultOption.formatDateOther()進行調用
例如這種如何經過Vue設計,談談本身的想法,設計不分對錯,只分是否反人類。先說說結構以下:文章是導航欄中一個選項,文章下面有專題,專題下面有具體的關於這個專題下的做品。所以每張頁面的位置是固定的,訪問專題頁面,那麼前面一級必定是文章,訪問‘配置文件內容’這個做品那麼前面一級確定就是這個做品所在的專題Spring,而這個具體Spring專題又是來自專題這個頁面,結構很清晰,會變的只不過是具體專題和具體的做品。代碼編寫的話能夠單獨寫一個指示欄組件,經過傳入指示欄位置的數組
indication[{name: '文章',path:'/路由地址'},{name:'專題', path:'/路由地址'}]
讓組件去展現。前面這個數組傳入的是不變的位置,而具體專題和做品的數據是會變的,這時候能夠在請求這篇做品的時候讓後臺返回做品所在的專題名字和具體專題導航要用到的參數以及做品的名字和導航要用到的參數
在控制檯出現一個警告,expected '' , get array, 這種警告須要在父組件傳入prop屬性的時候用引號括起來,並用v-bind綁定,告訴vue這是一個js表達式而不是字符串,具體參考 傳遞靜態或動態 Prop
路由地址不變而僅僅改變路由參數,那麼當前頁面是不會被加載的,那麼可使用watch去監控,相似以下代碼
watch: { '$route' (to, from) { this.loadArticle({nodeId: this.$route.params.nodeId}) this.initIndication() } }
mouseenter mouseover mouseout,這裏有三個事件,其中mouseout是移出沒什麼問題,另外兩個有什麼區別呢。
mouseenter是剛進入監聽的元素的時候只觸發一次,在元素裏面移動的過程當中是不會在觸發。mouseover只要在元素中移動就會不斷的觸發。
情景:通過一段時間學習vue-cli單頁面+node.js的項目搭建,總體後臺功能以及頁面代碼都以最簡單粗暴的方式實現,所以存在不少難以忍受的問題,好比代碼的複用,特別是沒有體現組件化的思想,所以這部分記錄組件化遇到的一些問題
方式:將vue中常常複用到的部分單獨開發成一個.vue文件,同時也抽取公共基礎組件做爲之後其餘項目的複用java
官網的組件父子通訊的章節已經講得很明白,這裏須要注意一點就是在父組件的子組件標籤上指定子組件中props參數的時候不必定就須要加個冒號,加冒號的意思就是v-bind,將父組件的data選項變量綁定好傳遞,不加冒號就是一個靜態常量
父組件傳遞一個backgroud的圖片url給子組件,子組件的css樣式中使用父組件傳遞過來的url值。須要注意
一、關於資源路徑的加載,在template中經過常量指定的資源路徑一概使用相對路徑引用資源(注:這些資源不必定就放到src/assets下面,你能夠根據組件內模塊劃分,層級間有多個assets存放各自組件的資源,只要你使用相對路徑引用,file-loader url-loader這些loader加載器就會本身處理這些路徑,這些加載器處理的路徑指向的是build之後webpack將src的資源合併到dist的存放路徑,也就是說loader會將文件系統路徑處理成url路徑,供web訪問,這兩種路徑須要搞明白)
二、若是template中使用js提供的變量路徑,好比說<img :src="backgroudImg" /> 這時候在backgroudImg指定相對路徑是錯誤的,訪問會報404,處理辦法就是在js中使用 backgroundUrl = require('../logo.png'),使用require後會經過加載器去轉換資源的相對路徑並返回這個資源的url路徑,這時候才能在template的標籤元素裏面使用
三、怎麼把父組件傳遞的背景圖片路徑應用到子組件元素裏面? 這時候須要一個計算屬性,經過require獲取到圖片。一開始在子組件的計算方法中使用require(this.backgroundImg) 這個backgroundImg是props的屬性,結果有個警告require支持表達式而不是變量,這時候我改寫成requie(this.backgroundImg+' ') 結果報找不到模塊(webpack把圖片路徑當作一個模塊來加載,使用url-loader), 排查問題的利器就是刪改,我把this.backgroundImg替換成let obj = '' 發現沒問題,那麼問題出在這個props屬性上,這麼解決呢? 換個思路,由父組件調用require來作圖片路徑的加載,返回的的url傳遞給給子組件,這樣作的好處是不須要在require中使用變量了,也不會報找不到模塊的錯誤了,參考 Vue 爬坑之旅--父組件傳入圖片路徑和路由給子組件
使用lodash產生隨機數 _.random,能夠指定任意範圍。 用該隨機數來給panel組件隨機產生一個背景圖,原理是background-position
vue單頁面有兩個比較容易錯的地方,第一是資源路徑,第二就是路由。 vue-cli生成的項目指定了vue-router做爲前端路由,提供兩種模式,hash以及history。hash是vue-router默認的模式,在瀏覽器中會出現一個#號,hash認爲#後面的路徑隨便你怎麼變都不會刷新頁面,而history 是利用了window中的History對象,經過pushStatus方法改變History Entity,這個方法會將新的進入加入歷史棧,可是不會刷新頁面。所以二者均可以實現SPA頁面只發一次請求,日後頁面都不會刷新。
存在問題(只描述現象不清楚具體原理)
一、hash模式下,按F5刷新,當前子組件mounted觸發, main.js mountd觸發,回到index.html頁面
二、子組件之間跳轉, 子組件import 的js文件中的對象依舊存在,無論跳到那個組件下面,經過F12的控制檯都能查到某個子組件的js中的全局變量(無刷新,單頁面,js文件整合在一塊兒放到index.html頁面上,出現這種問題應該能夠理解)
異步路由使用let ANiuContent = (resolve) => { require(['../components/ExampleContent'], resolve) }
記得要npm install dev 進行重啓才能生效。
css樣式污染:很複雜,經過查看最終生成的html文件的頭文件style列表,從上面的前後順序能夠明白爲何當前頁面的樣式不起做用。須要在當前的vue文件下的style中覆蓋全局樣式中的某一個樣式,使用組件異步就可讓style的優先級變高。 須要修改第三方引入的組件中的樣式的時候能夠再style scope標籤上面再添加一個style不帶scope的樣式,在裏面重寫第三方組件中的樣式,這裏爲何不使用全局樣式? 異步組件化之後全局樣式優先級貌似比組件中的樣式低,組件中的樣式直接覆蓋了全局樣式
nodejs異常不免處理很差,拋出未捕捉的異常致使整個進程中止,這時候不該該使用
process.on('uncaughtException')
,會致使用戶一直得不到返回的結果,nodejs提供了domain和cluster處理,遇到錯誤就會從新開一個進程,並關閉當前進程,向用戶提示錯誤信息。np2也能實現這個的效果
前端視頻插件使用video.js,後臺使用nodejs做爲服務器語言。設計思路:後臺前臺上傳的視頻保存到oss並將objectKey保存到數據庫中。 在播放視頻的時候前臺傳遞ObjectKey到後臺,後臺先從服務器中查找視頻臨時文件夾是否存在這個ObjectKey的文件,若是存在則直接返回臨時文件的路徑給前臺,若是不存在則從oss上下載視頻文件到視頻臨時存放的文件夾中並返回視頻文件路徑給前臺。服務器上的視頻臨時文件夾在凌晨進行定時清理一次保證服務器空間不會被累積的視頻文件佔滿。
簡單理解co的異步函數同步處理的原理,能讀懂下面代碼就夠了
function co (gen) { var it = gen() function go (res) { var ret = it.next(res) recursion(ret) } go() function recursion (ret) { if (ret.done) { return } ret.value.then(go) } } function sayhello (saying) { let promise = new Promise(function (resolve, reject) { setTimeout(function () { resolve(saying) }, 3000) }) return promise } co(function* helloworld () { let result = yield sayhello('a'); console.log(result); console.log(yield sayhello('pretty')) console.log(yield sayhello('code')) })
使用node-schedule插件,具體使用方法參考 定時任務(node-schedule)
請移步參考 MongoDB中對數組元素進行查詢 MongoDB查詢(數組、內嵌文檔和$where)
一、問題、session和cookies怎麼選擇
答、重要信息保存session中,非重要信息保存cookies中
二、問題、nodejs如何使用session
答、express4.0+已經移除session、cookies這種依賴,須要安裝插件,並使用app.use進行session的配置,這篇文章能夠看看 什麼是session、 express-session
三、問題、session保存mongodb中須要注意什麼
答、須要引入插件connect-mongo,這個插件專門處理將session保存到mongodb中,它和mongoose功能不同因此不存在衝突,引入時須要注意,在一些博客中引入是var MongoStore = require('connect-mongo')(express)
,可是版本的緣由須要改爲var MongoStore = require('connect-mongo')(session)
,具體以官網 connect-mongo爲準
四、session只要同一個瀏覽器中打開的req只會在store中保存一個session記錄,saveUninitialized=false,只有初始化的req的session纔會保存,saveUninitialized=true,只要req請求的session沒有存儲就會在store中建立
驗證碼思路:後臺生成一驗證碼圖片返回給前臺輸入,登陸時在後臺將前臺輸入的驗證碼和生成的驗證碼內容進行比較。這裏有如下的問題
一、後臺怎麼保存生成好的驗證碼而且怎麼知道前臺登陸是的驗證碼圖片內容是什麼
答:這裏須要明白session的做用,將生成好的驗證碼保存在session中,每次請求過來都從session中找到這個請求生成的驗證碼內容
二、登陸驗證碼生成插件,這裏使用svg-captcha插件
三、登陸驗證邏輯:連續錯三次及以上顯示驗證碼直到正確登陸後限制消失,如此造成一個週期,具體實現原理在session中記錄請求的登陸錯誤次數,成功後清空
四、驗證碼怎麼獲取:登陸框是一個組件,顯示隱藏使用v-if在登陸組件中完成,這樣作的話在父組件引用這個登陸組件並渲染父組件的時候登陸組件也被渲染,所以只觸發一次登陸組件的mouted。這裏獲取驗證碼在父組件點擊登陸的時候去獲取,獲取的邏輯放到vuex的action中異步完成
使用插件vue-lazyload完成。這裏完成background的懶加載,原先是想用一個v-lazy-container包含,可是須要嚴格指定data-src路徑,這個路徑img標籤的圖片路徑不是background的背景圖片路徑,後面只能按照官網文檔使用v-lazy:background-image。項目中使用的一些背景圖是經過一張大圖中使用background-position的形式移動完成,在v-lazy:background-image後面可使用:style={'background-position': '-30px -30px'}來實現
項目部署
本地電腦是window系統,所以下載一個gitbash的工具實如今window下使用liunx命令而不是window的其它命令,太難記。上傳使用scp命令,上傳時liunx的存放上傳代碼的目錄有權限限制則先使用ls -l查看權限,使用chmod對目錄權限進行配置
linux上先安裝nodejs,這是爲了能用到npm命令,這裏有一點注意解壓好node的時候,須要將node的bin裏面的node以及npm做爲全局變量,實現和簡單將解壓包裏面的具體命令在/usr/local/bin下創建軟鏈接,這時候就能夠全局使用/user/local/bin下的目錄名做爲執行的命令,如/usr/local/bin/npm.軟鏈接的創建必須是絕對路徑,相對路徑會有問題. 查看全局路徑可使用echo $PATH 會發現/usr/local/bin是其中的一個全局路徑
使用pm2插件啓動,如何在liunx上配置pm2請看教程: linux下安裝pm2
能ping通服務器ip,可是端口就訪問不到。能夠查看服務器防火牆,增長服務器防火牆端口,防火牆在centos7上的命令教程請看: Centos 7 systemctl和防火牆firewalld命令。 發現增長了端口仍是不行,這是阿里服務器有個白名單,具體設置教程查看: 阿里雲關閉防火牆端口不能外網訪問
一、安裝mongodb:在官網上找到社區版的liunx安裝版本,選擇完之後在下面能夠看到一個url路徑,在linux上使用wget獲取,解壓之後將mongodb的bin下的常常要操做的命令如:mongod,mongo 使用ln -s在/usr/local/bin下建立,這樣就能夠全局使用命令
二、建立mongodb數據庫的用戶並受權參考: Enable Auth 、 Database Commands¶、 createUser、 Built-In Roles¶ 。mongo 登陸:mongo -u adminUser-p adminPassword --authenticationDatabase='admin' ,若是這裏沒有指定authenticationDatabase 那麼登陸後須要用db.auth('adminUser','adminPassword')進行受權才能操做
三、mongodb數據庫受權補充:mongodb命令行進行受權有兩種,其中一種是mongo -uadminName -p adminPassword --authenticationDatabase "dbname"
前面用戶名,密碼,數據庫要麼就不要雙引號了,要麼就用雙引號括起來,別js敲多了用單引號,這個坑讓我敲了一個晚上的用戶新建刪除登陸的命令,一直被拒絕登陸。新建用戶的時候密碼必定不要帶@(mongodb://yijiebuyi:yijiebuyi@127.0.0.1:27017/admin
)緣由在括號裏有@就會被@後面當成主機名,又是掉坑裏面。在moogoose鏈接路徑裏面要帶着具體的數據庫,別別出心裁用mongoose.connect(uri, {dbName: dbname}).then()
第二個參數給定,否則鏈接的時候報沒權限,在mongodb啓動的命令終端一看居然嘗試鏈接另一個數據庫。要想不掉坑,遵循官方文檔規規矩矩的敲,花費這麼多時間讓本身痛苦以外一切都毫無心義
nginx安裝: nginx安裝,安裝完配置,使用find / -name nginx.conf ,找到這個nginx的配置文件,在本身的服務器上出現了/etc/nginx和/usr/sbin/nginx 在sbin下的是nginx的執行命令,在/etc下的是nginx的配置文件,在這個nginx.conf中,增長下面一段配置,在conf.d目錄下新增一個vue項目的配置文件,能夠簡單配置後臺服務器代理以及nginx關鍵性的配置便可
![]()
篇外話
一個月多一點點,邊學邊作邊查資料,原本想實現一個視頻+博客文章這樣的我的網,在疲憊之餘聽聽來自youtube上下載的喜歡歌曲,可是理想仍是和顯示有誤差,視頻這一塊花了很多時間去實現,在本地帶寬足夠的狀況下仍是沒什麼問題,可是放到雲服務器1g 1g 1mbps的時候發現看視頻以及上傳視頻佔據了整個服務器的帶寬,到最後不得不移除這一模塊,等之後見識足夠多之後再戰視頻模塊。node