首页

Webpack:知识点总结以及遇到问题的处理办法

前端达人

文章目录

0.官方文档:

1.webpack概述:

2.webpack的基本使用:

3.在项目中安装和配置 webpack:

4.配置自定义打包的自定义入口和出口:

4.配置自动打包功能:

5.配置生成预览页面功能:

6.配置自动打包相关参数:

7.webpack 中的加载器:

8.loader加载器的基本使用:

9.Vue单文件组件:

10.webpack 打包发布:

11.以上所有配置 webpack.config.js 截图


1.webpack概述:
webpack是一个流行的前端项目构建工具(打包工具) ,可以解决当前web开发中所面临的困境
webpack提供了友好的模块化支持,以及代码压缩混淆、处理js兼容问题、性能优化等强大的功能,从而让程序员把工作的重心放到具体的功能实现上,提高了开发效率和项目的可维护性

2.webpack的基本使用:
2.1:打开终端运行命令 npm init -y 初始化包管理配置文件 package.json

2.2:新建 src 源文件目录(里面放程序员自己写的代码比如 html css js images …)

2.3:如果需要引入 jquery 库 终端运行以下命令npm install jquery -S 安装 jquery

自己在src文件夹中创建 index.js 引入下载的jquery包import $ from 'jquery'

3.在项目中安装和配置 webpack:
3.1:终端运行 npm install webpack-cli -D 命令,安装webpack相关的包

这里要注意一个问题 : package.json 和 package-lock.json 文件里的名字默认为 “name”=“webpack”,在配置 webpack-cli 之前要把name 改成 其他名字 比如 “name”=“webpack_” 不然的话为出现无法安装的问题

具体可点击这里 Webpack依赖包安装问题解决方案
3.2:在项目根目录中 ,创建名为 webpack.config.js 的 webpack 配置文件

3.3:在 webpack.config.js 中,初始化一下基本配置

建议选择 development (打包速度快,体积大),项目上线是才改成 production (如果选择production会进行代码的压缩和混淆,打包速度慢,体积小)

3.4:在package.json中的 script节点 新增一个dev脚本 值为 webpack ,就可以实现打包功能



  • 在终端运行命令:npm run dev 就可以打包 默认打包成main.js在 dist文件夹中

  • src自己新建的index.html 中引入打包后的 js




vue,vant,使用过程中 Swipe 轮播自定义大小遇到的坑

前端达人

今天讲一下使用vant Swipe 轮播控件过程中遇到的问题

主要是使用swiper自定义的大小的时候,宽度适应不同分辨率的移动设备

适应宽度的同时还需控件的正常使用


先看一下需要实现的功能,

微信截图_20200417142351.png

微信截图_20200417142429.png

一个简单的轮播图,但是每个轮播的宽度需要低于100%,使第二个轮播的van-swipe-item可以展示到第一个位置一部分



这时我们再去vant的文档查看一下控件

微信截图_20200417142821.png


刚好有一个自定义控件大小的可以使用,完美解决了我们的问题


当我们使用控件之后


 <van-swipe :loop="false"  @change="onChange" :width="350">
        <van-swipe-item v-bind:id="item0"><div class="swipe0">
            <div class="contion">

                <p class="title">家中有事,申请请假一天</p>
                <p class="title1"><span class="rice"></span>部门经理核审中</p>
                <p class="time">03.8 &nbsp;&nbsp;&nbsp; 14.25</p>
                <p class="type">放假申请</p>
            </div>
            <img src="../../assets/images/index/xx/fangjia.png">

        </div></van-swipe-item>
        <van-swipe-item ><div class="swipe1"></div></van-swipe-item>
        <van-swipe-item ><div class="swipe2"></div></van-swipe-item>
        <template #indicator>
            <div class="custom-indicator">
                {{ current + 1 }}/3
            </div>
        </template>
    </van-swipe>



发现功能可以使用,但是再 iPhone8/7 plus  以及iPhone5/se 等分辨率下出现了宽度固定而不适应的情况,

微信截图_20200417143329.png

微信截图_20200417143349.png


简单来说,我们把van-swipe-item宽度控制在了80% 第二个van-swipe-item自然可以展示出来一部分

