四、微服务分布式电商系统--前端开发基础知识&快速入门

【摘要】前端开发基础知识&快速入门~

前言

VSCode的使用

之前介绍过,这边不再赘述。

ES6

简介

ECMAScript 6.0(以下简称ES6,ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言)是JavaScript语言的下一代标准,已经在2015年6月正式发布了,并且从ECMAScript 6.0开始采用年号来做版本。即ECMAScript2015,就是ECMAScript6。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。每年一个新版本。

ES6新特性

let声明变量

新建es6文件夹,使用VSCode打开。新建文件1.let.html,按住Shift+!快速生成代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
// var 声明变量往往会越域
// let 声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a); // 1
//console.log(b); // Uncaught ReferenceError: b is not defined

// var 可以声明多次
// let 只能声明一次
var m = 1
var m = 2
let n = 3
//let n = 4
console.log(m); // 2
//console.log(n); // Uncaught SyntaxError: Identifier 'n' has already been declared

// var 会变量提升
// let 不存在变量提升
console.log(x); // undefined
var x = 10;
//console.log(y); //Uncaught ReferenceError: Cannot access 'y' before initialization
//let y = 10;
</script>

const声明变量(只读变量)

1
2
3
4
5
6
<script>
// 1. 声明之后不允许改变
// 2. 一旦声明必须初始化,否则会报错
const a = 1;
a = 3; // Uncaught TypeError: Assignment to constant variable.
</script>

解构表达式

数组解构

1
2
3
4
5
6
7
8
<script>
// 数组解构
let arr = [1,2,3];
//以前我们想获取其中的值,只能通过角标。ES6可以这样:
const [x,y,z] = arr;// x,y,z将与arr中的每个位置对应来取值
//然后打印
console.log(x,y,z);
</script>

对象解构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
// 数组解构
let arr = [1,2,3];
//以前我们想获取其中的值,只能通过角标。ES6可以这样:
const [x,y,z] = arr;// x,y,z将与arr中的每个位置对应来取值
//然后打印
console.log(x,y,z);


const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
// 以等价于下面 前的做法
//const name = person.name;
//const age = person.age;
//const language = person.language;
//console.log(name);
//console.log(age);
//console.log(language);

//解构表达式获取值,将person里面的每一个属性和左边对应赋值
//对象解构
const{name,age,language} = person;
console.log(name,age,language);

//扩展:如果想要将name的值赋给其他变量,可以如下,abc是新的变量。
//const{name:abc,age,language} = person;
//console.log(abc,age,language);

</script>

字符串扩展

几个新的API

ES6为字符串扩展了几个新的API:

  • startsWith():返回布尔值,表示是否找到了参数字符串。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • includes():返回布尔值,表示参数字符串是否在原字符串的尾部。
1
2
3
4
5
6
7
<script>
let str = "hello.vue";
console.log(str.startsWith("hello"));//ture
console.log(str.endsWith(".vue"));//ture
console.log(str.includes("e"));//true
console.log(str.includes("hello"));//ture
</script>

字符串模板

模板字符串相当于加强版的字符串,用反引号除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。

1
2
3
4
5
6
let ss = `
<div>
<span>hello world</span>
</div>
`
console.log(ss)

字符串扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//1.字符串模板
let ss = `
<div>
<span>hello world</span>
</div>
`
console.log(ss)

//2.字符串插入变量和表达式。变量名写在${}中,${}中可以JavaScript表达式。
let name = "张三";
let age = 18;
let info = `我是${name},今年${age+1}了`;
console.log(info)

//3.字符串中调用函数
function fun(){
return "这是一个函数";
}
let sss = `H啊哈哈哈~${fun()}`;
console.log(sss);//H啊哈哈哈~这是一个函数

函数优化

函数参数默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法。
function add(a, b) {
//判断b是否为空,为空就给默认值1
b = b || 1;
return a + b;
}
//传一个参数
console.log(add(10));

//现在可以这么写,直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}

//传一个参数
console.log(add2(10));

</script>

不定参数

不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。
具名参数只能放在参数列表的最后,并且有且只有一个不定参数。

1
2
3
4
5
6
7
8
//2.不定参数
<script>
function fun(...values) {
console.log(values.length)
}
fun(1) //1
fun(1, 2, 3, 4) //4
</script>

箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
//以前声明一个方法
// var print = function(obj){
// console.log(obj);
// }
//一个参数
var print = obj => console.log(obj);
print("hello");

//多个参数
var sum = function (a, b) {
return a + b;
}
var sum2 = (a, b) => a + b;
console.log(sum2(11, 12));

//多个参数多行代码
var sum3 = function (a, b) {
c = a + b;
return a + c;
}
var sum4 = (a,b)=>{
c = a + b;
return a + c;
};
console.log(sum4(11, 12));
</script>

实战:箭头函数结合解构表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//实战:箭头函数结合解构表达式
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
function hello(person) {
console.log("hello," + person.name)
}
//现在的方式
var hello2 = (param) => console.log("hello," + param.name);
hello2(person);
//箭头函数+解构
var hello3 = ({name}) => console.log("hello," + name);
hello3(person);

对象优化

新增的API

ES6给Object拓展了许多新的方法,如:

  • keys(obj):获取对象的所有key形成的数组。
  • values(obj):获取对象的所有value形成的数组。
  • entries(obj):获取对象的所有key和value形成的二维数组。格式:[[k1,v1],[k2,v2],...]
  • assign(dest,…src):将多个src对象的值 拷贝到dest中。(第一层为深拷贝,第二层为浅拷贝)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //1.新增的API
    const person = {
    name: "jack",
    age: 21,
    language: ['java', 'js', 'css']
    }
    console.log(Object.keys(person));//["name","age","language"]
    console.log(Object.values(person));//["jack",21,Arrays(3)]
    console.log(Object.entries(person));//[Arr,ay(2),Arrays(2),Arrays(2)]

    const target = { a: 1 };
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    //Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。
    Object.assign(target, source1, source2);
    console.log(target)//{a: 1, b: 2, c: 3}

声明对象简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//对象的函数属性简写
let person3 = {
name: "jack",
//以前:
eat: function (food) {
console.log(this.name + "在吃" + food);
},
//箭头函数版,这里拿不到this
eat2: food => console.log(person3.name + "在吃" + food),
//简写版
eat3(food) {
console.log(this.name + "在吃" + food)
}
}
person3.eat("apple");//jack在吃apple

对象拓展运算符

拓展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象。

1
2
3
4
5
6
7
8
9
10
//4.对象拓展运算符
//(1).拷贝对象(深拷贝)
let person4 = { name: "Amy", age: 15 }
let someone = { ...person4 }
console.log(someone)//{name: "Amy", age: 15}
//(2).合并对象
let age1 = { age: 15 }
let name1 = { name: "Amy" }
let person5 = { ...age1, ...name1 }//如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值
console.log(person5)//{age: 15, name: "Amy"}

map和reduce

map

1
2
3
4
5
6
7
8
9
//map():接受了一个函数,将原数组中所有元素用这个函数处理后放入新数组返回。
let arr = ['1','20','5','3'];

arr = arr.map((item)=>{
return item*2
});

arr = arr.map(item=>item*2);
console.log(arr);//[2, 40, 10, 6]

reduce

语法:
arr.reduce(callback,[initalValue])
reduce为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用reduce的数组。
callback(执行数组中每个值的函数,包含四个参数)

  • 1.previous(上一次调用回调返回的值,或者是提供初始值(initialValue))
  • 2.currentValue(数组中当前被处理的元素)
  • 3.index(当前元素在数组中的索引)
  • 4.array(调用reduce的数组)
    initalValue(作为第一次调用callback的第一个参数。)
    1
    2
    3
    4
    5
    6
    7
     //let arr = [2, 40, 10, 6];
    let result = arr.reduce((a, b) => {
    console.log("上一次处理后:" + a);
    console.log("当前正在处理:" + b);
    return a + b;
    },100);
    console.log(result);

    Promise

    1. Promise语法
    1. 处理异步结果
    1. Promise改造以前嵌套方式
    1. 优化处理

