移动端项目-信息管理系统
项目依赖
- 项目基本依赖
-
-S
:- vue
- vue-router
-
-D
:- 编译打包:webpack webpack-dev-server webpack-cli
- 模板插件:html-webpack-plugin extract-text-webpack-plugin@next
- CSS编译:css-loader style-loader less less-loader
- JS编译:babel-loader@7.1.5 babel-core babel-cli babel-preset-es2015 babel-preset-stage-0 babel-plugin-transform-runtime
- 图片,字体编译:url-loader file-loader
- VUE编译:vue-loader vue-template-compiler
-
- 本项目使用的其他依赖
-
-S
:- mint-ui axios moment vue-preview
-
- 本地服务器数据库依赖
-
-D
: express cors body-parser formidable mongodb
-
项目结构
- 知识点
- 底部导航栏点击点亮效果
- mui插件中默认在底部导航点击点亮时,会添加一个样式
mui-active
; - 使用router-link作为路由跳转链接,当该项被点亮时,会添加两个样式
router-link-exact-active
和router-link-active
;其中router-link-active
为默认值,可以通过设置路由构造函数中的参数linkActiveClass
来进行全局配置;参考链接:router-link之active-class - 构造函数设置参数,设置在
new VueRouter({})
中,与routes设置相同; - 通过设置
linkActiveClass
默认值,将router-link-active
修改为mui-active
,就可以达到点亮的样式效果;
- mui插件中默认在底部导航点击点亮时,会添加一个样式
- axios组件设置请求和响应的拦截器,设置加载功能
- 代码:
//引入axios import Axios from 'axios'; //Axios:设置默认url参数 Axios.defaults.baseURL='http://localhost:5555';//默认的服务器路由地址 //设置拦截器interceptors,添加loading效果 //请求前拦截 Axios.interceptors.request.use(function (config) { Indicator.open({ text: 'Loading...', spinnerType: 'fading-circle' }); return config; }); //响应后拦截 Axios.interceptors.response.use(function (data) { Indicator.close(); return data; });
- Vue的过滤器filter,用于转换时间格式,使用moment第三方组件
- 项目中配合filter过滤器使用;用于转换日期格式;
- 也可以使用silly-datetime插件来转换日期格式;
- momentjs文档链接:
- 图片懒加载:使用mint-ui中的Lazy load组件
- 使用:在img标签上使用
v-lazy
绑定图片src地址;并引入相对应的样式;
- 使用:在img标签上使用
- 缩略图vue-preview插件的使用
- 参考链接:
- 解析:vue-preview标签上,绑定slides属性,属性值为数组,数组中每个对象,就是遍历后得到的图片;会产生多个元素,其中标签名为figure;
- 思路:
- 1)引入模块,进行参数设定,在发送请求获取数据后,需要对获取的数据进行参数设置
- 参数w,h:指的是放大图的宽高;
- 参数src:指的是大图的地址;
- 参数msrc:指的是小图的地址;
- 代码:
this.$axios.get('/api/getimageinfo/'+orderid) .then(res => { var imgsrcData=res.data.msg; //设置参数 imgsrcData.forEach(item => { item.w=600;//设置大图的宽度 item.h=400; item.src=item.img_src; item.msrc=item.img_src; }); this.imgSrc=imgsrcData; }) .catch(err => { console.log(err); });
- 2)覆盖样式:调整页面布局,覆盖样式;
- 代码:
/*图文分享详情页中图片缩略图样式覆盖*/ .my-gallery figure{ width: 33.33333333%; font-size: 17px; display: inline-block; margin: 0 -4px 0 0; padding: 10px 0 0 14px; text-align: center; vertical-align: middle; background: 0 0 } .my-gallery figure a img{ width: 100%; max-width: 100%; height: auto; }
- 1)引入模块,进行参数设定,在发送请求获取数据后,需要对获取的数据进行参数设置
- mint-ui中loadmore组件
- 1)设置auto-fill为false,解决页面渲染立刻触发loadBottom函数;
- 参考链接:vue+mint-ui 下拉组件loadmore踩坑
- 代码:
<div class="mui-content" style="background-color:#fff"> <mt-loadmore :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" ref="loadmore" auto-fill="false"> <ul class="mui-table-view mui-grid-view"> <li class="mui-table-view-cell mui-media mui-col-xs-6 mui-col-sm-3" v-for="(item,index) in goodsData" :key="index"> <router-link :to="{name: 'goods_detail',params: {orderid: item.order}}"> <div class="mui-media-object" > <img :src="item.img_src"/> </div> <div class="mui-media-body">{{item.title}}</div> <div class="price"> <p><span>¥{{item.sell_price}}</span><span>¥{{item.market_price}}</span></p> <p><span>热卖中</span><span>剩{{item.stock_quantity}}件</span></p> </div> </router-link> </li> </ul> </mt-loadmore> </div>
- 2)给父级组件设置固定高度,并设置属性
overflow: scroll/auto
;.mui-bar-nav ~ .mui-content{ padding-top: 0; padding-bottom: 50px; height: 577px; overflow: auto; }
- 3)解决报错问题:在mint-ui.common.js中添加event.cancelable判断,判断是否取消了关联的默认动作;
- 参考链接:vue项目中使用mint-ui Loadmore组件报错解决方案
- 注意:在控制台中找到报错具体行数,设置bottomMethod中的关联默认动作;
if (typeof this.bottomMethod === 'function' && this.direction === 'up' && this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded && event.cancelable) { event.preventDefault(); event.stopPropagation();
- 1)设置auto-fill为false,解决页面渲染立刻触发loadBottom函数;
- localStorage知识点
- 生命周期:本地浏览器储存,永远不消失;
- localStorage中通过setItem存储的数据类型为字符串格式,所以需要通过
JSON.stringify(obj)
将对象格式转化为字符串格式储存; - localStorage中通过getItem获取的数据类型也为字符串格式,也需要通过
JSON.parse(str)
将字符串格式转化为对象;二者是相互配合使用的; - 若某变量未设置,则获取的值为null;所以在该项目中封装prodTools.js文件中,需要赋值初始值;若获取为null,则赋值为空对象;
- 路由跳转时的钩子函数
- 路由跳转后,渲染实例组件时,在该组件中设置beforeRouteEnter钩子函数,目的是,在路由跳转之前,进行操作;
- 格式:函数内不能通过this获取实例,必须调用next()函数,否则组件不会被渲染;其中to指的是跳转到下一个组件的路由,from指的是从哪一个组件来的路由,获取一个对象,对象中有name,path,query等属性
beforeRouteEnter (to, from, next) { next(vm => { // 通过 `vm` 访问组件实例 }) }
- 本项目中使用在设置相同组件,不同参数的设置,如:根据不同路由跳转,设置不同的title属性;
- 注意:beforeRouteEnter钩子函数中的next()函数在执行时,是在created()函数执行完事之后才执行的;所以在next()中设置变量,在created()函数中不能获取;
- 获取对象中所有的key值
- 代码:
Object.keys(obj)
,调用Object身上的keys方法;获取的为数组,数组元素为对象的key值;
- 代码:
- vue事件中获取事件对象
- 事件绑定时在参数最后面设置
$event
实参; - 事件匿名函数中接收实参;
<template> <button @click="addTo('实参',$event)">点击</button> </template> <script> export default { methods: { addTo(arg,event){ //其中arg为'实参'; //event为事件对象; } } } </script>
- 事件绑定时在参数最后面设置
- v-model只能用在input标签内;
- 购物车页面效果
- 点击加减号,购物数量累加累减,购物车总数量也发生变化;
- 点击左侧按钮,选择商品件数累加,总价跟着变化;
- 点击删除按钮,将该商品删除,购物车跟着改变;
- 购物车页面制作
- 重点:必须操作localStorage的数据,操作并更新数据;拿到实时数据;
- 点击加减号,购物数量要累加累减,需要边界值判断;必须同时更新localStorage中数据,还要触发监听行为,让总数进行累加累减
- 给每个商品前面的按钮添加不同的v-model值,添加到对象中;然后点击按钮
- 购物车中每个商品的购物数量的知识
- vue项目中页面实时更新,必须是赋值的状态下,改变变量的值,才能更新页面;(待考证)
- 购物数量如果在赋值时通过属性赋值给shopData,则在购物数量变化时,不会更新页面
- 需要通过
vm.$set(target,propertyName/index,value)
来改变属性值;
- 购物车总价中计算属性的应用
- 应用场景:通过监视多个变量的变化,然后计算出一个变量,作为函数的返回值去赋值;
- 购物车项目中:选中的总件数和总价数,可以通过计算属性来监视变量的变化,进而返回数值,赋值显示;
- 在计算属性函数中,遍历每个商品的数据数组,然后判断里面的isPicked属性的布尔值,进而判断是否重新计算;
- 在此项目中,计算属性监视的变量都是商品的数组中的属性,比如按钮值,购买属性等;
computed: { setMent(){ let totalSum=0; let totalNum=0; //遍历shopData,判断isPicked的布尔值,并计算总价和总件 this.shopData.forEach((itemobj)=>{ if(itemobj.isPicked){ totalSum+=itemobj.shopCount*itemobj.sell_price; totalNum+=itemobj.shopCount; } }); return {totalSum, totalNum} } }
- router-view的渐入渐出效果
- 给router-view添加过渡效果,即通过transition来包裹;
- 给transition设置mode属性,使过渡效果有先后顺序;
<template> <!--添加过渡效果--> <transition name="rouview" mode="out-in"> <router-view></router-view> </transition> </template> <style scoped> .rouview-enter-active, .rouview-leave-active{ transition: opacity .5s; } .rouview-enter, .rouview-leave-to{ opacity: 0; } </style>
- 底部导航栏点击点亮效果
- 注意点:
- formidable获取post请求数据时,新建form对象时,必须写在请求函数体内,不能写在外面,否则会出错;
- data中定义变量时,最好定义其数据类型的文件,如[],{}等类型,但需注意的是,在向后台获取数据后,对其赋值时,保证其数据类型要相同;
- 存在异步操作时,不能使用var声明变量,要用let声明变量;let会形成私有作用域;
上传本地文件的两种方式
- from表单自动提交
- form表单需要设置enctype属性,值为:
multipart/form-data
;服务端通过formidable设置获取;
- form表单需要设置enctype属性,值为:
- jquery中ajax发送请求提交数据
- 在vue组件中使用jquery,需要设置webpack.config.js参数;参考链接:如何在Vue中使用jQuery
- 通过创建FormData实例,获取file文件的上传数据,插入到实例中,作为上传的数据;
- ajax发送请求时,需要设置两个参数contentType和processData,设置为false;
- 注意阻止按钮的默认事件,vue中可以添加
@click.stop.prevent
,来阻止冒泡和默认事件;
<template>
<div>
<!--form表单提交文件-->
<form action="http://localhost:5055/filewen" method="post" enctype="multipart/form-data">
<input type="file" name="fromwen" id="filesr"/>
<input type="submit" value="提交" name="btn"/>
</form>
<!--jquery中ajax提交文件-->
<form>
<input type="file" name="wenjian" id="files"/>
<button @click.stop.prevent="toPush">提交数据</button>
</form>
</div>
</template>
<script>
export default {
data(){
return {
}
},
methods: {
toPush(){
var formData=new FormData();
formData.append('myFile',$('#files')[0].files[0]);
//jquery发送ajax请求,获取数据
$.ajax({
type: 'POST',
url: 'http://localhost:5055/filewen',
data:formData,
dataType: 'json',
contentType: false,//不需要头;
processData: false,//不转换数据;
success: (res) => {
console.log(res);
},
error: (err)=>{
console.log(err);
}
})
}
}
}
</script>
<style scoped>
</style>
webpack打包的知识点
- 提取css文件,build后生成独立的css文件
- 插件:
- extract-text-webpack-plugin:若webpack为4.x,则下载时命令
npm i --save-dev extract-text-webpack-plugin@next
; - mini-css-extract-plugin
- extract-text-webpack-plugin:若webpack为4.x,则下载时命令
- 插件:
- 设置hash值作为压缩后的文件名
- js文件:
[chunkhash].js
- 在webpack.config.js中设置位置
output: { path: path.resolve(__dirname,"dist_vendors"), filename: "[name].[chunkhash:6].js",//原来文件的name值拼接到hash上,hash位数为6位; }
- css文件:
[contenthash].js
- extract-text-webpack-plugin在4.x中不能使用该方式,但mini-css-extract-plugin可以使用;
- 参考链接:webpack4.x抽取css【extract-text-webpack-plugin与mini-css-extract-plugin】
- js文件:
- 提取第三方模块,压缩为一个js文件
- 目的:将第三方模块提取出来,避免多次压缩更新;
- 思路:在entry中设置vendors,存储第三方模块,在设置optimization属性,设置commons属性中的name值;
- 参考链接:迁移到webpack4:从webpack.optimize.CommonsChunkPlugin到config.optimization.splitChunk
- 代码:
entry: { main: path.resolve(__dirname,"src/main.js"), vendors: ['vue','vue-router','moment','vue-preview','axios'],//将第三方模块写入; }, optimization: { splitChunks: { cacheGroups: { commons: { name: "vendors",//与entry中相对应; chunks: "initial", minChunks: 2 } } } },
- 去除浏览器控制台警告
- 设置webpack.config.js中的mode参数设置为production;
- webpack打包压缩问题待解决;
- 1)提取第三方模块后,webpack-dev-server运行不能正常运行;
- 2)提取css文件时,hash值使用时会报错;
- 3)设置压缩存储路径时,图片等静态资源的地址发送改变,不能正常获取,待解决;
- 4)路由懒加载问题:不能使用,语法不支持,需要下载插件,待解决;
- 5)压缩混淆代码:添加指定代码后,无效果,不能进一步压缩;
移动端项目-信息管理系统
移动端项目:信息管理系统
1.涉及到的技术栈:
1)vue vue-router构建基本构架
2)webpack压缩打包 webpack-dev-server开发环境测试
3)axios 前端与后台间的数据交互
4)mui mint-ui移动端页面构建 其中mui引入的静态资源 mint-ui下载插件引入
5)其他插件知识:moment转化日期 vue-preview图片预览功能
6)设置后台服务器的插件:
express:构建基本服务器框架
cors:跨域请求设置插件;
formidable:post请求获取数据 图片上传功能;
mongodb:本地数据库存储;
2.项目思路总结
1)顶部通栏 mint-ui
九宫格 mui
底部选项卡 mui =>引入自定义图标iconfont 阿里巴巴矢量图标库
轮播图:mint-ui
2)路由知识:
重定向redirect
路由跳转
params设置
路由嵌套
多视图
3.项目中的知识点
1)底部选项卡点亮效果:设置router-link中的默认点亮类名,配合mui-active使用,完成效果;
2)拦截器interceptor,Axios设置,拦截请求和响应时,设置页面加载效果;
3)过滤器filter,Vue类设置,过滤获取的时间数据,通过moment转化为指定格式的时间;也可以使用silly-datetime
4)mint-ui中的lazy load,图片懒加载设置;只需设置v-lazy绑定变量图片地址;
5)vue-preview移动端图片预览插件的使用;
6)封装两个js文件,一个为子组件传递父组件参数的vue实例,一个为封装的localStorage的操作对象;
7)localStorage本地存储的知识;
8)路由跳转中的钩子函数beforeRouteEnter,在路由跳转前后,进行操作,通过在next()中操作实例
9)给router-view添加过渡动画效果,通过transition包裹,设置样式,但需设置mode参数,规定两个过渡效果发生的先后顺序;
10)购物车总计部分的制作:使用计算属性,遍历整个数据,判断isPicked的布尔值,进行累加,实时更新;
11)图片懒加载功能实现;mui中是在图文列表时,进行的图片懒加载; mint-ui中是在大的图片时使用;