但是当滑到第二页的时候 由于第一页的宽度还是80% 所以就出现了这样的情况,所以我打算采用

监听 change 事件

动态的改变 滑动到第几页的时候 把当页的宽度变为80% 其他页保持不变,


于是

 <van-swipe :loop="false"  @change="onChange" >
        <van-swipe-item v-bind:id="item0"><div class="swipe0">
            <div class="contion">

                <p class="title">家中有事,申请请假一天</p>
                <p class="title1"><span class="rice"></span>部门经理核审中</p>
                <p class="time">03.8 &nbsp;&nbsp;&nbsp; 14.25</p>
                <p class="type">放假申请</p>
            </div>
            <img src="../../assets/images/index/xx/fangjia.png">

        </div></van-swipe-item>
        <van-swipe-item v-bind:id="item1"><div class="swipe1"></div></van-swipe-item>
        <van-swipe-item v-bind:id="item2"><div class="swipe2"></div></van-swipe-item>
        <template #indicator>
            <div class="custom-indicator">
                {{ current + 1 }}/3
            </div>
        </template>
    </van-swipe>





首先 我们为每个swipe-item添加id



 data(){
            return {
                android: true,
                ios: true,
                iphoneX: true,
                current: 0,
                item0:'item0',
                item1:'item1',
                item2:'item2',
            }
        },
        mounted(){

        },
        methods: {
            onChange(index){
                console.log('当前 Swipe 索引:' + index);
                if(index==1){
                    var div =document.getElementById("item0").style.setProperty('width', '10rem', 'important');
                    var div1 =document.getElementById("item1").style.setProperty('width', '9.3333333rem', 'important');
                    var div2 =document.getElementById("item2").style.setProperty('width', '9.3333333rem', 'important');
                } else  if(index==2){
                    var div1 =document.getElementById("item1").style.setProperty('width', '10rem', 'important');
                    var div0 =document.getElementById("item0").style.setProperty('width', '10rem', 'important');
                    var div2 =document.getElementById("item2").style.setProperty('width', '9.3333333rem', 'important');
                } else  if(index==0){
                    var div =document.getElementById("item2");
                    var div0 =document.getElementById("item0").style.setProperty('width', '9.3333333rem', 'important');
                    var div1 =document.getElementById("item1").style.setProperty('width', '9.3333333rem', 'important');
                }
            },



此外,监听滑动事件,根据滑动到第几页 更改当前页面的宽度,


这样就解决了




Swipe自定义宽度下,同时适应不同分辨率的情况


兰兰设计:前端达人





vue + vuex + koa2开发环境搭建及示例开发

seo达人

写在前面

这篇文章的主要目的是学会使用koa框架搭建web服务,从而提供一些后端接口,供前端调用。
搭建这个环境的目的是: 前端工程师在跟后台工程师商定了接口但还未联调之前,涉及到向后端请求数据的功能能够走前端工程师自己搭建的http路径,而不是直接在前端写几个死数据。即,模拟后端接口。

当然在这整个过程(搭建环境 + 开发示例demo)中,涉及到以下几点知识点。
包括:

  • koa2的知识点
  • node的知识点
  • 跨域问题
  • fetch的使用
  • axios的使用
  • promise的涉及
  • vuex -> state、mutations、actions的使用

第一部分:环境搭建

vue + vuex环境

首先是vue + vue-router + vuex的环境。我们用vue-cli脚手架生成项目,会用vue的同学对这块应该很熟了。

// 全局安装脚手架工具 npm i vue-cli -g // 验证脚手架工具安装成功与否 vue --version // 构建项目 vue init webpack 项目名 // 测试vue项目是否运行成功 npm run dev

因为脚手架生成的vue项目不包含vuex,所以再安装vuex。

// 安装vuex npm i vuex --save

koa2环境

前端项目构建好了,就开始构建我们的后端服务。

首先在你的开发工具(不管是webstorm还是sublime)里新建一个目录,用来搭建基于koa的web服务。

在这里,我们不妨给这个目录起名为koa-demo。

然后执行:

// 进入目录 cd koa-demo // 生成package.json npm init -y // 安装以下依赖项 npm i koa npm i koa-router npm i koa-cors

安装好koa和两个中间件,环境就算搭建完成了。

第二部分:示例开发

搭建环境是为了使用,所以我们立马来写一个demo出来。
demo开发既是一个练习如何在开发环境中写代码的过程,反过来,也是一个验证环境搭建的对不对、好不好用的过程。

后端接口开发

本例中,后端我们只提供一个服务,就是给前端提供一个返回json数据的接口。代码中包含注释,所以直接上代码。

server.js文件

 // server.js文件 let Koa = require('koa'); let Router = require('koa-router'); let cors = require('koa-cors'); // 引入modejs的文件系统API let fs = require('fs'); const app = new Koa(); const router = new Router(); // 提供一个/getJson接口 router
    .get('/getJson', async ctx => { // 后端允许cors跨域请求 await cors(); // 返回给前端的数据 ctx.body = JSON.parse(fs.readFileSync( './static/material.json'));

    }); // 将koa和两个中间件连起来 app.use(router.routes()).use(router.allowedMethods()); // 监听3000端口 app.listen(3000);

这里面用到了一个json文件,在'./static/material.json'路径,该json文件的代码是:

// material.json文件 [{ "id": 1, "date": "2016-05-02", "name": "张三", "address": "北京 清华大学",
}, { "id": 2, "date": "2016-05-04", "name": "李四", "address": "上海 复旦大学",
}, { "id": 3, "date": "2016-05-01", "name": "王五", "address": "广东 中山大学",
}, { "id": 4, "date": "2016-05-03", "name": "赵六", "address": "广东 深圳大学",
}, { "id": 5, "date": "2016-05-05", "name": "韩梅梅", "address": "四川 四川大学",
}, { "id": 6, "date": "2016-05-11", "name": "刘小律", "address": "湖南 中南大学",
}, { "id": 7, "date": "2016-04-13", "name": "曾坦", "address": "江苏 南京大学",
}] 

