蓝调爵士

蓝调爵士 查看完整档案

北京编辑郑州升达经贸管理学院  |  软件工程 编辑北京微蜜友网络科技  |  h5前端工程师 编辑 github.com/Liiukenan 编辑
编辑

好看的皮囊千篇一律,有趣的灵魂万里挑一。

个人动态

蓝调爵士 发布了文章 · 11月25日

nextjs 根据生产环境和测试环境打不同的包

dev环境和test环境以及pro环境的接口不一样,因为上线之前毕竟是需要测试的。
这就需要我们来打不同的包来便于测试。
在nextjs中,只需要简单的配置就可以完成我们需要的工作,我之前做的时候是根据官方文档写的建立 .env.development , .env.production以及 .env.test,但是打test包之后总是报一个无限循环的bug,试了很久也没解决,如果有熟悉的小伙伴欢迎留言讨论。

目前我用的是另一个方法。

我们建立好nextjs框架之后,找到package.json这个文件,修改其中的

"scripts": {
    "dev": "NEXT_PUBLIC_DOMAIN_ENV=development next dev",
    "build": "NEXT_PUBLIC_DOMAIN_ENV=production next build && next export",
    "start": "next start",
    "test":"NEXT_PUBLIC_DOMAIN_ENV=test next build && next export"
  }

其中 next build && next export 是打包静态文件到cdn用的。主要是前面加了 NEXT_PUBLIC_DOMAIN_ENV=test 至关重要。
然后我在根目录加了个config文件夹,新建servicePath当做接口地址文件,熟悉react和vue框架的同学应该对这个很熟悉了,axios获取接口的时候用这个很方便(当然文件夹跟文件名称并不是固定的,小伙伴们可以根据自己的需要来取),以下附上我的servicePath.js的内容

let ipUrl = null; //接口
if(process.env.NEXT_PUBLIC_DOMAIN_ENV==="production"){
    //生产环境接口地址
    ipUrl="http://127.0.0.1:7001"
}else {
    //开发以及测试环境接口地址(我这里开发环境和测试环境是一样的接口)
    ipUrl="http://128.0.0.1:7005"
}
let servicePath = {
  getArticleList: ipUrl + "/getArticleList", //首页接口
};
export default servicePath;

然后在你的页面里引入
import servicePath from '../config/servicePath'

剩下的使用就不跟大家过多介绍啦。

最后npm run build 就是生产环境打包,npm run test 就是测试环境打包。

查看原文

赞 0 收藏 0 评论 0

蓝调爵士 发布了文章 · 7月17日

一个简单的命令行项目发布工具 fjpublish.js

我们发布包的时候,总是要打包,然后把包放到测试服上,当然正式的包一般都发给后台让他们放到服务器,但是每次打包每次用ftp工具往上放也很麻烦,这里我给大家推荐一款简单的一键发布命令行框架的,贼好用,强烈推荐!!!!
首先当然是安装啦!
https://fjpublish.manman.io/...,如果有什么搞不明白的,官方文档写的很清楚,下面介绍我最常用的一种方法。

安装

npm install -g fjpublish # 或者:yarn global add fjpublish

配置(这里是vue的项目)
1594969612350.jpg
新建好这样一份文件放在根目录后,然后里面写入

module.exports \= {

modules: \[

{

name: "测试环境",

env: "test",

ssh: {

host: "54.222.180.211",   //测试服地址

username: "ubuntu",  //测试服链接名称

//privateKey为认证在服务器的公钥对应的私钥地址,请灵活变通

privateKey: require("fs").readFileSync(

"/Users/liukenan/.ssh/id\_rsa"

) //mac用户举例

},

buildCommand: "test",//这里是npm run test的意思

localPath: "dd",//vue生成的包名

remotePath: "/data/www/dd"  //上传到服务器的文件夹位置

}

\]

};

好了,配置完成。
最后在终端输入fjpublish env -s 发布就ok了!

查看原文

赞 0 收藏 0 评论 0

蓝调爵士 关注了标签 · 6月30日

node.js

图片描述
Node 是一个 Javascript 运行环境(runtime)。实际上它是对 Google V8 引擎(应用于 Google Chrome 浏览器)进行了封装。V8 引擎执行 Javascript 的速度非常快,性能非常好。Node 对一些特殊用例进行了优化,提供了替代的 API,使得 V8 在非浏览器环境下运行得更好。例如,在服务器环境中,处理二进制数据通常是必不可少的,但 Javascript 对此支持不足,因此,V8.Node 增加了 Buffer 类,方便并且高效地 处理二进制数据。因此,Node 不仅仅简单的使用了 V8,还对其进行了优化,使其在各环境下更加给力。

关注 81776

蓝调爵士 评论了文章 · 2019-03-21