模块化

  • 1.什么是模块化
    模块化就是把代码进行拆分,方便重复利用。类似java中的导包:要使用一个包。必须先导包。而JS中没有包的概念,换来的是模块。
    模块功能主要由两个命令构成:exportimport
    export命令用于规定模块的对外接口。
    import命令用于导入其他模块提供的功能。

  • 2.export
    比如我定义一个js文件:hello.js,里面有一个对象。

    1
    2
    3
    4
    5
    const util = {
    sum(a, b) {
    return a + b;
    }
    }

    我们可以使用export将这个对象导出。

    1
    2
    3
    4
    5
    6
    7
    const util = {
    sum(a, b) {
    return a + b;
    }
    }

    export {util}

    export不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。
    当要导出多个值时,还可以简写。比如我有一个文件:user.js。

    1
    2
    3
    var name = "jack"
    var age = 21
    export { name, age }

    省略名称
    上面的导出代码中,都明确指定了导出的变量名,这样其他人在导入使用时就必须准确写出变量名。否在就会出错。
    因此js提供了default关键字,可以对导出的变量名进行省略。
    例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // const util = {
    // sum(a, b) {
    // return a + b;
    // }
    // }

    // export {util}
    //`export`不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。

    export const util = {
    sum(a, b) {
    return a + b;
    }
    }

    export default {
    sum2(a, b) {
    return a + b;
    }
    }
  • 3.import

    1
    2
    3
    4
    5
    6
    7
    8
    import util from "./hello.js"
    //import abc from "./hello.js"
    import {name,add} from "./user.js"

    util.sum(1,2);
    //abc.sum2(2,3);
    console.name(name);
    add(1,3);
  • 4.测试以上代码

Node.js

前端开发,少不了node.js,node.js是一个基于Chrome V8引擎的JavaScript运行环境。
http://nodejs.cn/api/ 我们关注与node.js的npm功能就可以。
NPM是随同NodeJS一起安装的包管理工具,JavaScript-NPM可以理解为Java-Maven。
(1).官网下载安装node.js,并使用node -v检测版本。
(2).配置npm使用淘宝镜像。npm config set registry http://registry.npm.taobao.org/

Vue

MVVM思想

  • M:即Model,模型,包括数据和一些基本操作。
  • V:即View,视图,页面渲染结果。
  • VM:即View-Model,模型与视图间的双向操作。(无需开发人员干涉)

在MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到view中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。
而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不再关心Model和View之间是如何相互影响的:

  • 只要我们Model发生了改变,View上自然就会表现出来。
  • 当用户修改了View,Model中的数据也会跟着改变。
    开发人员从繁琐的DOM操作中解放出来,把关注点放在如何操作Model上。

Vue简介

Vue.js(读音 /vjuː/, 类似于 view)是一套构建用户界面的渐进式框架。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不易于上手,还便于与第三方或既有项目整合。另一方面,当与现代化的工具链以及各种支持库结合使用,Vue也完全能够为复杂的单页应用提供驱动。

官网:https://cn.vuejs.org/
参考:https://cn.vuejs.org/v2/guide/

Git地址:https://github.com/vuejs/
尤雨溪,Vue.js创造者,Vue Technology创始人,致力于Vue的研究开发。

入门案例

新建并使用VSCode打开文件夹vue2。初始化项目,然后就会生成一个package.json文件,代表它是一个npm来管理的。

1
npm init -y


安装vue依赖。

1
npm install vue


新建一个index.html测试使用vue.js。

在浏览器打开。

在浏览器控制台修改name的值按回车,页面上的值也会跟着改变。

在VSCode中安装插件Vue 2 Snippets

安装vue-devtools插件

vue-devtools是一款基于chrome游览器的插件,用于调试vue应用,这可以极大地提高我们的调试效率。

  • 登录github,获取到vue-devtools源码并下载下来。https://github.com/vuejs/vue-devtools。
  • 打开下载文件,在根目录下执行cmd命令来下载项目的依赖 : npm install
  • 下载依赖结束之后,编译项目,执行cmd命令:npm run build
  • 在chrome浏览器中,打开>更多工具>扩展程序。开启开发者模式。并将项目文件中的chrome文件整体导入。
  • 在浏览器中打开vue-devtools

概念

指定