然后我们是用以下命令将服务启动

node server.js

测试接口是否良好

打开浏览器,输入http://127.0.0.1:3000/getJson。看一看页面上是否将json文件中的json数据显示出来,如果能够显示出来,则说明这个提供json数据的服务,我们已经搭建好了。

前端调用后端接口示例

为突出重点,排除干扰,方便理解。我们的前端就写一个组件,组件有两部分:首先是一个按钮,用来调用web服务的getJson接口;然后是一个内容展示区域,拿到后端返回的数据以后,将其在组件的这块区域显示出来

首先我们看组件文件

<template> <div class="test"> <button type="button" @click="getJson">从后端取json</button> <div class="showJson">{{json}}</div> </div> </template> <script> import {store} from '../vuex' export default { computed: {
          json(){ return store.state.json;
          }
        }, methods: {
          getJson(){
              store.dispatch("getJson");
          }
        }
    } </script> <style scoped> .showJson{ width:500px; margin:10px auto; min-height:500px; background-color: palegreen;
  } </style> 

非常简单,就不多解释了。
然后看我们的vuex文件

import Vue from 'vue' import Vuex from 'vuex';

Vue.use(Vuex) const state = { json: [],
}; const mutations = {
  setJson(state, db){
    state.json = db;
  }
} const actions = {
  getJson(context){ // 调用我们的后端getJson接口 fetch('http://127.0.0.1:3000/json', { method: 'GET', // mode:'cors', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json',
      },
    }).then(function (res) { if(res.status === 200){ return res.json()
      }
    }).then(function (json) { //console.log(typeof Array.from(json), Array.from(json)); context.commit('setJson', Array.from(json));
    })
  }
}; export const store = new Vuex.Store({ state: state, mutations: mutations, actions: actions,
})

ok, 代码撸完了,获取后端数据之前是这样的。

获取后端数据之后是这样的。

说说axios

想要把本demo的fetch改为axios方式,要做的工作有以下几处:
1、安装axios、在vuex文件引用axios

npm i axios import axios from 'axios'

2、将fetch部分代码替换为:

const actions = {
  getJson(context){
    axios.get('/json', { method: 'GET', // mode:'cors', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json',
      },
    }).then(function (res) { if(res.status === 200){ return res.data
      }
    }).then(function (json) { //console.log(typeof Array.from(json), Array.from(json)); context.commit('setJson', Array.from(json));
    })
  }
};