从引入到实例最详尽 vue.js引入vuex储存接口数据并调用的流程

项目终于做完了,博客也很久没更新了,写下这个项目用到的一些知识,以后大家也少踩点坑
第一步当然还是安装了,这里只介绍npm的安装方法,别的请自行百度。

npm install vuex --save

第二步就是调用,我在src文件夹简历了个store.js的文件,方便管理。然后在main.js里面引入

import store from "./store";
new Vue({
  store,
  render: h => h(App)
}).$mount("#app");

至此,安装基本完成,下面介绍这个东西的用法。vuex的好处我也不多说了,简单来说就是数据共享嘛,反正谁用谁知道。不要以为你的项目小就可以不用这个,它可以让你在开发中省掉很多事儿。
现在我的文件是这样的(项目框架是vue-cli3.0):

clipboard.png

接下来就开始在store里面写东西啦。其实这东西用法简单的一比,就是几个属性而已。最常用的就这四个:state,mutations,actions,getters.
state就是存死数据的,当然下面也可以改它的数据.

1.store

在store.js里面:

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
  state: {
    box: 123
  }
});

然后在你的组件里面引入一下(我这里直接引用了这四个家伙,实际开发的时候你用到啥引用啥就好,不然eslint又该出红线了)

import {
        mapGetters,
        mapState,
        mapMutations,
        mapActions

} from "vuex";
然后在计算属性里面写

  computed: {
    ...mapState(["box"])
  },

接下来在template里面直接调用,这个数据是共享的,在每一个组件里面想用都可以直接这么引入调用(加个点击事件,下面要用下)

<div class="page">
    {{box}}
</div>
<button @click="btn">按钮</button>

哈哈,界面里面估计都已经显示了123了吧。就是这么简单。

2.mutations

接下来看mutations,这个属性主要是修改store存储的值的,就比如说刚才那个box,就可以用这个玩意儿修改。
在store里面接着上面的写

export default new Vuex.Store({
  state: {
    box: 123
  },
  mutations: {
    someMutation(state, count) {
      state.box += count;
    }
  }
});

这个里面有两个参数,state,count,state就是上面那个state,count就是你要传入的数据,当然,你不传东西也可以,只是个方法而已。我这随便写了个案例。
接下来在你的组件里面的调用,这里调用是在methods里面写,毕竟人家是方法嘛,对吧!

...mapMutations(["someMutation"]),
    btn(){
      this.someMutation(22);
    }

这里我传了个值为22,写在了点击事件里面,然后就是开始点击,相信你现在看到已经变成145了。

3.actions
actions里面也是两个参数, 例如在store.js里面这么写:

actions: {
    getbox2(context,s) {
      return context.box;
    }
  }

我们可以通过第一个参数context来获取state或者getter里面的值,context.state或者context.getters直接就可以获取第二个参数s,就是我们传的值。
在组件里面我们直接这么写

methods:{
    ...mapActions(["getbox2"]),
    ...mapMutations(["someMutation"])
   }

然后直接调用

mounted(){
    this.getbox2(1234).then((res)=>{
          console.log(res)
    })
}

这里打印出来的是根据刚才在store里面返回的值有关,

getbox2(context,s) {
      return context.box;
    }

这样返回的就是123,若是

getbox2(context,s) {
          return s;
        }

这么写返回的就是你传入的那个s,打印出1234.
actions还可以直接调用mutations的方法。例如
getbox2(context) {

  return context.commit('someMutation');
}

然后在组件中直接调用

this.getbox2()

这样就直接运行了someMutation这个方法。值得一提的是actions是异步的,就是你想怎么用,想在哪用都是可以的。简单来说,就是你想改变state的值,就用mutations,如果你想用方法,就用actions

4.getters
getters就更加简单啦,直接在store里面,例如:

getters: {
    getbox(state) {
      return 1;
    }
  }

然后在组件的计算属性里面这么写:

computed: {
    ...mapGetters(["getbox"]),
    ...mapState(["box"])
  },

然后在template里面直接拿来用,

<div class="page">
    {{ getbox }}
    {{box}}
   <button @click="btn">按钮</button>
  </div>

简单来说,这东西就是vuex里面的计算属性,跟computed一个尿性。里面的state就是上面那个state。最终代码是这样的:

组件中:

<template>
  <div class="page">
    {{ getbox }}
    {{box}}
   <button @click="btn">按钮</button>
  </div>
</template>

<script type="text/ecmascript-6">
 import {
        mapGetters,
        mapState,
        mapMutations,
        mapActions
    } from "vuex";
export default {
  data() {
    return {
      count:0
    }
  },
  components: {
  },
  computed: {
    ...mapGetters(["getbox"]),
    ...mapState(["box"])
  },
  methods:{
    ...mapActions(["getbox2"]),
    ...mapMutations(["someMutation"]),
    btn(){
      this.someMutation(22);
    },
  },
  mounted() {
    //  this.getbox2().then((res)=>{
    //   console.log(res)
    // })
    this.getbox2()
    
  },
}
</script>