插值表达式

  • 1.花括号
    格式:{ { } }
    说明:
    • 该表达式支持JS语法,可以调用js内置函数。(必须有返回值)
    • 表达式必须有返回结果。例如1+1,没有结果的表达式不允许使用,如:let a = 1 + 1;
    • 可以直接获取Vue实例中定义的数据或函数。
  • 2.插值闪烁
    使用{ { } }方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{ { } },加载完毕后才显示正常数据,我们称之未插值闪烁。
    我们将网速调慢一些,然后刷新页面,试试看刚才的案例。

v-bind

v-model

v-on

  • 基本用法

  • 事件修饰符
    在事件处理程序中调用event.preventDefault()event.stopPropagation()是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理DOM事件细节。
    为了解决这个问题,Vue.js为v-on提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。

    • .stop:阻止事件冒泡到父元素
    • .prevent:阻止默认事件发生
    • .capture:使用事件捕获模式
    • .self:只有元素自身触发事件才执行(冒泡或捕获的都不执行)
    • .once:只执行一次
  • 按键修饰符
    在监听按键事件时,我们经常需要检查常见的键值。Vue允许为v-on在监听按键事件时添加按键修饰符:

    1
    2
    <!-- 只有在'keyCode'是13时调用'vm.submit' -->
    <input v-on:keyup.13="submit()">

    记住所有的keyCode比较困难,所以Vue为最常用的按键提供了别名:

    1
    2
    3
    4
    <!-- 同上 -->
    <input v-on:keyup.enter="submit()">
    <!-- 缩写语法 -->
    <input @keyup.enter="submit()">

    全部的按键别名:
    .enter
    .tab
    .delete(捕获”删除”和”退格”键)
    .esc
    .space
    .up
    .down
    .left
    .right

  • 组合按键
    可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或者键盘事件的监听器。
    .ctrl
    .alt
    .shift

    1
    2
    3
    4
    <!-- Alt + C -->
    <input @keyup.alt.67="clear">
    <!-- Ctrl + Click -->
    <div @click.ctrl="doSomething">Do something</div>

v-for

v-of和v-show

v-else和v-else-if

计算属性和侦听器

组件化

在大型应用开发的时候,页面可以划分很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独立开发,这无疑增加了我们的开发成本。所以我们把页面的不同部分拆开城独立的组件,然后再不同页面就可以共享这些组件,避免重复开发。
在vue中,所有的vue实例都是组件。

全局组件

  • 组件其实也是一个Vue实例,因此它在定义时也会接受:data、methods、声明周期函数等。
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
  • data必须是一个函数,不再是一个对象。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <body>
    <div id="app">
    <button v-on:click="count++">我被点击了{{count}}次</button>
    <counter></counter>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
    //1.全局声明注册一个组件
    Vue.component("counter", {
    template: `<button v-on:click="count++">我被点击了{{count}}次</button>`,
    data() {
    return {
    count: 1
    }
    }
    });
    new Vue({
    el: "#app",
    data: {
    count: 1
    }
    });
    </script>
    </body>

    组件的复用

    局部组件

    定义好的组件,可以任意复用多次:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //2.局部声明一个组件
    const buttonCounter = {
    template: `<button v-on:click="count++">我被点击了{{count}}次~~~~</button>`,
    data() {
    return {
    count: 1
    }
    }
    };

生命周期和钩子函数

生命周期

每个Vue实例被创建时都要经过一系列的初始化过程:创建实例、装载模板、渲染模板等等。Vue为生命的每个状态都设置了钩子函数(监听函数)。每当Vue实例对于不同的生命周期时,对应的函数就会被触发调用。
生命周期:你不需要立马弄明白所有的东西。
生命周期图示

钩子函数

vue模块化开发

npm install webpack -g

全局安装webpack

npm install -g@vue/cli-init

全局安装vue脚手架

初始化vue项目

vue init webpack appname:vue脚手架使用webpack模块化初始化一个appname项目

启动vue项目

项目的package.json中有scripts,代表我们能运行的命令。
npm start=npm run dev:启动项目

使用Vue脚手架

自定义组件

整合ElementUI快速开发

https://element.eleme.cn/#/zh-CN/component/installation

Babel

Babel是一个JavaScript编译器,我们可以使用es的最新语法编程,而不用担心浏览器兼容问题。他会自动转化为浏览器兼容的代码。

Webpack

自动化项目构建工具。gulp也是同类产品。

结束语

评论