3、又会遇到跨域,在webpack中修改,路径config/index.js文件中添加proxyTable项的配置:

proxyTable: { '/json': { target: 'http://127.0.0.1:3000', changeOrigin: true, pathRewrite: { '^/json': '/json' }
      }
    },

后记

基于vue脚手架搭建的项目,模拟异步取数据,也可以直接在脚手架生成的static文件夹下放置数据,假装是后台拿过来的数据。

不过搭建一个基于express或者koa的web服务,确实也该是一个前端工程师应该掌握的。

OK,以上就是全文了。
如果这篇文章使你有所收获,不胜荣幸。
欢迎点赞,以期能帮助更多同学!

vue实现移动端悬浮窗效果

前端达人

本文讲述,在使用VUE的移动端实现类似于iPhone的悬浮窗的效果。

相关知识点

touchstart 当在屏幕上按下手指时触发

touchmove 当在屏幕上移动手指时触发

touchend 当在屏幕上抬起手指时触发
mousedown mousemove mouseup对应的是PC端的事件

touchcancel 当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档等操作。

效果图

实现步骤

1.html

总结了一下评论,好像发现大家都碰到了滑动的问题。就在这里提醒一下吧。可将该悬浮 DIV 同你的 scroller web 同级。 —- (log: 2018-08-21)

html结构: <template> <div>你的web页面</div> <div>悬浮DIV</div> </template>

<template>
 <div id="webId">
 ...
 <div>你的web页面</div>
 <!-- 如果碰到滑动问题,1.1 请检查这里是否属于同一点。 -->
 <!-- 悬浮的HTML -->
 <div v-if="!isShow" class="xuanfu" id="moveDiv"
  @mousedown="down" @touchstart="down"
  @mousemove="move" @touchmove="move"
  @mouseup="end" @touchend="end"
 >
  <div class="yuanqiu">
  {{pageInfo.totalPage}}
  </div>
 </div>
 ...
 </div>
</template>

2.JS

<script>
data() {
 return {
 flags: false,
 position: { x: 0, y: 0 },
 nx: '', ny: '', dx: '', dy: '', xPum: '', yPum: '',
 }
}

methods: {
 // 实现移动端拖拽
 down(){
 this.flags = true;
 var touch;
 if(event.touches){
  touch = event.touches[0];
 }else {
  touch = event;
 }
 this.position.x = touch.clientX;
 this.position.y = touch.clientY;
 this.dx = moveDiv.offsetLeft;
 this.dy = moveDiv.offsetTop;
 },
 move(){
 if(this.flags){
  var touch ;
  if(event.touches){
   touch = event.touches[0];
  }else {
   touch = event;
  }
  this.nx = touch.clientX - this.position.x;
  this.ny = touch.clientY - this.position.y;
  this.xPum = this.dx+this.nx;
  this.yPum = this.dy+this.ny;
  moveDiv.style.left = this.xPum+"px";
  moveDiv.style.top = this.yPum +"px";
  //阻止页面的滑动默认事件;如果碰到滑动问题,1.2 请注意是否获取到 touchmove
  document.addEventListener("touchmove",function(){
   event.preventDefault();
  },false);
 }
 },
//鼠标释放时候的函数
 end(){
 this.flags = false;
 },
}
</script>

3.CSS

<style>
 .xuanfu {
 height: 4.5rem;
 width: 4.5rem;
 /* 如果碰到滑动问题,1.3 请检查 z-index。z-index需比web大一级*/
 z-index: 999;
 position: fixed;
 top: 4.2rem;
 right: 3.2rem;
 border-radius: 0.8rem;
 background-color: rgba(0, 0, 0, 0.55);
 }
 .yuanqiu {
 height: 2.7rem;
 width: 2.7rem;
 border: 0.3rem solid rgba(140, 136, 136, 0.5);
 margin: 0.65rem auto;
 color: #000000;
 font-size: 1.6rem;
 line-height: 2.7rem;
 text-align: center;
 border-radius: 100%;
 background-color: #ffffff;
 }
</style>

实现好JS逻辑,基本上,问题不大。

本文链接 http://www.luyixian.cn/javascript_show_166242.aspx



