ES6
ES6简介
ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如JavaScript则是规范的具体实现;
JavaScript三大组成部分:
**ECMAScript**
:语句语法规范;**BOM**
:浏览器对象模型;-
ES6新特性
let 声明变量
1、
var声明的变量往往会越域 ,**let**声明的变量有严格局部作用域
<script>
{
var a = 1;
let b = 2;
}
console.log(a);
console.log(b);
</script>
2、
var可以声明多次,**let**只能声明一次
<script>
var m=1;
var m=3;
let n=2;
</script>
3、
var会变量提升,let不存在变量提升
<script>
console.log("x的值:"+x);//声明前使用
var x = 10;
console.log("y的值:"+y);//声明前使用
let y = 20;
</script>
const声明常量(只读变量)
<script>
//1.声明之后不允许改变
//2.一但声明必须初始化,否则会报错
const a=1;
</script>
解构表达式
用数组结构赋值(方便)
<script>
let arr=[1,2,3];
//用数组结构将1,2,3分别赋值给x,y,z
let [x,y,z] = arr;
</script>
对象结构
<script>
//先声明一个常量
const person={
name:"张三",
age:"19",
language:["java","english","chinese"]
}
//将name,age,language三个属性拿出来
const {name,age,language}=person;
//将name的属性值赋值到abc中
const{name:abc}=person;
console.log(name,age,language,abc);
</script>
字符串扩展
几个新的 API
<script>
//字符串扩展
let str = "hello.vue";
console.log(str.startsWith("hello"));
//判断是否以"hello"开始,返回true
console.log(str.endsWith(".vue"));
//判断是否以".vueo"结束,返回true
console.log(str.includes("e"));
//判断是否含"e",返回true
console.log(str.includes("hello"));
//判断是否含"hello",返回true
</script>
字符串模板
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
</script> //1、声明多行字符串,以前还需要拼串,现在不需要了 let xml=` <div> <span>hello world<span> </div>`; console.log(xml); //2、字符串插入变量和表达式。变量名写在${}中,${}中也可以写表达式,写方法; let name1 = "张三"; let age1 = 18; let info = `我是${name1},今年${age1+10}了`; console.log(info) </script>
函数优化
函数参数默认值
<script> /*以前的做法*/ function add(a, b) { //判断b是否为空,为空就给默认值1 b = b || 1; return a + b; } // 传一个参数 console.log(add(10)); /*现在新特性的做法*/ function add1(a,b=1){ return a+b; } console.log(add1(10)) </script>
不定参数
<script> function say(...canshu){ console.log(canshu.length)//输出参数的个数 } say(1);//输出1个 say(1,2,3,4,5,6,7,6)//输出8个 </script>
箭头函数
</script> /*箭头函数*/ var print1=obj => console.log(obj); //只有一个参数且方法体只有一行的方法 print1("hello")//调用 var print2=(a,b)=>a+b; //多个参数,只有一行返回值 console.log(print2(1,2)) var print3=(a,b)=>{ c=a+b; return c*c; }//多个参数,方法体不止一行 console.log(print3(1,2)) </script>
对象优化
ES6 给Object 拓展了许多新的方法,如:
keys(obj)
:获取对象的所有key
形成的数组values(obj)
:获取对象的所有value
形成的数组entries(obj)
:获取对象的所有key
和value
形成的二维数组。格式:[[k1,v1],[k2,v2],...]
;assign(dest, ...src)
:将多个src
对象的值拷贝到dest
中。(第一层为深拷贝,第二层为浅拷贝)<script> /*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, Array(3)] console.log(Object.entries(person));//打印出key,value 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} /*2、声明对象简写*/ const age = 23 const name = "张三" // 传统 const person1 = { age: age, name: name } console.log(person1) // ES6:属性名和属性值变量名一样,可以省略 const person2 = { age, name } console.log(person2) //{age: 23, name: "张三"} /*3、对象的函数属性简写*/ 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 person3.eat2("apple");//jack在吃apple person3.eat3("apple");//jack在吃apple </script>
对象拓展运算符
拓展运算符
{...}
用于取出参数对象所有可遍历属性然后拷贝到当前对象。<script> // 1、拷贝对象(深拷贝) let p1 = { name: "Amy", age: 15 } let someone = { ...p1 }//将p1的属性以及值拷贝到someone中 // 2、合并对象 let myage = { age: 15 } let myname = { name: "Amy" } let p2 = { ...myage, ...myname }//将这两者的属性以及值拷贝到p2中 //如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值 console.log(p2) //{age: 15, name: "Amy"} </script>
map
和reduce
方法map
接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
<script> let arr = ['1', '20', '-5', '3']; console.log(arr) //数组中的字符都转化为数字,并*2 arr = arr.map(s => parseInt(s)*2); console.log(arr) </script>
reduce
语法:
arr.reduce(callback,[initialValue])
**reduce**
为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用**reduce**
的数组。**callback**
(执行数组中每个值的函数,包含四个参数)previousValue
(上一次调用回调返回的值,或者是提供的初始值(initialValue
))currentValue
(数组中当前被处理的元素)index
(当前元素在数组中的索引)array
(调用reduce
的数组)
initialValue
(作为第一次调用callback
的第一个参数。)
<script>
let arr1 = [2, 40, -10, 6];
let result=arr.reduce((a,b) => {
console.log("上一次处理后:"+a)
console.log("当前正在处理:"+b)
return a+b;
},100)
console.log(result);
</script>
Promise
在JavaScript
的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript
的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。一旦有一连串的ajax
请求a,b,c,d...
后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层层嵌套的方式,非常容易造成上下文代码混乱,我们不得不非常小心翼翼处理内层函数与外层函数的数据,一旦内层函数使用了上层函数的变量,这种混乱程度就会加剧……总之,这种层叠上下文的层层嵌套方式,着实增加了神经的紧张程度。
场景
- 查出当前用户信息;
- 按照当前用户的id查出他的课程;
- 按照当前课程id查出分数;
传统嵌套方法(比较乱)
<script> /* 1、查出当前用户信息 2、按照当前用户的id查出他的课程 3、按照当前课程id查出分数 */ //以前的方法 $.ajax({ url:"mock/user.json", success(data){ console.log("查询用户:",data); $.ajax({ url:`mock/user_corse_${data.id}.json`, success(data){ console.log("查询到课程:",data); $.ajax({ url:`mock/corse_score_${data.id}.json`, success(data){ console.log("查询到课程分数:",data); } }); }, }); }, }); </script>
使用Promise
<script> //使用promise封装异步操作 //1、先声明一个公用函数 function get(url,data){ return new Promise((ifsuccess,iferror)=>{ $.ajax({ url:url, data:data, success:function(data){ ifsuccess(data)//成功的话 }, error:function(err){ iferror(data)//失败的话 } }); }); } //2、进行操作 get("mock/user.json") .then((data)=>{//动态取值就需要用``号不能用双引号 console.log("查询用户:",data); return get(`mock/user_corse_${data.id}.json`); }).then((data)=>{//then得到上一步成功的数据 console.log("查询到课程:",data); return get(`mock/corse_score_${data.id}.json`); }).then((data)=>{ console.log("查询到课程成绩:",data); }).catch((err)=>{ console.log("出现异常:",err); }); </script>
模块化
什么是模块化
模块化就是把代码进行拆分,方便重复利用。类似java
中的导包:要使用一个包,必须先 导包。而JS
中没有包的概念,换来的是模块。
模块功能主要由两个命令构成:export
和import
。
export
命令用于规定模块的对外接口。-
导出export
const util={ sum(a,b){ return a+b; } } var name="zzk" export {util,name} //还可以简写为: // export const util={ // sum(a,b){ // return a+b; // } // }
export
不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。
导入import
import util from "./hello.js"//“./”一个点“.”代表当前目录 import name from "./hello.js" //也可以直接import {util,name} from "./hello.js" var c=util.sum(1,2) console.log(c) console.log(name)
vue
更多信息访问vue官网:vuejs.org
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
上。
安装
npm安装:**npm install vue**
(安装最新稳定版)之后通过**<script>**
标签引入
【注意:npm安装的话你的project名不能和安装的依赖同名】
也可以直接下载然后**<script>**
标签下引入;
npm安装:
- 先执行初始化命令
**npm init -y**
表示此项目交由npm管理,之后就会生成一个文件package.json
, 之后再执行命令
**npm install vue**
安装(如果安装特定版本可以直接在**vue**
后面加**@版本号**
);使用
helloworld程序:
<div id="app"> <h1>{{name}},很帅</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> let vm=new Vue({ el: "#app", data: { name: "张三" } }) </script>
双向绑定
效果:我们修改表单项,num会发生变化。我们修改 num,表单项也会发生变化。为了实时观察到这个变化,我们将num输出到页面。
我们不需要关注他们为什么会建立起来关联,以及页面如何变化,我们只需要做好数据和视图的关联即可(MVVM)<div id="app"> <input type="text" v-model="num"> <h1>{{name}},很帅,{{num}}人为他点赞</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> let vm=new Vue({ //属性名和属性值一样的时候可以只写“属性(名|值),” el: "#app", data: { name: "张三", num: 1 } }) </script>
输入框标签里面添加一个属性_v-model_
并赋值,在需要输出的地方_{{这个属性值}}_
,然后在vue对象的data属性值添加上该值并附上默认值即可;事件处理
在标签中添加一个属性
v-on:xxx="xxx"
,其中xxx
为要对某个属性做的操作,例如还是上面的例子,我添加一个<button_v-on:click_="num++">点赞</button>
则每点击一次则vue
实例中data
属性中的num
属性就会+1;
还可以单独写一个方法,点击时调用这个方法来操作数据(把方法都放在vue实例的methods
属性里面);<button v-on:click="cancle">取消点赞</button> ... <script> let vm=new Vue({ el: "#app", //与某元素绑定属性 data: { //封装数据 name: "张三", num: 11 }, methods:{ //封装方法 cancle(){ this.num--; } } }) </script>
指令
v-text
和v-html
可以使用
v-text
和v-html
指令来替代双大括号{{}}
说明:
**v-text**
:将数据输出到元素内部,如果输出的数据有HTML
代码,会作为普通文本输出;**v-html**
:将数据输出到元素内部,如果输出的数据有HTML
代码,会被渲染;-
v-bind
(单向绑定)**v-bind**
给html标签的属性进行绑定(即双引号里面的内容)<!-- 给html标签的属性进行绑定 --> <div id="app"> <a v-bind:href="link">go baidu</a> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data:{ link: "http://www.baidu.com" }, }); </script>
并且还对属性style
和class
做了单独的增强:<!-- 给html标签的属性进行绑定 --> <div id="app"> <a v-bind:href="link">go baidu</a><br> <!-- 还对class属性和style属性进行了增强 --> <span v-bind:class="{active:isActive,'text-danger':hasError}" v-bind:style="{color:clo,fontSize:fsize}">测试</span> <!-- 根据isActive的bool值进行判断是否class="active" --> <!--根据hasError的bool值进行判断是否class="'text-danger'" (因为“-”是非法的,所以加个单引号,也可直接驼峰命名textDnger)--> <!-- 下面同理 --> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data:{ link: "http://www.baidu.com", isActive:false, hasError:true, clo:'red', fsize: '66px' }, });
v-model
(双向绑定)<div id="app"> 请选择: <br> <input type="checkbox" v-model="language" value="java"><br> <input type="checkbox" v-model="language" value="phpa"><br> <input type="checkbox" v-model="language" value="golang"><br> 你选择的有: <span v-text="language"></span> </div> <script> let vm=new Vue({ el:"#app", data:{ language:[] //选中的属性值把存在language的数组里面 }, }) </script>
<div id="app"> <h1>你写的是:{{msg}}</h1> <br> <input type="text" v-model:value="msg"> <!--value可省略,即写为v-modele="msg"--> </div> <script> new Vue({ el: '#app', data: { msg:"" } }) </script>
v-on
基础用法
调用事件,例如调用点击事件:
<div id="app"> <button v-on:click="numAdd">+{{num}}</button><br> <!--也可以简写:@click=xxx--> <span v-text="num"></span> </div> <script> new Vue({ el:"#app", data:{ num: 1 }, methods:{ numAdd(){ this.num+=2 } } }); </script>
事件修饰符
事件冒泡问题:子元素的操作连带了父元素;例如:
<div id="try" v-on:click="hello"> 大div <br> <div @click="hello"> 小div </div> </div> <script> new Vue({ el: '#try', methods:{ hello(){ alert("点击了") } }, }); </script>
这样的话点击“小div”的话就会
alert("点击了")
两次,这就属于时间冒泡事件;
为了解决这个问题,Vue.js 为v-on
提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。 .stop
:阻止事件冒泡到父元素;.prevent
:阻止默认事件发生;.capture
:使用事件捕获模式;.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
:只执行一次;
这里就可以用:<div_@click.stop_="hello">
按键修饰符(v-on:keyup
或@keyup
)
在监听键盘事件时,我们经常需要检查常见的键值。Vue允许为v-on
在监听键盘事件时添加按键修饰符;
全部的按键别名:
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
例如:在一个输入框内按”上键”数值增加,按”下键”数值减少,如下:<inputv-model="num1"type="text"v-on:keyup.up="num1++"@keyup.down="num1--">
也可以用设置组合键,例如:<inputv-model="num1"@click.ctrl="num1+=10">
这样ctrl+单击
数据就会+10;
v-for
遍历用的;
<div id="app">
<ul>
<li v-for="(user,index) in users":key="user.name">
<!--遍历的时候加上“:key”来区分不同数据,提高vue渲染效率,key值为数据里面的唯一属性-->
<!--第一个参数是值,第二个参数值索引-->
当前索引:{{index}};当前元素值:{{user.name}}--->{{user.age}} <br>
</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data:{
//定义一个对象数组
users:[
{name:"张三",age:12},
{name:"李宗盛",age:22},
{name:"瘦鸡",age:32},
{name:"事件",age:42},
{name:"微软",age:15},
]
}
});
</script>
v-if
和v-show
<h1 v-if="bool">如果bool=true就看到我v-if</h1><br>
<h1 v-show="bool">如果bool=true就看到我v-show</h1><br>
不同的是当bool=false
时v-if
所在元素是消失,而v-show
所在元素是用style="display: none;"
修饰:
计算属性和侦听器
<div id="app">
<ul>
<li>西游记;价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传;价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"></li>
<li>总价:{{totalPrice}}</li>
</ul>
{{msg}}
</div>
<script>
new Vue({
el: '#app',
data:{
xyjPrice: 190.1,
shzPrice: 12.12,
xyjNum: 1,
shzNum: 1,
msg: "",
},
computed:{//声明一个计算属性
totalPrice(){//完成总价的计算
return this.xyjNum*this.xyjPrice+this.shzNum*this.shzPrice
}
},
watch:{//声明一个监听器,监听西游记的数量
xyjNum: function(newVal,oldVal){
//新式语法可以直接写为: xyjNum:(..){..}
if(newVal>3){
this.msg="购买数量过多"
}else{
this.msg=""
}
}
},
});
</script>
过滤器
过滤器不改变真正的data
,而只是改变渲染的结果,并返回过滤后的版本。在很多不同的情况下,过滤器都是有用的,比如尽可能保持API
响应的干净,并在前端处理数据的格式。
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}}===>{{user.name}}==>{{user.age}}
==>{{user.age|ageFilter}}==>{{user.age|gFilter}}<br>
<!--用管道符“|”将user.age传入ageFilter方法的参数中-->
</li>
</ul>
</div>
<script>
//声明一个全局过滤器
//(必须声明在局部过滤器之前,否则全局过滤器失效)
Vue.filter("gFilter",function(val){
if(val>=18){
return"成年~~~~~";
}else{
return"未成年~~~~";
}
});
new Vue({
el:"#app",
data:{
userList:[
{id:1,name:"张三",age:13},
{id:2,name:"张静怡",age:23},
{id:3,name:"张诺",age:17},
]
},
filters:{//声明一个局部过滤器
ageFilter(val){
if(val>=18){
return"成年";
}else{
return"未成年";
}
}
},
});
</script>
组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。
所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。在vue
里,所有的vue
实例都是组件;
全局组件
<div id="app">
<counter></counter> <!--调用自定义全局组件-->
<!--用组件名声明一个标签名 -->
</div>
<script>
//1、全局声明注册一个组件
Vue.component('counter',{//参数是组件名
template: '<button @click="count++">我被点击了{{count}}次</button>',
data(){
return{count:1}
}
});
new Vue({
el:"#app",
data:{
count: 1,
}
});
</script>
- 组件其实也是一个
**Vue**
实例,因此它在定义时也会接收:data
、methods
、生命周期函数
等 - 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有
el
属性。 - 但是组件渲染需要
html
模板,所以增加了template
属性,值就是HTML模板 ; - 全局组件定义完毕,任何
vue
实例都可以直接在HTML中通过组件名称来使用组件了 data
必须是一个函数,不再是一个对象;
局部组件
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue
的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用局部注册。
<div id="root">
<!--调用自定义局部组件-->
<my-counter></my-counter>
</div>
<script>
//声明一个局部组件
const myCounter={
template: '<button @click="count++">我被点击{{count}}次</button>',
data(){
return{count:1}
}
};
new Vue({
el:"#root",
data:{
count:1
},
//components就是当前vue对象子组件集合。
components:{//在此放入所有自定义局部组件
'my-counter':myCounter
}
});
</script>
组件的**data**
属性必须是函数!一个组件的data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝;
Vue
生命周期和钩子函数
生命周期
每个Vue
实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue
为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue
实例处于不同的生命周期时,对应的函数就会被触发调用。
钩子函数使用
beforeCreated
:我们在用Vue
时都要进行实例化,因此,该函数就是在Vue
实例化时调用,也可以将他理解为初始化函数比较方便一点,在Vue1.0时,这个函数的名字就是init。created
:在创建实例之后进行调用。beforeMount
:页面加载完成,没有渲染。如:此时页面还是{{name}}
;mounted
:我们可以将他理解为原生js
中的window.onload=function({.,.});
或许大家也在用jquery
,所以也可以理解为jquery
中的$(document).ready(function(){….})
,他的功能就是:在dom
文档渲染完毕之后将要执行的函数,该函数在 Vue1.0 版本中名字为compiled
。 此时页面中的{{name}}
已被渲染成张山;beforeDestroy
:该函数将在销毁实例前进行调用。destroyed
:改函数将在销毁实例时进行调用。beforeUpdate
:组件更新之前。updated
:组件更新之后。<div id="root"> <button @click="age++">{{name}}:{{age}}</button> </div> <script> new Vue({ el: '#root', data:{ name:"张山", age:1, }, beforeCreate() { console.log("数据模型加载前"); }, created(){ console.log("数据模型加载完成"); }, beforeMount(){ console.log("页面加载完成,没有渲染"); }, beforeDestroy(){ console.log("实例销毁前"); }, destroyed(){ console.log("实例销毁完成"); }, beforeUpdate(){ console.log("准备修改") } }); </script>
使用Vue脚手架进行模块化开发
初始化步骤:
1、全局安装webpack:
npm install webpack -g
2、安装vue
脚手架(这里与老师版本一致4.0.3
):npm i -g @vue/cli@4.0.3 --force
- (
--force
表示覆盖以前的vue脚手架版本) - 可用命令
vue-V
检查所安装vue
脚手架版本或是否安装成功vue
脚手架;
- (
3、初始化项目:vue init webpack 项目名
(vue
脚手架使用webpack
模板初始化项目)
4、进入都初始化项目的vue-demo
目录里面,执行语句npm run dev
项目运行,运行成功浏览器访问http://localhost:8080/
,如下:
项目结构
运行流程:
- 进入页面首先加载
index.html
和main.js
文件。 main.js
导入了一些模块【vue、app、router
】,并且创建vue实例,关联index.html
页面的<div id=”app”>
元素。使用了router
,导入了App组件。并且使用<App/>
标签引用了这个组件;- 第一次默认显示App组件。App组件有个图片和
<router-view>
,所以显示了图片。但是由于<router-view>
代表路由的视图,默认是访问/#/路径(router路径默认使用HASH模式)。在router中配置的/是显示HelloWorld
组件。 - 所以第一次访问,显示图片和
HelloWorld
组件。 我们尝试自己写一个组件,并且加入路由。点击跳转。需要使用
<router-link to="/foo">Go to Foo</router-link>
标签;手动构建一个单文件组件
// 组件三要素:template,script,style <template> <div> <h1>你好hello{{name}}</h1> </div> </template> <script> export default{ data() { return { name: '张静怡', }; }, } </script> <style> </style>
然后在
**router**
里面加上这个vue
的路由;... import Hello from '@/components/Hello' //引入刚才创建的Hello.vue ... //下面创建这个路由 { path: '/hello', name: "hello", component: Hello, }
详情见官网:vueRouter;
Vue整合ElementUI快速开发
elementUI组件库网址:element.eleme.cn
npm安装:
npm i element-ui -S
(也可以手动下载下来)- 之后在
main.js
里面引入:importElementUIfrom'element-ui';
import'element-ui/lib/theme-chalk/index.css';
- 之后让
Vue
使用ElementUI
:Vue.use(ElementUI)
-
axios
axios
是独立于vue
的一个项目,基于promise用于浏览器和node.js
的http
客户端; 在浏览器中可以帮助我们完成
ajax
请求的发送;-
nodejs
nodejs
是**JavaScript**
运行环境,类似于java
里面的jdk
,不需要浏览器通过nodejs
直接运行js
文件;简介
什么是
Node.js
简单的说
Node.js
就是运行在服务端的JavaScript
。Node.js
是一个事件驱动I/O服务端JavaScript
环境,基于Google的V8引擎,V8引擎执行Javascript
的速度非常快,性能非常好。Node.js
有什么用 如果你是一个前端程序员,你不懂得像PHP、Python或Ruby等动态编程语言,然后你想创建自己的服务,那么
Node.js
是一个非常好的选择。Node.js
是运行在服务端的JavaScript
,如果你熟悉Javascript
,那么你将会很容易的学会Node.js
。- 当然,如果你是后端程序员,想部署一些高性能的服务,那么学习
Node.js
也是一个非常好的选择。
**cmd**
查看**nodejs**
版本:**node -v**
;
npm
npm
简介
什么是npm
npm
全称Node Package Manager,是Node.js
包管理工具,是全球最大的模块生态系统,里面所有的模块都是开源免费的;也是Node.js
的包管理工具,相当于前端的Maven
。
npm
工具的安装位置
我们通过npm
可以很方便地下载**js**
库,管理前端工程。Node.js
默认安装的npm
包和工具的位置:Node.js目录\node_modules
- 在这个目录下你可以看见
npm
目录,npm
本身就是被npm
包管理器管理的一个工具,说明Node.js
已经集成了npm
工具; **cmd**
查看npm
版本:npm** -v**
;使用
项目初始化
**cmd**
在目标文件夹内执行命令**npm init**
执行初始化(会让你选择默认js
文件name
属性,vue
版本等信息,也可以直接执行**npm init -y**
全部使用默认值);按照提示输入相关信息,如果是用默认值则直接回车即可。
name:项目名称;
version:项目版本号;
description:项目描述;
keywords:{Array}关键词,便于用户搜索到我们的项目;
最后会生成
package.json
文件,这个是包的配置文件,相当于maven
的pom.xml
我们之后也可以根据需要进行修改。
修改npm
镜像
- 设置淘宝镜像:
npm config set registry https://registry.npm.taobao.org
; - 查看
**npm**
配置信息:npm config list
; - 测试,比如下载
**jquery**
:npm install jquery
; - 也可以直接根据配置文件下载:直接根据配置文件下载,直接执行
npm install
;- #使用
**npm install**
安装依赖包的最新版, - #模块安装的位置:
**项目目录\node_modules**
- #安装会自动在项目目录下添加
**package-lock.json**
文件,这个文件帮助锁定安装包的版本 - #同时
**package.json**
文件中,依赖包会被添加到**dependencies**
节点下,类似**maven**
中的**<dependencies>**
- #
**npm**
管理的项目在备份和传输的时候一般不携带**node_modules**
文件夹
**npm install**
- #根据
**package.json**
中的配置下载依赖,初始化项目
**npm install jquery@指定版本号**
- #如果安装时想指定特定的版本
# 局部安装:依赖只在当前项目中能用
- #
**devDependencies**
节点:开发时的依赖包,项目打包到生产环境的时候不包含的依赖 - #使用-D参数将依赖添加到
**devDependencies**
节点 **npm install --save-dev eslint**
#或**npm install -D eslint**
#全局安装
- #Node.js全局安装的npm包和工具的位置:
**用户目录\AppData\Roaming\npm\node_modules**
- #一些命令行工具常使用全局安装的方式
**npm install -g webpack**
- #使用
#更新包(更新到最新版本) npm update 包名 #全局更新 npm update -g 包名 #卸载包 npm uninstall 包名 #全局卸载 npm uninstall -g 包名
模块化开发
es5
写法
自定义方法
//定义两个自定义方法
const sum=function(a,b){
return parseInt(a)+parseInt(b);
}
const subtract=function(a,b){
return parseInt(a)-parseInt(b);
}
//设置2个方法可以被其他js调用
module.exports={
sum,subtract
}
调用自定义方法
/*调用自定义方法*/
const m=require('./myMethod.js')
console.log(m.sum(1,1));
console.log(m.subtract(1,1));
结果
PS E:\IDEAworks\classroom\moduleDemo\es5> node .\useMyMethod.js 2 0
es6
写法
注:**es6不能直接用,需要进行转码,转码过程较为复杂,之后在框架中会直接进行转码,这里不转码**
自定义方法
/*自定义方法:myMethod.js*/
//定义两个可以被其他js调用的自定义方法
//定义方法-1
export function sum(a,b){
return parseInt(a)+parseInt(b);
}
export function subtract(a,b){
return parseInt(a)-parseInt(b);
}
//定义方法-2
export default{
sum(a,b){
return parseInt(a)+parseInt(b);
},
subtract(a,b){
return parseInt(a)-parseInt(b);
}
}
调用自定义方法
/*调用自定义方法:useMyMethod.js*/
//调用方法-1
import {sum,subtract} from "./myMethod1.js"
console.log(sum(1,1));
console.log(subtract(1,1));
//调用方法-2
import * as m from "./myMethod1.js"
console.log(m.sum(1,1));
console.log(m.subtract(1,1));
跨域问题
比如前后端调用,**3**
个地方:**访问协议**
,**访问ip**
,**端口号**
有任何一个不一样就会产生跨域问题,不能正常访问,跨域问题本质是浏览器对ajax
请求的一种限制;
解决
- 在后端接口
controller
添加注解**@CrossOrigin**
; - 使用
httpclient
; - 通过
gateway
网关;