<style scoped lang="stylus">
</style>

在store.js中:

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    box: 123
  },
  mutations: {
    someMutation(state, count) {
      // state.box += count;
      state.box++;
    }
  },
  actions: {
    getbox2(context) {
      return context.commit('someMutation');
    }
  },
  getters: {
    getbox(state) {
      return state.box;
    }
  }
});

main.js中:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

好了,大功告成,相信你们对这个所谓的状态管理工具有一定的了解了。有啥写的不太好的地方,请大家多多指教。

查看原文

蓝调爵士 发布了文章 · 2018-09-17

获取图片主体背景色

当网络不好的时候,图片未加载出来,先加载背景色,当时就觉得很有意思,效果是这样图片描述

主要用到rgbaster.js,这里我把源码也贴下来。
rgbaster.js的内容是:

!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.RGBaster=t()}(this,function(){"use strict";var t=function(n,o){var u=new Image,t=n.src||n;"data:"!==t.substring(0,5)&&(u.crossOrigin="Anonymous"),u.onload=function(){var n,t,e,r=(n=u.width,t=u.height,(e=document.createElement("canvas")).setAttribute("width",n),e.setAttribute("height",t),e.getContext("2d"));r.drawImage(u,0,0);var i=r.getImageData(0,0,u.width,u.height);o&&o(i.data)},u.data-original=t},s=function(n){return["rgb(",n,")"].join("")},f=function(n,t){return{name:s(n),count:t}},n={};return n.colors=function(n,u){var a=(u=u||{}).exclude||[],c=u.paletteSize||10;t(n,function(n){for(var t={},e="",r=[],i=0;i<n.length;i+=4)r[0]=n[i],r[1]=n[i+1],r[2]=n[i+2],e=r.join(","),-1===r.indexOf(void 0)&&0!==n[i+3]&&-1===a.indexOf(s(e))&&(t[e]=e in t?t[e]+1:1);if(u.success){var o=function(n,t){if(n.length>t)return n.slice(0,t);for(var e=n.length-1;e<t-1;e++)n.push(f("0,0,0",0));return n}(function(n){var t=[];for(var e in n)t.push(f(e,n[e]));return t.sort(function(n,t){return t.count-n.count}),t}(t),c+1);u.success({dominant:o[0].name,secondary:o[1].name,palette:o.map(function(n){return n.name}).slice(1)})}})},n});

具体html和js的使用代码是:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取图片主题色脚本扩展的完整的示例</title>
    <script data-original="./rgbaster.js"></script>
</head>

<body>
    <div id="box" style="width:500px;height: 500px;">
        <img data-original="mm4.jpg" alt="" id="image">
    </div>
    <script type="text/javascript">
    var img = document.getElementById('image');
    var box=document.getElementById('box');
    RGBaster.colors(img, {
        // return up to 30 top colors from the palette  从调色板返回最多30个顶级颜色
        paletteSize: 30,
        // don't count white
        //排除 白色
        exclude: ['rgb(255,255,255)'],
        // do something when done
        //获取成功之后
        success: function(payload) {
            box.style.background=payload.dominant;
            console.log('Dominant color:', payload.dominant);
            console.log('Secondary color:', payload.secondary);
            console.log('Palette:', payload.palette);
        }
    })
    </script>
</body>
</html>

剩下的,效果一出,大家一目了然,就是这么简单。

查看原文

赞 0 收藏 0 评论 0

蓝调爵士 关注了标签 · 2018-09-07

vue.js

Reactive Components for Modern Web Interfaces.

Vue.js 是一个用于创建 web 交互界面的。其特点是

  • 简洁 HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
  • 数据驱动 自动追踪依赖的模板表达式和计算属性。
  • 组件化 用解耦、可复用的组件来构造界面。
  • 轻量 ~24kb min+gzip,无依赖。
  • 快速 精确有效的异步批量 DOM 更新。
  • 模块友好 通过 NPM 或 Bower 安装,无缝融入你的工作流。

官网:https://vuejs.org
GitHub:https://github.com/vuejs/vue

关注 100533

蓝调爵士 赞了文章 · 2018-09-07

webpack手动构建vue和vue-cli构建使用 px2rem-loader ,全局自动转换px单位,让自适应来的更简单点!

做移动端时,适配 是必须的。使用rem单位,可在不同屏幕上完美显示相同的布局。px2rem 插件方便的将px单位转为了rem。

1. 自己手动构建vue webpck配置

我们在开发过程中,我们在css文件中,直接按设计稿,直接以px像素为单位,然后在真正的应用中,我们想让px自动转制为rem单位,那这个要怎么让构建工具自动转换呢?