再加一点

css之display:inline-block布局

1.解释一下display的几个常用的属性值,inline , block, inline-block

  • inline(行内元素):
    1. 使元素变成行内元素,拥有行内元素的特性,即可以与其他行内元素共享一行,不会独占一行. 
    2. 不能更改元素的height,width的值,大小由内容撑开. 
    3. 可以使用padding上下左右都有效,margin只有left和right产生边距效果,但是top和bottom就不行.
  • block(块级元素):
    1. 使元素变成块级元素,独占一行,在不设置自己的宽度的情况下,块级元素会默认填满父级元素的宽度. 
    2. 能够改变元素的height,width的值. 
    3. 可以设置padding,margin的各个属性值,top,left,bottom,right都能够产生边距效果.
  •  inline-block(融合行内于块级):
    1. 结合了inline与block的一些特点,结合了上述inline的第1个特点和block的第2,3个特点.
    2. 用通俗的话讲,就是不独占一行的块级元素。如图:

图一:1.png

图二:

2.png

两个图可以看出,display:inline-block后块级元素能够在同一行显示,有人这说不就像浮动一样吗。没错,display:inline-block的效果几乎和浮动一样,但也有不同,接下来讲一下inline-block和浮动的比较。

 

2.inline-block布局 vs 浮动布局

    a.不同之处:对元素设置display:inline-block ,元素不会脱离文本流,而float就会使得元素脱离文本流,且还有父元素高度坍塌的效果

    b.相同之处:能在某程度上达到一样的效果

我们先来看看这两种布局:
图一:display:inline-block3.png

图二:4.png

对两个孩子使用float:left,我在上一篇浮动布局讲过,这是父元素会高度坍塌,所以要闭合浮动,对box使用overflow:hidden,效果如下:

>>乍一看两个都能做到几乎相同的效果,(仔细看看display:inline-block中有间隙问题,这个留到下面再讲)

c.浮动布局不太好的地方:参差不齐的现象,我们看一个效果:
图三:

图四:

>>从图3,4可以看出浮动的局限性在于,若要元素排满一行,换行后还要整齐排列,就要子元素的高度一致才行,不然就会出现图三的效果,而inline-block就不会。

 

3.inline-block存在的小问题:

a.上面可以看到用了display:inline-block后,存在间隙问题,间隙为4像素,这个问题产生的原因是换行引起的,因为我们写标签时通常会在标签结束符后顺手打个回车,而回车会产生回车符,回车符相当于空白符,通常情况下,多个连续的空白符会合并成一个空白符,而产生“空白间隙”的真正原因就是这个让我们并不怎么注意的空白符。

 

b.去除空隙的方法:
1.对父元素添加,{font-size:0},即将字体大小设为0,那么那个空白符也变成0px,从而消除空隙
现在这种方法已经可以兼容各种浏览器,以前chrome浏览器是不兼容的
图一:

 

c.浏览器兼容性:ie6/7是不兼容 display:inline-block的所以要额外处理一下:
在ie6/7下:
对于行内元素直接使用{dislplay:inline-block;}5.png
对于块级元素:需添加{display:inline;zoom:1;}

 6.png

4.总结:

display:inline-block的布局方式和浮动的布局方式,究竟使用哪个,我觉得应该根据实际情况来决定的:
a.对于横向排列东西来说,我更倾向与使用inline-block来布局,因为这样清晰,也不用再像浮动那样清除浮动,害怕布局混乱等等。
b.对于浮动布局就用于需要文字环绕的时候,毕竟这才是浮动真正的用武之地,水平排列的是就交给inline-block了。



vue父组件向子组件传值

前端达人

非常简单,相信大家一看就懂

复制到浏览器即可使用,注意别忘了引入vue哦


<div id="app">
    <div>{{pmsg}}</div>
    <menu-item :title='ptitle' :content='ptitle'></menu-item>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
    //父组件向子组件传值-基本使用
    Vue.component('menu-item', {
        props: ['title', 'content'],
        data: function() {
            return {
                msg: '子组件本身的数据'
            }
        },
        template: `<div>
      <p>{{msg}}</p>
      <p>{{title}}</p>
      <p>{{content}}</p>
      </div>`
    });
    var vm = new Vue({
        el: '#app',
        data: {
            pmsg: '父组件中内容',
            ptitle: '动态绑定属性'
        }
    });
