手把手,从无到有带你用vue进行项目实战 系列一(搭建框架篇)
手把手,从无到有带你用vue进行项目实战 系列二(cdn、gzip性能加速篇)
对Vue的解析主要分为简介、核心内容、组件、路由和状态管理四部分
一、简介
Vue.js主要有四个特点
知识点 : Vue.js如何实现数据双向绑定?
Vue.js的响应式使用起来很简单,不需要引入太多的新概念,声明实例new Vue({data:data})后对data里面的数据进行视图上的绑定。修改data数据,视图中相应数据也会随之修改。
详析
Vue 使用基于依赖追踪的观察系统并且异步队列更新,所有的数据变化都是独立触发,除非它们之间有明确的依赖关系。 vue.js 采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(for...in 或 Object.keys 方法), 这些值可以被改变,也可以被删除。这种方法允许这些额外的细节从默认值改变。
知识点 : 数组更新检测注意事项
由于vue检测到数组更新后会触发视图更新,因此单独列出来
变异方法(mutating method 改变原数组)
push(), pop(), shift(), unshift(), splice(), sort(), reverse()
非变异 (non-mutating method)
filter(), concat() 和 slice()
注意:
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
2. 当你修改数组的长度时,例如:vm.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
为了解决第二类问题,你可以使用 splice:
example1.items.splice(newLength)
知识点 : 对象更改注意事项
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。
但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性
总结:使用Vue.js可以让开发更简单,同时颠覆了传统前端开发模式,提供现代web开发中常见对功能:
二、核心内容
Vue.js具有渐进式的特点,核心部分实现基础功能,路由、状态管理和对服务的封装使用插架,这一部分我们主要解析核心内容
1、生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。常用的钩子有:
2、数据绑定
模版语法:
:href=“url">...
click="doSomething">...
上面对语法是对v-bind和v-on的缩写,是一个语法糖,实现的结果是一样的。
知识点 : 过滤器
Vue支持在{{}}插值的尾部添加一个管道符“|”对数据进行过滤,经常用于格式化文本,格式如下:
{{ date | formatDate}}
var app = new Vue({
...
filters:{
formatDate:function(value){
...
}
}
})
过滤器也可以串联,而且可以使用参数
//串联
{{ message | filter1 | filter2}}
//接收参数
{{message | filterA('arg1','arg2')}}
敲黑板 : vue2新变化
3、计算属性和观察者
计算属性是依赖它的缓存的,一个计算属性所依赖的数据发生变化时,它才会重新取值,所以只要依赖属性不改变,就不更新。
4、内置指令
v-cloak>
{{message}}
[v-cloak]{
display:none;
}
对于简单的项目很实用,但是在工程化的项目中,项目的HTML文件只有一个空的div元素,剩余内容都是用路由挂在不同组件完成的,所以不需要v-cloak。
知识点 : v-if与v-show的区别
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
都需要绑定在某个元素上,避免未编译前的闪现问题,用于绑定更新text和innerHtml
为dom元素注册了一个索引,可以直接访问dom元素
<div v-el:demo>this is a demo
与v-el类似,只不过用于子组件上,实例可以通过$refs访问子组件
Vue.js2中的新增指令,表示只渲染一次,及时数据更新也不改变
5、组件
代码复用一直是软件开发中长期存在的问题,每个开发者都想利用之前写好的代码,又担心引入后对现有项目有影响。现在web component的出现提供一种思路,可以自定义tag标签,拥有自己的模版、样式和交互。angular.js的指令、react.js的组件化都在往这个方向尝试,vue.js也提供了自己的组件系统。
组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。 所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。
在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop给子组件下发数据,子组件通过事件给父组件发送消息。看看它们是怎么工作的。
组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。父组件的数据需要通过 prop 才能下发到子组件中。
Vue.component('child', {
// 在 JavaScript 中使用 camelCase
props: ['myMessage'],
template: '{{ myMessage }}'
})
my-message ="hello!">
如果你使用字符串模板,则没有这些限制。
知识点 : props的单向数据流和数据验证
5.2.1 单向数据流 --> vue2新特性
尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态。如果需要使用父组件传过来的数据,有两种方式:
1. 在子组件内再次声明一个参数,引用父组件的prop
2. 使用计算属性
5.2.2props数据验证
验证prop的类型,可以有这几种:String、Number、Boolean、Object、Array、Function
使用 v-on 绑定自定义事件
每个 Vue 实例都实现了事件接口,即:
• 使用 $on(eventName) 监听事件
• 使用 $emit(eventName) 触发事件
知识点 : vue2废弃了$dispatch和$broadcast方法
vue2废弃了$dispatch和$broadcast方法,这两种方法主要依赖组件的树结构, 如果组件越来越复杂时,这种结构很难被理解。
props和event用于分发数据,slot用于分发内容,实例如下:
class="container">
name ="header">
name ="footer">
......
......
slot
="header">这里可能是一个页面标题
主要内容的一个段落。
另一个主要段落。
slot
="footer">这里有一些联系信息
......
......
class="container">
这里可能是一个页面标题
主要内容的一个段落。
另一个主要段落。
这里有一些联系信息
知识点 : 组件在vue2中的变化
//vue.js1中为
三、路由
vue的路由是独立于核心模块之外的,对于大多数单页面应用,都推荐使用官方支持的 vue-router 库。
vue的路由交给vue-router实现和管理,随着vue升级到vue2,vue-router也做了相应的升级,在适配vue2的同时,自身的使用方法上也做了改变(shit)。
vue-router的基础功能这里不做过多的介绍,主要分析vue-router2的新功能:
知识点 : vue-router2的新升级
vue-router2的新升级主要涉及五个方面:使用方式、跳转方式、钩子函数、获取数据、命名视图,这里主要介绍钩子函数和获取数据
1、钩子函数
1.1 全局钩子
1.2 单个路由钩子
1.3 组件内钩子
钩子实例:
router.beforeEach((to, from, next) => {
if(window.localStorage.getItem('token')){
next();
}else{
next("/login");
}
});
to: 即将要进入的目标的路由对象
from: 当前导航即将要离开的路由对象
next: 调用该方法后,才能进入下一个钩子
2、获取数据
直接来看一下实例:
export default{
data(){
return{
...
}
},
created(){
//组件创建完后获取数据
this.fetchData();
},
watch:{
//如果路由有变化会再次执行该方法
'$store':'fetchData'
},
methods:{
fetchData(){
//调用service获取数据
}
}
}
上面的实例就是利用生命周期在不同的时间点获取、刷新数据。
四、状态管理
vue 的状态管理有两种方式:中央事件总线和vuex,这是主要介绍vuex,因为vuex更适合工程化的项目,实现的方式更为优雅。
1、vuex可用于非父子组件(也就是跨级组件和兄弟组件)间通信
实例代码:
State:存储数据
const store = new Vuex.store({
state:{
count:0;
}
});
在任何的组件内,可以直接调用$store.state.count来获取:
//index.vue
首页
{{$store.state.count}}
五、异步调用接口数据
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端
实例:
import axios from ‘axios';
const ajaxUrl = env === 'development'
? 'http://10.10.10.10:1212/'
: 'http://newservice:1100/';
const ajaxFun = function(serviceUrl,paramData,callback){
axios({
method:'post',
url:serviceUrl,
baseURL: ajaxUrl,
timeout: 30000,
headers: {'content-type': 'application/json'},
data:paramData,
}).then(function(res){
return callback(res.data);
}).catch(function (error) {
var data = {
retCode:"000000",
retMsg:"网络错误,请联系客服"
}
callback(data);
});
}
手把手,从无到有带你用vue进行项目实战 系列一(搭建框架篇)
手把手,从无到有带你用vue进行项目实战 系列二(cdn、gzip性能加速篇)