大家想一下,我们的构建工具,其实最主要还是来自vue,vue这个文件中我们使用了vue-loader,那如果说你使用了vue-cli脚手架的话,那么你想增加这个功能,并不简单,但是我们手工打造构建工具,就不受限制,想怎么用就怎么用,按照刚才的思路,我们知道,所有的文件几乎是vue文件,所有的loader是vue-loader。

在webpack配置,我们一个文件可以使用多个loader, 我们使用vue-loader也可以用其它loader,那怎么用呢?这就要去看vue官方文档了。

这边我为大家找到这个文档

clipboard.png

通过官方文档,我们可以了解到,要使用sass-loader,要需要在vue-loader中,增加一个options进行相应的配置就可以使用对应的loader了。

我们现在要做的是能自动将px转换成rem,所以跟这也有相似类,只要我们将转换的loader添加进行就可以了,那能将px自动转换成rem是哪个loader呢?

那我们要怎么找呢?当我们不会的时候,可以到npm.js官网,然后可以猜想一到输入px, rem,一回车就可以看到

clipboard.png

从图中我们可以看到有个px2rem2-loader,下面还有一个px2rem,我们直接搜索px2rem

clipboard.png

这种loader有多个,平常我们用的比较多的还是px2rem,所以这边 就介绍px2rem,其它loader可以自行研究噢!点击进去我们可以发现

clipboard.png

里面有介绍我们怎么安装,以及怎么引入,我们可以模仿vue官网的写法

clipboard.png

如上图,我们主要注意几点

  1. loader解析顺序是按从右到左的方法解析的。
  2. px2rem官网是没有带后缀.loader,webpack2.0之后是没允许的,所以这边我们要加上后缀。
  3. scss文件首先要把scss转成正常的css,在交给px2rem.loader来做,所以是外还需要加上一个sass-loader
  4. remUnit: 750//设计稿宽度/10,remPrecision:表示转换过程小数保留几位。

2. 使用vue-cli构建px2rem.loader

1).下载lib-flexible

我使用的是vue-cli+webpack,所以是通过npm来安装的

npm i lib-flexible --save

2)引入lib-flexible

在main.js中引入lib-flexible

import 'lib-flexible/flexible'

3) 安装px2rem-loader

npm install px2rem-loader

4).配置px2rem-loader

在build下的 utils.js中,找到generateLoaders 方法,在这里添加 。

clipboard.png

安装配置结束后,重启项目 。然后再浏览器中查看。会发现自己设置的px被转为rem 了。

愿你成为终身学习者
查看原文

赞 17 收藏 9 评论 8

蓝调爵士 收藏了文章 · 2018-09-06

浅谈 Vue 项目优化

好久不写博文了,本文作为我使用半年 vue 框架的经验小结,随便谈谈,且本文只适用于 vue-cli 初始化的项目或依赖于 webpack 打包的项目。

前几天看到大家说 vue 项目越大越难优化,带来很多痛苦,这是避免不了的,问题终究要解决,框架的性能是没有问题的,各大测试网站都有相关数据。下面进入正题

基础优化

所谓的基础优化是任何 web 项目都要做的,并且是问题的根源。HTML,CSS,JS 是第一步要优化的点

分别对应到 .vue 文件内的,<template>,<style>,<script>,下面逐个谈下 vue 项目里都有哪些值得优化的点

template

语义化标签,避免乱嵌套,合理命名属性等等标准推荐的东西就不谈了。

模板部分帮助我们展示结构化数据,vue 通过数据驱动视图,主要注意一下几点

  • v-show,v-if 用哪个?在我来看要分两个维度去思考问题,第一个维度是权限问题,只要涉及到权限相关的展示无疑要用 v-if,第二个维度在没有权限限制下根据用户点击的频次选择,频繁切换的使用 v-show,不频繁切换的使用 v-if,这里要说的优化点在于减少页面中 dom 总数,我比较倾向于使用 v-if,因为减少了 dom 数量,加快首屏渲染,至于性能方面我感觉肉眼看不出来切换的渲染过程,也不会影响用户的体验。
  • 不要在模板里面写过多的表达式与判断 v-if="isShow && isAdmin && (a || b)",这种表达式虽说可以识别,但是不是长久之计,当看着不舒服时,适当的写到 methods 和 computed 里面封装成一个方法,这样的好处是方便我们在多处判断相同的表达式,其他权限相同的元素再判断展示的时候调用同一个方法即可。
  • 循环调用子组件时添加 key,key 可以唯一标识一个循环个体,可以使用例如 item.id 作为 key,假如数组数据是这样的 ['a' , 'b', 'c', 'a'],使用 :key="item" 显然没有意义,更好的办法就是在循环的时候 (item, index) in arr,然后 :key="index"来确保 key 的唯一性。