</script>
————————————————
版权声明:本文为CSDN博主「温柔的坚持」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43745003/article/details/104908639

vue非父子组件间的传值

前端达人

vue非父子组件传值的基本语法

创建一个新的vue对象
var newvue = new Vue()
    
触发事件
newvue.$emit('自定义事件名', 参数)
    
监听事件
newvue.on('自定义事件名', 触发方法名)
    
销毁事件
newvue.off('自定义事件名')

案例

放在html页面上即可显示,注意要引入vue

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>父组件</div>
    <div>
      <button @click='handle'>销毁事件</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      兄弟组件之间数据传递
    */
    // 提供事件中心
    var hub = new Vue();

    Vue.component('test-tom', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>TOM:{{num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          hub.$emit('jerry-event', 2);
        }
      },
      mounted: function() {
        // 监听事件
        hub.$on('tom-event', (val) => {
          this.num += val;
        });
      }
    });
    Vue.component('test-jerry', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>JERRY:{{num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          // 触发兄弟组件的事件
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function() {
        // 监听事件
        hub.$on('jerry-event', (val) => {
          this.num += val;
        });
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {

      },
      methods: {
        handle: function(){
          hub.$off('tom-event');
          hub.$off('jerry-event');
        }
      }
    });
  </script>
</body>
</html>
————————————————
版权声明:本文为CSDN博主「温柔的坚持」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43745003/article/details/104919633



Vue移动端项目优化过程

前端达人

文章目录

前言

一、白屏时间过长分析

二、针对性优化

针对animate.css

针对mint-ui的优化

针对图片的优化

三、webpack打包优化与分析

webpack-bundle-analyzer打包分析

打包优化

四、优化后线上测试速度提升

五、优化总结

前言

最近在做项目时,测试提出了在App端的H5项目入口加载时间过长,白屏等待过久,需要优化的问题,于是着手开始分析:



项目技术栈:基于Vue全家桶做的一个移动端类似WebApp的项目,使用到的第三方库有:mint-ui, echarts,momentjs。

项目痛点:白屏时间过长

一、白屏时间过长分析

 通过访问线上环境,结合Chrome devtool中Network和Performance功能可以具体分析整个白屏的耗时主要在哪一块儿

Network耗时记录:

点击查看原图

Performance性能面板

点击查看原图

通过上面两张图分析,从浏览器发起请求到解析HTML完成这一过程中:
animate.css, mini-ui.css的请求耗时最长。
图片过大耗时。
二、针对性优化
针对animate.css
animate.css由于使用的是第三方CDN(国外服务器)所有请求时间相对较长,所以如果必须要用animate.css那么可以下载下来作为本地资源,也可以使用国内CDN,或者不用animate.css,而是针对使用到的几个CSS动画,直接自己造轮子
针对mint-ui的优化
由于mint-ui在原项目中使用的是全局引用的方式,这才导致打包资源过大,css单独请求耗时过长的问题,所以主要解决方案是按需引入mint-ui,借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

安装babel-plugin-component, 若已安装可忽略
修改 .babelrc (重点在plugins中):


{
  "presets": [
    ["env", { "modules": false }],
    "stage-2"
  ],
  "plugins": ["transform-runtime",["component", [
      {
          "libraryName": "mint-ui",
          "style": true
      }
  ]]],
  "comments": false,
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": [ "istanbul" ]
    }
  }
}


在main.js中引用使用到的插件


import Vue from 'vue'
import { Button, Cell } from 'mint-ui'
import 'mint-ui/lib/style.min.css'  // 引用CSS
import App from './App.vue'

Vue.component(Button.name, Button)
Vue.component(Cell.name, Cell)
/* 或写为
 * Vue.use(Button)
 * Vue.use(Cell)
 */

new Vue({
  el: '#app',
  components: { App }
})


在使用的组件中改为按需引用组件


import Vue from 'vue'
 var Popup = Vue.component('mt-popup')
 var Swipe = Vue.component('mt-swipe')
 var SwipeItem = Vue.component('mt-swipe-item')
 export default {
    name:'my-component',
    components:{
     Popup,
     Swipe,
     SwipeItem
    }
}

