+Vue简介
SoC:关注度分离原则
Vue只关注视图层
HTML+CSS+JS: 视图:给用户看 刷新后台数据
尤雨溪 发布于2014年2月;
网络通信:axios
页面跳转:vue-router
状态管理:vuex
前段三要素 HTML结构+CSS(表现)+JavaScript(行为)
CSS预处理器
CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行CSS的编码工作。转化成通俗易懂的话来说就是“用一种专门的编程语言,进行Web 页面样式设计,再通过编译器转化为正常的CSS文件,以供项目使用”。
常用的CSS预处理器有哪些
- SASS:基于 Ruby,通过服务端处理,功能强大。解析效率高。需要学习Ruby 语言,上手难度高于LESS。
- LESS:基于NodeJS,通过客户端处理,使用简单。功能比 SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以我们后台人员如果需要的话,建议使用LESS。
虚拟Dom:利用内存;
计算属性–>Vue特色
JavaScript框架
-
jQuery:大家熟知的JavaScript 框架,优点是简化了DOM操作,缺点是DOM操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6、7、8;
-
Angular: Google 收购的前端框架,由一群Java程序员开发,其特点是将后台的 MVC模式搬到了前端并增加了模块化开发的理念,与微软合作,采用TypeScript语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如:1代->2代,除了名字,基本就是两个东西;截止发表博客时已推出了 Angular6)
-
React: Facebook出品,一款高性能的」JS前端框架;特点是提出了新概念【虚拟DOM】用于减少真实DOM操作,在内存中模拟DOM 操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习—门【sX】语言;
-
vue :
一款渐进式JavaScript框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了Angular(模块化)和React(虚拟 DOM)的优点; -
Axios:
前端通信框架;因为 vue的边界很明确,就是为了处理DOM,所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery 提供的AJAX通信功能;
后台开发
前端为主的MV*时代
此处的MV*模式如下:
- MvC(同步通信为主): Model、View、Controller
- MVP(异步通信为主): Model、View、Presenter
- MVVM(异步通信为主): Model、View、ViewModel
为了降低前端开发复杂度,涌现了大量的前端框架,比如: Angu ls 、 React , Vue.js 、EmberJs等,这些框架总的原则是先按类型分层,比如Templates、Controllers、Models,然后再在层内做切分,如下图:
MVVM组成部分
第一个vue程序
【说明】IDEA可以安装Vue 的插件!
注意:Vue 不支持 IE8及以下版本,因为Vue使用了IE8无法模拟的ECMAScript5特性。但它支持所有兼容ECMAScript 5 的浏览器。
什么是MVVM
MVVM (Model-View-ViewModel)是一种软件架构设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行的 WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是 WPF和Silverlight的架构师)于2005年在他的博客上发表。
MVVM源自于经典的MVC (Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用,其作用如下:
- 该层向上与视图层进行双向数据绑定
- 向下与Model层通过接口请求进行数据交互
MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有vue.js , Angulars等。
为什么要使用MVVM
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处
- 低耦合:视图(View)可以独立于 Model变化和修改,一个ViewModel可以绑定到不同的View 上,当View 变化的时候Model可以不变,当Model变化的时候View 也可以不变。
- 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
- 独立开发:开发人员可以专注于业务逻辑和数据的开发〔ViewModel),设计人员可以专注于页面设计。
- 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
MVVM组成部分
下载地址
开发版本
- 包含完整的警告和调试模式:https://vuejsorg/js/vue.js
- 删除了警告 30.96KB min + gzip: https://vuejs.org/js/js/vue.min.js
CDN:
第一个Vue程序
<!--view层 模板-->
<div id="app">
{{message}}
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
message:"hello,vue"
}
});
</script>
VUE基本语法
{{}}
<div id="app">
{{message}}
</div>
绑定 v-bind
缩写v-bind:title==:title
<span v-bind:title="message">
嘿嘿
</span>
你看到的v-bind等被称为指令。指令带有前缀v-,以表示它们是Vue提供的特殊特性。可能你已经猜到了,它们会在渲染的DOM上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元索节点的title特性和Vue 实例的message 属性保持—致”。
如果你再次打开浏览器的JavaScript 控制台,输入app.message = ‘新消息’,就会再一次看到这个绑定了title 特性的HTML已经进行了更新。
判断 v-if v-else-if v-else
<!--view层 模板-->
<div id="app">
<h1 v-if="ok">true</h1>//ok为真
<h1 v-else>False</h1>
</div>
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else>C</h1>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data: {
type: "A"
}
});
</script>
循环 v-for
<!--view层 模板-->
<!--<div id="app">
<li v-for="item in items">
{{item.message}}
</li>
</div>-->
<div id="app"> //index 下标
<li v-for="(item,index) in items">
{{item.message}}---{{index}}
</li>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
items: [
{message: "狂神说Java"},
{message: "狂神说前端"},
{message: "狂神说运维"},
]
}
});
</script>
绑定事件 v-on
v-on:事件=
缩写 v-on:事件= == @事件
<!--view层 模板-->
<div id="app">
<button v-on:click="sayHi">Click me</button>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
message: "狂神说Java"
},
methods:{ //方法必须写在Vue的methods对象中
sayHi: function () {
alert(this.message);
}
}
});
</script>
双向绑定 v-model
什么是双向数据绑定
Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是 Vue.js 的精髓之处了。
值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。
为什么要实现数据的双向绑定
在vue.js中,如果使用vuex,实际上数据还是单向的,之所以说是数据双向绑定,这是用的UI控件来说,对于我们处理表单,Vue.js的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。
在表单中使用双向数据绑定
你可以用v-model指令在表单<input>
,<textarea>
及<select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元索。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行―些特殊处理。
注意: v-model 会忽略所有表单元素的value,checked、selected特性的初始值而总是将Vue 实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!
输入框
<div id="app">
输入框<input type="text" v-model="message">{{message}}
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
message:""
}
});
</script>
单选框
<input type="radio" value="男" v-model="sex">男
<input type="radio" value="女" v-model="sex">女
<p>
选中了谁:{{sex}}
</p>
多选框
爱好:
<input type="checkbox" name="vehicle" value="Bike" v-model="loves">吃饭
<input type="checkbox" name="vehicle" value="Car1" v-model="loves">睡觉
<input type="checkbox" name="vehicle" value="Car2" v-model="loves">打豆豆
<input type="checkbox" name="vehicle" value="Car3" v-model="loves">旅游
<p>
<li v-for="love in loves">{{love}}</li>
</p>
下拉框
下拉框:
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>value:{{selected}}</span>
注意:如果v-model表达式的初始值未能匹配任何选项,<select>
元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS不会触发change事件。因此,更推荐像上面这样提供—个值为空的禁用选项。
组件
组件是可复用的 vue 实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签、Thymeleaf的 th:fragment等框架有着异曲同工之妙。通常一个应用会以一棵嵌套的组件树的形式来组织:
<div id="app">
<shijie></shijie>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
//定义一个Vue组件component
Vue.component("shijie",{
template:'<li>wuhuhahei</li>>'
});
</script>
<!--view层 模板-->
<div id="app">
<!-- 组件,传递给组件中的值;props -->
<shijie v-for="item in items" v-bind:qin="item"></shijie>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
Vue.component("shijie",{
props:['qin'],
template:'<li>{{qin}}</li>>'
});
var vm = new Vue({
el:"#app",
//Model:数据
data:{
items:["Java","Linux","前端"]
}
});
</script>
说明
- v-for="item in items”:遍历vue 实例中定义的名为 items 的数组,并创建同等数量的组件
- v-bind: item=“item”:将遍历的 item项绑定到组件中 props定义的名为item属性上; = 号左边的item为 props定义的属性名,右边的为 item in items中遍历的item项的值
Axios异步通信
什么是Axios
Axios是一个开源的可以用在浏览器端和Nodes 的异步通信框架,她的主要作用就是实现 AJAX异步通信,其功能特点如下:
- 从浏览器中创建 XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API[JS中链式编程]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF (跨站请求伪造)
GitHub: https://github.com/axios/axios
中文文档:http://www.axios-js.com/
为什么要是用Axios
由于Vue.js 是一个视图层框架并且作者(尤雨溪)严格准守SoC(关注度分离原则),所以Vue.js并不包含AJAX的通信功能,为了解决通信问题,作者单独发了一个名为vue- resource的插件,不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery,因为它操作Dom太频繁!
第一个Axios程序
官方文档:https://cn.vuejs.org/v2/guide/instance.html#生命周期图示
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载DOM、渲染→更新→渲染、卸载等一系列过程,我们称这是Vue 的生命周期。通俗说就是Vue 实例从创建到销毁的过程,就是生命周期。
在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue 的实例。
<div id="vue">
<div>{{info.name}}</div>
<div>{{info.address.city}}</div>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="http://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#vue',
//data: 属性
//data()函数
data(){
return{
//请求的返回参数格式,必须和json字符串一样 可以不写
info:{
name: null,
address: {
street:null,
city:null,
country:null
}
}
}
},
mounted(){ //钩子函数 链式编程 => ES6新特性 response变量
axios.get('../data.json').then(response=>(this.info=response.data))
}
})
</script>
{
"name" :"狂神说Java" ,
"url" :"https: //blog.kuangstudy.com",
"page" : 1,
"isNonProfit" : true,
"address" : {
"street" :"含光门",
"city" :"陕西西安",
"country" : "中国"
},
"links" : [
{
"name" : "bilibili",
"url" : "https://space.bilibili.com/95256449"
},
{
"name" : "狂神说java",
"url" : "https://blog.kuangstudy.com"
},
{
"name" : "百度",
"url" : "https://www.baidu.com/"
}
]
}
解决Vue闪烁源代码问题
v-clock解决页面闪烁问题
如果网速慢,而该标签内容是变量没有请求响应回来的时候,页面上先不显示该标签(vue给该标签加了css样式),当响应回来的时候改标签默认将css样式去除。此指令可以解决使用插值表达式页面闪烁问题
将该指令加在html标签中时,可以在该文件中加style属性为display:none,例子如下:
<style>
[v-clock]{
display: none;
}
</style>
<div>{{info.name}}</div>
<div>{{info.address.city}}</div>
计算属性
什么是计算属性
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数;简单点说,它就是一个能够将计算结果缓存起来的属性〔将行为转化成了静养态的属性),仅此而已;可以想象为缓存!
- methods:定义方法,调用方法使用currentTime1(),需要带括号
- computed:定义计算属性,调用属性使用currentTime2,不需要带括号; this.message是为了能够让currentTime2观察到数据变化而变化
- 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.mes5age=“qinjiang” ,改变下数据的值,再次测试观察效果!
<div id="vue" v-clock>
<p>{{currentTime1()}}</p>
<p>{{currentTime2}}</p>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="http://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#vue',
data:{
message: "hello,ShiYu"
},
methods:{
currentTime1:function () {
return Date.now(); //返回一个时间戳
}
},
computed: { //计算属性 methods computed 重名之后,只会调用methods方法
currentTime2: function () {
this.message;//这个值被刷新的时候,currentTime2会被重新复制
return Date.now();//返回一个时间戳
}
}
});
</script>
结论:
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的低到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
slot 插槽
<!--view层 模板-->
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
</todo>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
//slot:插槽
Vue.component("todo",{
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>>'
});
Vue.component("todo-items",{
props: ['item'],
template: '<div>{{item}}</div>>'
});
var vm = new Vue({
el:"#app",
//Model:数据
data:{
title: "秦老师系列课程",
todoItems: ['狂神说Java','狂神说前端','狂神说Linux']
}
});
</script>
自定义事件分发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kCg2wEby-1619279901171)(Vue.assets/image-20201212111943023.png)]
<!--view层 模板-->
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems" :item="item"
v-bind:index="index" v-on:remove="removeItems" :key="index"></todo-items>
</todo>
</div>
<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
//slot:插槽
Vue.component("todo",{
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props: ['item','index'],
//只能绑定当前主键的方法
template: '<div>{{index}}---{{item}} <button @click="remove">删除</button></div>',
methods: {
remove: function (index) {
//this.$emit 自定义事件分发
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el:"#app",
//Model:数据
data:{
title: "秦老师系列课程",
todoItems: ['狂神说Java','狂神说前端','狂神说Linux']
},
methods: {
removeItems: function (index) {
console.log("删除了"+this.todoItems[index] + "OK");
this.todoItems.splice(index,1); //一次删除一个元素
}
}
});
</script>
其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性。
要解释key的作用,不得不先介绍一下虚拟DOM的Diff算法了。
我们知道,vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。
key
vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设:
1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
2. 同一层级的一组节点,他们可以通过唯一的id进行区分。
基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。
这里我们借用React’s diff algorithm中的一张图来简单说明一下:
当页面的数据发生变化时,Diff算法只会比较同一层级的节点:
-
如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。
-
如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
比如一下这个情况:
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
所以一句话,**key的作用主要是为了高效的更新虚拟DOM**。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,
否则vue只会替换其内部属性而不会触发过渡效果。
链接:https://www.jianshu.com/p/0044532e4a93
Vue小结
核心︰数据驱动,组件化
优点∶借鉴了AngulaJS的模块化开发和React 的虚拟Dom,虚拟Dom就是把Dom操作放到内存中执行;
常用的属性:. v-if
-
v-else-if
-
v-else
-
v-for
-
v-on绑定事件,简写@. v-model 数据双向绑定
-
v-bind 给组件绑定参数,简写:
组件化:
- 组合组件slot插槽
- 组件内部绑定事件需要使用到 this.$emit( “事件名”,参数);
- ·计算属性的特色,缓存计算数据
遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含,比如Ajax之类的通信功能,为了解决通信问题,我们需要使用Axios框架做异步通信;
说明
Vue的开发都是要基于NodeJS,实际开发采用vue-cli脚手架开发,vue-router路由,vuex做状态管理; Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品!)来快速搭建前端项目~
第一个vue-cli项目
什么是vue-cli
vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板;
预先定好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速;
主要的功能:
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
需要的环境
安装Node.js
-
Node.js:http://nodejs.cn/download
安装就无脑下一步就好,安装在自己的环境目录下
-
Git:https://git-scm.com/downloads
镜像:https://npm.taobao.org/mirrors/git-for-windows/
确认node.js安装成功
- cmd 下输入node-v,查看是否能够正确打印出版本号即可!
- cmd下输入nmp-v,查看是否能够正确打印出版本号即可!
这个npm就是一个软件包安装工具,和linux下的apt软件安装差不多
安装Node.js淘宝镜像加速器(cnpm)
这样子的话,下载会快很多
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题 --registr=https://registry.npm.taobao.org 需要在安装的时候加上 每次都需要
bom install --registr=https://registry.npm.taobao.org
安装的过程有点慢~,耐心等待!虽然安装了cnpm,尽量少用,会出现下载完不能使用的问题
安装的位置C:\Users\86177\AppData\Roaming\npm
安装vue-cli
cnpm install vue-cli -g
# 测试是否安装成功
# 查看可以基于那些模板创建vue应用程序,通常选择webpack
vue list
第一个vue-cli应用程序
-
创建一个Vue项目,随便创建一个目录
-
创建一个基于webpack模板vue应用程序
# 这里的myvue是项目名称,根据需求取名 去所要创建的目录下输入命令 vue init webpack myvue
一路选择no即可;
说明
- Project name:项目名称,默认回车即可
- Project description:项目描述,默认回车即可
- Author:项目作者,默认回车即可
- Install vue-router:是否安装vue-router,选择n不安装(后期需要再手动添加)
- Use ESLint to lint your code:是否使用ESLint做代码检查,选择n不安装(后期需要再手动添加)
- Set up unit tests:单元测试相关,选择n不安装(后期需要再手动添加)
- Setup e2e tests with Nightwatch:单元测试相关,选择n不安装(后期需要再手动添加)
- Should we run npm install for you after the project has been created:创建完成后直接初始化,选择n,我们手动执行;运行结果!
初始化并运行
cd myvue
npm install
npm run dev
ctrl+c停止
webpack学习
本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle.
Webpack 是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换,任何形式的资源都可以当做模块,比如CommonsJS、AMD、ES6、cSs、JSON、CoffeeScript、 LESS等;
伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了WebApp模式。它们运行在现代浏览器里,使用HTML5、CSS3、ES6等新的技术来开发丰富的功能,网页已经不仅仅是完成浏览器的基本需求; WebApp通常是一个SPA (单页面应用),每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的JS代码,这给前端的开发流程和资源组织带来了巨大挑战。
前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。
安装webpack
WebPack是一款模块加载器兼打包工具,它能把各种资源,如JS、JSX、ES6、SASS、LESS.图片等都作为模块来处理和使用。可以想象成吧es6的代码打包成es5的。
安装
#打包工具
npm install webpack -g
#客户端
npm install webpack-cli -g
测试安装成功:
-
webpack -v
-
webpack-cli -v
配置
创建webpack.config.js配置文件
- entry:入口文件,指定Webpack用那个文件作为项目的入口
- output:输出,指定WebPack把处理完成的文件放置到指定路径
- module:模块,用于处理各种类型的文件
- plugins:插件,如:热更新、代码重用等
- resolve:设置路径指向
- watch:监听,用于设置文件改动后直接打包
module.exports = {
entry:"",
output:{
path:"",
filename:""
},
module:{
loaders:[
{test:/\.js$/,loader:""}
]
},
plugins:{},
resolve:{},
watch:true
}
直接运行webpack命令打包
使用webpack
-
创建项目
-
创建一个名为modules的目录,用于放置JS模块等资源文件
-
在modules下创建模块文件,如hello.js,用于编写JS模块相关代码
//暴露一个方法:sayHi exports.sayHi = function(){ document.write("<div>HelloWebPack</div>"); }
-
在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性
// require导入一个模块,就可以调用这个模块中的方法了 var hello = require("./hello"); hello.sayHi( ) ;
-
在项目目录下创建webpack.config.js 配置文件,使用webpack 命令打包
webpack -watch //热部署 实时监听改变
vue-router
Vue Router是 Vue.js官方的路由管理器。它和Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的css class的链接
- HTML5历史模式或hash模式,在IE9中自动降级
- 自定义的滚动条行为
安装
npm install vue-routr --save-dev
模式
hash:路径带#符号,如http://localhost/#/login
history:路径不带# 符号,如http://localhost/login
通过mode设置
export default new Router({
mode:'history',
})
Vue实战
我们采用实战教学模式并结合ElementuI
组件库,将所需知识点应用到实际中,以最快速度带领大家掌握Vue的使用;
创建工程
注意:命令行都需要使用管理员模式运行
1、穿件一个名为hello-vue的工程 vue init webpack hello-vue
2、 安转依赖,需要安装vue-router、element-ui、sass-loader、node-sass四个插件
#进入工程目录
cd hello-vue
#安装 vue-router
npm install vue-router --save-dev
#交装element- ui
npm i element-ui -s
#安装依赖
npm install
#安装SASS 加载器
cnpm install sass-loader node-sass --save-dev
#启动测试
npm run dev
3、Npm命令解释:
- npm install moduleName :安装模块到项目目录下
- npm install -g moduleName : -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看npm config prefix的位置
- npm install -save moduleName : --save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖,-S为该命令的缩写
- npm install -save-dev moduleName: --save-dev的意思是将模块安装到项目目录下,并在package文件的 devDependencies节点写入依赖,-D为该命令的缩写
具体代码在hello-vue
参数传递的两种方式
1、name+params
<!--name 传组件名,注意是name params 传递参数
这时候就需要对象 使用v-bond绑定一个-->
<router-link :to="{name: 'userProfile', params:{id:1}}">个人信息</router-link>
router 的 index.js 里面接收参数
path: '/user/profile/:id',
显示
<!--所有的元素,不能直接在根节点下 否则报错-->
<div>{{$route.params.id}}
<h1>个人信息</h1>
</div>
2、props
<!--name 传组件名,注意是name params 传递参数
这时候就需要对象 使用v-bond绑定一个-->
<router-link :to="{name: 'userProfile', params:{id:1}}">个人信息</router-link>
router 的 index.js 里面接收参数
path: '/user/profile/:id',
显示
<template>
<!--所有的元素,不能直接在根节点下 否则报错-->
<div>{{id}}
<h1>个人信息</h1>
</div>
</template>
<script>
export default {
props:['id'], //这里这里 加了这里
name: "UserProfile"
}
</script>
重定向
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
{
path: '/goHome',
redirect: '/main'
},
页面跳转
//使用 vue-router 路由到指定页面,该方式称之为编程式导航
this.$router.push("/main");
路由钩子和异步请求
所有的钩子函数在上面Axios异步通信下的图中
beforeRouteEnter :在进入路由前执行
beforeRouteLeave :在离开路由前执行
<script>
export default {
props:['id'],
name: "UserProfile",
//类似过滤器,
beforeRouteEnter:(to,from,next)=>{
console.log("进入路由之前");
next();//不next会卡在这
},
beforeRouteLeave:(to,from,next)=>{
console.log("进入路由之后");
next();
}
}
</script>
参数说明
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next()跳入下一个页面
next(’/path’)改变路由的跳转方向,使其跳到另一个路由. next(false)返回原来的页面
next((vm)=>{})仅在beforeRouteEnter 中可用,vm是组件实例
在钩子函数中使用异步请求
1、 安装Axios cnpm install axios -s 还是要少用cnpm
2、main.js引用Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios) // 这里顺序错了会报错 不明白为什么