style

  • 将样式文件放在 vue 文件内还是外?讨论起来没有意义,重点是按模块划分,我的习惯是放在 vue 文件内部,方便写代码是在同一个文件里跳转上下对照,无论内外建议加上 <style scoped> 将样式文件锁住,目的很简单,再好用的标准也避免不了多人开发的麻烦,约定命名规则也可能会冲突,锁定区域后尽量采用简短的命名规则,不需要 .header-title__text 之类的 class,直接 .title 搞定。
  • 为了和上一条作区分,说下全局的样式文件,全局的样式文件,尽量抽象化,既然不在每一个组件里重复写,就尽量通用,这部分抽象做的越好说明你的样式文件体积越小,复用率越高。建议将复写组件库如 Element 样式的代码也放到全局中去。
  • 不使用 float 布局,之前看到很多人封装了 .fl -- float: left 到全局文件里去,然后又要 .clear,现在的浏览器还不至于弱到非要用 float 去兼容,完全可以 flex,grid 兼容性一般,功能其实 flex 布局都可以实现,float 会带来布局上的麻烦,用过的都知道不相信解释坑了。

至于其他通用的规范这里不赘述,相关文章很多。

script

这部分也是最难优化的点,说下个人意见吧。

  • 多人开发时尽量保持每个组件 export default {} 内的方法顺序一致,方便查找对应的方法。我个人习惯 data、props、钩子、watch、computed、components。
  • data 里要说的就是初始化数据的结构尽量详细,命名清晰,简单易懂,避免无用的变量,isEditing 实际可以代表两个状态,true 或 false,不要再去定义 notEditing 来控制展示,完全可以在模板里 {{ isEditing ? 编辑中 : 保存 }}
  • props 父子组件传值时尽量 :width="" :heigth="" 不要 :option={},细化的好处是只传需要修改的参数,在子组件 props 里加数据类型,是否必传,以及默认值,便于排查错误,让传值更严谨。
  • 钩子理解好生命周期的含义就好,什么时间应该请求,什么时间注销方法,哪些方法需要注销。简单易懂,官网都有写。
  • metheds 中每一个方法一定要简单,只做一件事,尽量封装可复用的简短的方法,参数不易过多。如果十分依赖 lodash 开发,methed 看着会简洁许多,代价就是整体的 bundle 体积会大,假如项目仅仅用到小部分方法可以局部引入 loadsh,不想用 lodash 的话可以自己封装一个 util.js 文件
  • watch 和 computed 用哪个的问题看官网的例子,计算属性主要是做一层 filter 转换,切忌加一些调用方法进去,watch 的作用就是监听数据变化去改变数据或触发事件如 this.$store.dispatch('update', { ... })

组件优化

vue 的组件化深受大家喜爱,到底组件拆到什么程度算是合理,还要因项目大小而异,小型项目可以简单几个组件搞定,甚至不用 vuex,axios 等等,如果规模较大就要细分组件,越细越好,包括布局的封装,按钮,表单,提示框,轮播等,推荐看下 Element 组件库的代码,没时间写这么详细可以直接用 Element 库,分几点进行优化

  • 组件有明确含义,只处理类似的业务。复用性越高越好,配置性越强越好。
  • 自己封装组件还是遵循配置 props 细化的规则。
  • 组件分类,我习惯性的按照三类划分,page、page-item 和 layout,page 是路由控制的部分,page-item 属于 page 里各个布局块如 banner、side 等等,layout 里放置多个页面至少出现两次的组件,如 icon, scrollTop 等

vue-router 和 vuex 优化

vue-router 除了切换路由,用的最多的是处理权限的逻辑,关于权限的控制这里不赘述,相关 demo 和文章有许多,那么说到优化,值得一提的就是组件懒加载

中文官网链接如上,例子如下

const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')

这段代码将 Foo, Bar, Baz 三个组件打包进了名为 group-foo 的 chunk 文件,当然啦是 js 文件

其余部分正常写就可以,在网站加载时会自动解析需要加载哪个 chunk,虽然分别打包的总体积会变大,但是单看请求首屏速度的话,快了好多。

