环境: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