Vue移动端项目-信息管理系统

移动端项目-信息管理系统

项目依赖

  • 项目基本依赖
    • -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-activerouter-link-active;其中router-link-active为默认值,可以通过设置路由构造函数中的参数linkActiveClass来进行全局配置;参考链接:router-link之active-class
      • 构造函数设置参数,设置在new VueRouter({})中,与routes设置相同;
      • 通过设置linkActiveClass默认值,将router-link-active修改为mui-active,就可以达到点亮的样式效果;
    • 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第三方组件
    • 图片懒加载:使用mint-ui中的Lazy load组件
      • 使用:在img标签上使用v-lazy绑定图片src地址;并引入相对应的样式;
    • 缩略图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;
           }
          
    • mint-ui中loadmore组件
      • 1)设置auto-fill为false,解决页面渲染立刻触发loadBottom函数;
         <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判断,判断是否取消了关联的默认动作;
         if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
         this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded && event.cancelable) {
         event.preventDefault();
         event.stopPropagation();
        
    • 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设置获取;
  • 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
  • 设置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
  • 提取第三方模块,压缩为一个js文件
     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中是在大的图片时使用;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335