vuex 面临的问题和解决方案有几点

  • 当网站足够大时,一个状态树下,根的部分字段繁多,解决这个问题就要模块化 vuex,官网提供了模块化方案,允许我们在初始化 vuex 的时候配置 modules。每一个 module 里面又分别包含 state 、action 等,看似是多个状态树,其实还是基于 rootState 的子树。细分后整个 state 结构就清晰了,管理起来也方便许多。
  • 由于 vuex 的灵活性,带来了编码不统一的情况,完整的闭环是 store.dispatch('action') -> action -> commit -> mutation -> getter -> computed,实际上中间的环节有的可以省略,因为 API 文档提供了以下几个方法 mapState、mapGetters、mapActions、mapMutations,然后在组件里可以直接调取任何一步,还是项目小想怎么调用都可以,项目大的时候,就要考虑 vuex 使用的统一性,我的建议是不论多简单的流程都跑完整个闭环,形成代码的统一,方便后期管理,在我的组件里只允许出现 dispatch 和 mapGetters,其余的流程都在名为 store 的 vuex 文件夹里进行。
  • 基于上面一条,说下每个过程里面要做什么,前后端数据一定会有不一致的地方,或是数据结构,或是字段命名,那么究竟应该在哪一步处理数据转换的逻辑呢?有人会说其实哪一步都可以实现,其实不然,我的建议如下
  1. 在发 dispatch 之前就处理好组件内需要传的参数的数据结构和字段名
  2. 到了 action 允许我们做的事情很多,因为这部支持异步,支持 state, rootState, commit, dispatch, getters,由此可见责任重大,首先如果后端需要部分其他 module 里面的数据,要通过 rootState 取值再整合到原有数据上,下一步发出请求,建议(async await + axios),拿到数据后进行筛选转换,再发送 commit 到 mutation
  3. 这一步是将转换后的数据更新到 state 里,可能会有数据分发的过程(传进一个 object 改变多个 state 中 key 的 value),可以转换数据结构,但是尽量不做字段转换,在上一步做
  4. 此时的 store 已经更新,使用 getter 方法来取值,token: state => state.token,单单的取值,尽量不要做数据转换,需要转换的点在于多个地方用相同的字段,但是结构不同的情况(很少出现)。
  5. 在组件里用 mapGetters 拿到对应的 getter 值。

打包优化

上面说了代码方面的规范和优化,下面说下重点的打包优化,前段时间打包的 vender bundle 足足 1.4M,app bundle 也有 270K,app bundle 可以通过组件懒加载解决,vender 包该怎么解决?

有人会质疑是不是没压缩或依赖包没去重,其实都做了就是看到的 1.4M。

解决方法很简单,打包 vender 时不打包 vue、vuex、vue-router、axios 等,换用国内的 bootcdn 直接引入到根目录的 index.html 中。

例如:

<script data-original="//cdn.bootcss.com/vue/2.2.5/vue.min.js"></script>
<script data-original="//cdn.bootcss.com/vue-router/2.3.0/vue-router.min.js"></script>
<script data-original="//cdn.bootcss.com/vuex/2.2.1/vuex.min.js"></script>
<script data-original="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script>

在 webpack 里有个 externals,可以忽略不需要打包的库

externals: {
  'vue': 'Vue',
  'vue-router': 'VueRouter',
  'vuex': 'Vuex',
  'axios': 'axios'
}

此时的 vender 包会非常小,如果不够小还可以拆分其他的库,此时增加了请求的数量,但是远比加载一个 1.4M 的 bundle 快的多。

总结

本文谈的优化可以解决部分性能问题,实际开发细节很多,总之按着规范写代码,团队的编码风格尽量统一,处理细节上多加思考,大部分性能问题都能迎刃而解。

文章出自 orange 的 个人博客 http://orangexc.xyz/
查看原文

蓝调爵士 收藏了文章 · 2018-03-08

前端面试之ES6篇(高产似母猪)

这也是前端面试经常询问的问题,经常问你es6出现了哪些新的特性,平时又使用过那些。在编写此教程的时候,第一句话往往就是面试常常问到的地方,然后后面就是他的详细解释,面试要求的内容我会用*标记出来。写技术文档是真的累啊,虽然是看别人的文档,但是你得看很多,而且还得自己总结啊。所以说要是觉得对你有用还是帮我点个star吧https://github.com/skychenbo

1、箭头函数需要注意的地方
2、ES6 let、const
3、set数据结构
4、promise对象的用法,手写一个promise
5、class的理解
6、模版语法的理解
7、rest参数
8、    module体系

箭头函数需要注意的地方

*当要求动态上下文的时候,就不能够使用箭头函数。也就是this的固定化
1、在使用=>定义函数的时候,this的指向是定义时所在的对象,而不是使用时所在的对象
2、不能够用作构造函数,这就是说,不能够使用new命令,否则就会抛出一个错误
3、不能够使用arguments对象
4、不能使用yield命令
这是一道当年很困惑我的一道题不知道你在第一眼能不能看出其结果,this的指向总是让人困扰,但是有了=>以后妈妈再也不用担心你使用this了

class Animal {
    constructor(){
        this.type = 'animal'
    }
    says(say) {
        setTimeout(function () {
            console.log(this.type + 'says' + say)
        },1000)
    }
}
var animal = new Animal()
animal.says('hi') // undefined says hi

我们再来看看=>的情况