此按需引入方案也同样适用于其他第三方UI组件库



针对图片的优化

图片小图通过webpack可以直接转为base64,而大图可以通过压缩或者换格式的方式来优化,这里推荐一个好用的图片压缩工具,工具:tinyPNG,如下是图片转换前后对比


点击查看原图


三、webpack打包优化与分析

在完成了上述优化以后,下面着重关注下webpack打包后生成的文件大小,看还有没有可以优化的余地。由于项目中已经通过路由按需加载的方式来做了功能拆分,所以通过webpack打包后生成了很多分散的js文件,如下图:


20200313153537713.png

通过上图分析可以知道打包后有几个文件相对较大,vendor.js都知道是第三方库文件打包形成,之前通过mint-ui按需加载会有一定的变化,后面记录。这里着重看另两个带hash的js文件,这里并看不出来它为什么这么大,所以这里需要用到webpack打包分析工具来做进一步的打包文件分析:webpack-bundle-analyzer

webpack-bundle-analyzer打包分析

它的作用如下图,即在打包后生成打包文件大小分析图,方便我们更加直观的看到文件大小和引用情况

点击查看原图



  • 这里先介绍下webpack-bundle-analyzer的简单使用
  1. 安装
npm intall -D webpack-bundle-analyzer
  1. 修改webpack.pro.conf.js. (这里由于只是用于生产打包分析且是通过vue-cli生成的项目框架)
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
    // ...
    plugins:[
        new BundleAnalyzerPlugin()
    ]
}

运行npm run build,(webpack默认会在打包完成时生成分析图)



版权声明:本文为CSDN博主「Sophie_U」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Sophie_U/article/details/104840167

Vuex的一些用法

前端达人

vuex的基础

1,状态管理(共享)

缓存数据==>内存, 只要刷新页面,数据就丢了

订单,详情等,,,不适用vuex缓存数据



用于



非父子通信的问题

缓存后端数据,提高用户体验

注意:

vuex只能有一个store,

为了防止多人修改,我们切割成子store, 再合并成唯一一个大的store对象

模块写法

import Vue from 'vue'
import Vuex from 'vuex'
import cinema from './module/cinemaModule'
import tabbar from './module/tabbarshowModule'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {

  }, // "全局"状态
  mutations:{

  },//唯一修改状态的地方
  //异步处理
  actions:{
  },
  // 对上面的“全局状态”进行数据处理, 类似于vue中的计算属性
  getters:{
  },

  modules:{
    cinema,
    tabbar
  }
})
export default store

2,子模块的写法

const module = {
  namespaced:true, //命名空间
  state :{
    cinemaList:[]
  },
  actions:{
    store.commit("setCinemaList",res.data.data.cinemas) //支持传参
  },
  mutations:{
    setCinemaList(state,data){
      console.log("setCinemaList",data)
      state.cinemaList = data
    }
  },
  getters:{
    topDataList(state){
      //state形参s, vuex自动调用时候,传来值
      return state.cinemaList.slice(0,5)
    }
  }
}

export default module

3,为了防止页面刷新丢失数据,所以还得找到其他插件来帮忙

import createPersistedState from "vuex-persistedstate"; //在index.js页面加入这个插件