class Animal() {
    constructor() {
        this.type = 'animal'
    }
    says(say) {
        setTimeout(() => {
            console.log(this.type + ' says ' + say)
        }, 1000)
    }
}
var animal = new Animal()
animal.says('hi') // animal says hi

ES6 let、const
*let是更完美的var,不是全局变量,具有块级函数作用域,大多数情况不会发生变量提升。const定义常量值,不能够重新赋值,如果值是一个对象,可以改变对象里边的属性值
let
1、let声明的变量具有块级作用域
2、let声明的变量不能通过window.变量名进行访问
3、形如for(let x..)的循环是每次迭代都为x创建新的绑定
下面是var带来的不合理场景

var a = []
for (var i = 0; i < i; i++) {
    a[i] = function () {
        console.log(i)
    }
}
a[5]() // 10

在上述代码中,变量i是var声明的,在全局范围类都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出都是10
而如果对循环使用let语句的情况,那么每次迭代都是为x创建新的绑定代码如下

var a = []
for (let i = 0; i < i; i++) {
    a[i] = function () {
        console.log(i)
    }
}
a[5]() // 5

当然除了这种方式让数组中的各个元素分别是不同的函数,我们还可以采用闭包和立即函数两种方法
这是闭包的方法

function showNum(i) {
    return function () {
        console.log(i)
    }
}
var a = []
for (var i = 0; i < 5; i++) {
    a[i] = showNum(i)
}

这是立即函数的方法

var a = []
for (var i = 0; i < 5; i++) {
    a[i] = (function (i) {
        return function () {
            console.log(i)
        }
    })(i)
}
a[2]()

Set数据结构

*es6方法,Set本身是一个构造函数,它类似于数组,但是成员值都是唯一的

const set = new Set([1,2,3,4,4])
[...set] // [1,2,3,4]
Array.from(new Set())是将set进行去重


promise对象的用法,手写一个promise

promise是一个构造函数,下面是一个简单实例

var promise = new Promise((resolve,reject) => {
    if (操作成功) {
        resolve(value)
    } else {
        reject(error)
    }
})
promise.then(function (value) {
    // success
},function (value) {
    // failure
})


Class的讲解

*class语法相对原型、构造函数、继承更接近传统语法,它的写法能够让对象原型的写法更加清晰、面向对象编程的语法更加通俗
这是class的具体用法

class Animal {
    constructor () {
        this.type = 'animal'
    }
    says(say) {
        console.log(this.type + 'says' + say)
    }
}
 let animal = new Animal()
 animal.says('hello') // animal says hello

 class Cat extends Animal {
     constructor() {
         super()
         this.type = 'cat'
     }
 }
 let cat = new Cat()
 cat.says('hello') // cat says hello

可以看出在使用extend的时候结构输出是cat says hello 而不是animal says hello。说明contructor内部定义的方法和属性是实例对象自己的,不能通过extends 进行继承。在class cat中出现了super(),这是什么呢
在ES6中,子类的构造函数必须含有super函数,super表示的是调用父类的构造函数,虽然是父类的构造函数,但是this指向的却是cat

Object.assign 方法

var n = Object.assign(a,b,c)向n中添加a,b,c的属性

模版语法

*就是这种形式${varible},在以往的时候我们在连接字符串和变量的时候需要使用这种方式'string' + varible + 'string'但是有了模版语言后我们可以使用string${varible}string这种进行连接

rest参数

*es6引入rest参数,用于获取函数的多余参数,这样就不需要使用arguments对象了
ex:

function add(...values) {
    let sum = 0
    for(var val of values) {
        sum += val
    }
    return sum
}

module体系

*历史上js是没有module体系,无法将一个大程序拆分成一些小的程序。在es6之前,有commonJs,AMD两种
CommonJS是如何书写的呢



const animal = require('./content.js')
    // content.js
    module.exports = 'a cat'

require.js是这样做的
// content.js

define('content.js', function () {
    return 'A cat'
})

require(['./content.js'], function (animal) {
    console.log(animal) // a cat
})

ES6的语法(在我用的vue中,就使用的是这个)

import animal from './content'
// content.js
export default 'a cat'

es6 import的其他用法
在vue中可以 import animal from './content'
animal这个值可以根据你的喜欢而改变,但是有一个问题就是如果一旦引入的是函数或者变量时,你就必须和content中的名字保持一致,可以参照
import { say, type } from './content'
常用的还有一种写法
import * as content from './content'
这种写法就是表示所有的输出值都在这个对象上

查看原文

蓝调爵士 收藏了文章 · 2018-03-05

2018前端面试准备

前端面试常见问题按知识点分类整理

前端面试常考问题整理,按模块知识点分类,持续完善中... Front-end-Developer-Questions by Modules and knowledge

前端面试经典问题:CSS 中居中的几种方式

面试中经常遇到的面试题之一,居中布局,特来总结

几个让我印象深刻的面试题 (一)

分享几个我遇到的认为不错的面试题

27款优质简洁的个人简历打包下载

优质简洁的个人简历打包

前端开发面试题总结之——JAVASCRIPT(一)

前端面试系列之 JavaScript,还有两篇

44 个 JavaScript 变态题解析

读者可以先去做一下感受感受. 当初笔者的成绩是 21/44...

当初笔者做这套题的时候不仅怀疑智商, 连人生都开始怀疑了....

不过, 对于基础知识的理解是深入编程的前提. 让我们一起来看看这些变态题到底变态不变态吧!

技术 | 前端面试题(二):自定义事件

我和阿里巴巴的同事守雌将为大家带来一个系列专题:前端面试题解析,一周更新两篇,本篇主要讲如何实现自定义事件。

前端开发面试题总结之——JAVASCRIPT(二)

前端开发面试题总结之—JavaScript,一共三篇

前端开发面试题总结之——HTML

前端开发面试题,本文主要讲述的是 HTML 相关的面试题。面试相关的我整理成收藏集欢迎关注。

收集 JavaScript 各种疑难杂症的问题集锦

关于 JavaScript,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。这篇文章记录了一些有价值的问题。

一道 JS 面试题所引发的 "血案",透过现象寻本质,再从本质看现象

由一道面试题想到拓展的,分析问题的方法

CSS 面试题解答

什么是 CSS reset?CSS 性能优化?浮动的原理和工作方式,会产生什么影响呢,要怎么处理?CSS 权重?

Excuse me?这个前端面试在搞事!

金三银四搞事季,前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下。

前端开发面试题总结之——JAVASCRIPT(三)

前端开发面试题总结之 JavaScript,一共三篇

1月前端面试记

背景 我于16.12.18辞职,之前有过一年左右的前端工作经验。从12月26号开始到1月9号先后面试了微信,百度,阿里巴巴uc,唯品会以及深圳腾讯等几家公司,特此总结与各位共勉。 微信 由于我已经毕业工作过,所以去微信面试是走的社招。微信社招极其严格,共八轮面试,总体来说我基本…

一道面试题引发的对 javascript 类型转换的思考

通过一道面试题,详细描述了 javascript 类型转换的相关内容,对 javascript 进阶有所帮助。

献给前端求职路上的你们(上)

我是一名前端开发,从2016年6月毕业到如今步入工作,期间也面试了一些公司,参考过一些面试文档,学习了一些面试宝典,掌握了一些面试、笔试技巧和经验,所以就总结了一些优质的前端面试题以及面试要点,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习,透彻学习,才能形成自己的知识链,以不变应万变,万不可投机取巧,只求面试过关哦!

征服 JavaScript 面试:什么是闭包

征服 JavaScript 面试:什么是闭包

一个普通本科在校生的前端学习之路

今天我分享的内容主要是关于前端初学者的学习路线和一些建议,还有自己在准备校招过程中的一点经验。

CSS 并不简单 -- 一道微信面试题的实践

本系列会持续分享本人学习到的 CSS 知识点、技巧和效果展示。如有错误,希望您能指出。

从培训班出来之后找工作的经历,教会了我这五件事

这是 Medium 上的一篇文章(已有 5900 个赞),讲的是国外一个培训出来的程序员,用三个月时间,找到了一份年薪 12 万美元的工作,并从中得到的五个忠告的故事。 我觉得他总结得很好,尤其是心态和方法,非常值得学习。对正在找工作的同学非常有用。 想收到更多最新、最专业的前…

最近遇到的前端面试题 (2017.02.23 更新版)

最近整理的前端面试题,希望能对大家有帮助。转载自:http://www.jianshu.com/p/3944...

17 年 2 月面试经验 | _striveg blog

个人面试几家的面试题和一点小感悟

面试 -- 网络 HTTP

现在面试门槛越来越高,很多开发者对于网络知识这块了解的不是很多,遇到这些面试题会手足无措。本篇文章知识主要集中在 HTTP 这块。文中知识来自 《图解 HTTP》与维基百科,若有错误请大家指出。文章会持续更新。 面试 -- 网络 TCP/IP 了解 Web 及网络基础 对端传输…

从一道面试题,到 “我可能看了假源码”

今天想谈谈一道前端面试题

技术 | 前端面试题(一):递归解析

我和阿里巴巴的同事守雌将为大家带来一个系列专题:前端面试题解析,一周更新两篇,也许答案可能不是最优的,但是也可以给你提供解决问题的思路。

谈谈面试与面试题

Winter 对于前端面试的一些看法。

查看原文

认证与成就

  • 获得 17 次点赞
  • 获得 7 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 7 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-06-12
个人主页被 505 人浏览