// 加入下面的代码
const store = new Vuex.Store({
  plugins: [createPersistedState({
    reducer(val){
      return {
        user: val.user
      }
    }
  })]


————————————————
版权声明:本文为CSDN博主「m0_46436313」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_46436313/article/details/104572076

vue框架渐进性的理解和mvvm模式的理解

前端达人

引言

现在市场很多前端开发的招聘岗位都或多或少的要求你要掌握vue,可以说vue在国内是非常的火爆的,下面我给大家介绍一下vue框架吧!

vue是渐进式框架


201806191038393.png


vue的核心是一个视图模板引擎,但是这并不能说明vue不是一个框架,如上图所示在声明式渲染(视图模板)基础上,vue可以添加组件系统component,vue-router客户端路由,vuex的状态管理,vue-cli构建工具来构建一个完整的框架,更重要的是这些功能相互独立,你可以任意选用你项目需要的部件,不一定非要全部整合在一起(就像是vuex它是一个很好的可以管理组件之间共享状态的部件,但非必须在你的每一个项目中使用它,如果说你的项目相对简单,组件之间的通信相对简单你完全可以不使用它),可以看到渐进式,其实就是vue的使用方式,同时也能看到vue的设计理念
vue是mvvm模式
为什么说vue是mvvm模式呢?这个大家首先要知道mvvm是什么。mvvm是Model-View-ViewModel的简写,即模型视图视图模型。模型是指后端传过来的数据,视图是指我们看到的页面,视图模型是mvvm框架的核心,他是连接view和model的桥梁,它有两个方向,第一将后端传来的数据转换成页面可以看到的视图,第二,将用户在页面上的交互转化成为后端数据,我们称之为双向绑定。
总结mvvm模式的视图和模型是不能直接通信的,它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信
vue框架可以理解为是ViewModel,它可以实现dom监听和数据绑定
vue的数据绑定原理

20200229115524399.png

当你把JavaScript对象传入vue实例作为data选项,vue会遍历此对象的所以属性,并使用Object.defineProperty把这些属性转换为getter和setter,每一个组件都有一个watcher实例,它会在组件渲染过程中,把接触过的数据记录为依赖,当依赖的setter被触发是,他会通知watcher,重而使关联的数据重新渲染,以下是代码展示。

<div id = "box"></div>
var obox = document.getElementById('box')
var obj = {}
object.defineProperty(obj,'myname',{
    get () {
        // obj设置了一个myname属性,当访问obj.myname属性会执行get方法
    },
    set (data) {
        // 当修改myname属性会执行set方法
        // data会得到你修改的值
        obox.innerHTML = data
    }
})
object.definePeoperty有一下缺点: {
1:无法监听es6的set,map变化
2:无法监听class类型的数据
3:属性的新增和删除也无法监听
4:数组元素的新整和删除也无法监听
}



Vue (一)、创建组件

seo达人

使用 vue-cli 创建 vue 项目:



cd 到指定的目录下 命令行输入:



vue init webpack-simple <项目名称>



根据提示设置Project name



设置Project description



设置Author



设置License



设置Use sass?



cd到刚刚创建的项目名称目录



命令行输入:npm install



等待安装完成后 执行 npm run dev 命令



注:以下部分练习是在https://jsfiddle.net 中进行

创建组件:(创建全局组件)

Html 部分:

<div id="app">

<div>练习</div>

<!-- 这里的 inline-template 取代组件函数中的 template:'' -->

<my-cmp inline-template>

  <p>{{ status }}</p>

</my-cmp>

<hr>

<my-cmp inline-template>

  <p>第二次使用{{ status }}</p>

</my-cmp>

</div>



Js 部分:

Vue.component('my-cmp',{

data: function () {

  return {

    status:'Critical'

    }

  },

 methods: {}



});



var vm = new Vue({

  el: "#app"

})



如果将data提取成公共的部分,则多次使用同一个组件则这部分数据在内存中使用的是同一块存储 如下演示:

html部分:

<div id="app">

  <div>练习</div>

  <my-cmp></my-cmp>

  <hr>

  <my-cmp></my-cmp>

</div>



Js 部分

var data = {status:'Critical'};

Vue.component('my-cmp',{

data: function () {

  return data

  },

 template:'<p>Server status {{ status }} (<button @click="changeStatus">Change</button>)</p>',

 methods: {

    changeStatus(){

    this.status = "Nomal"

    }  

 },



});

var vm = new Vue({

  el: "#app"

})



上面的js代码当点击按钮的时候两个组件引用的数据均会发生变化

局部注册组件:

html部分:

<div id="app">

  <div>局部注册组件练习</div>

  <local-cmp></local-cmp>

  <hr>

  <local-cmp></local-cmp>

</div>



Js 部分:



var cmp = {

   data: function () {

        return {

          status:'Critical'

        }

    },

   template:'<p>Server status {{ status }} (<button @click="changeStatus">Change</button>)</p>',

   methods: {

      changeStatus(){

        this.status = "Nomal"

      }  

   },

};

var vm = new Vue({

  el: "#app",

  components:{'local-cmp':cmp}

})


日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档