愿你被这个世界温柔以待
心中充满爱
Vue概述
Vue:渐进式JavaScript框架
渐进式:声明式渲染--> 组件系统 -->客户端路由-->集中式状态管理 --> 项目构建
官方api:cn.vuejs.org/v2/api/
Vue基本使用
我们来举一个小案例:实现hello world的写入 分别为原生js和jquery
这两种方式均可以实现这个功能,但是程序猿是比较聪明的哈,就想还有没有什么简单的方法呢,所以Vue就出现了
Vue的hello world实现基本过程:
基本使用步骤:
- 需要提供标签,用于填充数据
- 需要引入vue库文件
- 可以使用Vue的语义实现功能
- 把Vue提供的数据填充到标签
代码实现👇
实例参数分析:
- el:元素的挂载位置
把数据关联到某个标签内
(值可以是CSS选择器或者DOM元素) - data:模型数据(值是一个对象)
插值表达式用法:
- 将数据填充到HTML标签中
- 插值表达式支持基本的计算操作
例如:
<div>{{1 + 2}}</div>
可以打印出结果为3
Vue代码运行运行原理分析
- 概述编译过程的概念(Vue语法->原生语法)
前端渲染
把数据填充给到HTML标签中,前端渲染的几种方式:
- 原生js拼接字符串
- 使用前端模板引擎
- 使用Vue特有的模板语法
指令
定义:指令的本质就是自定义属性,只不过格式是固定的,以V-开始(例如v-cloak)
v-cloak指令用法
- 插值表达式存在“闪动”的问题
- 使用v-cloak指令解决
- 原理:先隐藏,替换好值之后再显示最终的值
[v-cloak] {
display: none;
}
<div v-cloak>
{{ message }}
</div>
数据绑定指令
- v-text 填充纯文本(没有闪动的缺点)
<div v-text="msg"></div>
- v-html 填充HTML片段
- v-pre 填充原始信息,会跳过编译过程
数据响应式
html5的响应式(屏幕适配,屏幕尺寸的变化导致样式的变化)
数据的响应式(数据的变化导致页面内容的变化)
在谷歌浏览器console出vm.msg,可以得到msg的值,当我们设置vm.msg = 3的时候,前端渲染界面也会发生改变,变成3,我们称这个变化过程为数据的响应式
v-once:只编译一次,显示内容之后不再具有响应式功能,例如,我们设置:
<div v-once>{{info}}</div>
当我们在浏览器console改变属性的值的时候,前端界面并未发送改变,即未发生数据响应式这个过程
应用场景:如果显示的信息后续不需要再修改,可以使用v-once,减少监听的属性,提高性能双向数据绑定
本质
用户改页面内容的时候,数据会变,如果数据变了,会影响插值表达式的内容,进而影响前端的渲染内容
原理:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
核心:
通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的,
v-model指定用法
需要绑定对应的属性值
<input type="text" v-model="msg">
MVVM设计思想
- M(model) 实质是data内的数据
- V(view)视图,本质上就是DOM元素
- VM(view-model) 控制逻辑,将两者相结合,视图和数据交互必须通过VM中介
事件绑定
如👇所示,我们使用v-on:click指令给button绑定事件,再写一个div显示输出的num值,实现的效果,每点击一次button,num均会加1,div内的num值也会发生改变:
事件函数的调用方式
有一个需要注意:这里的this指的是Vue的实例对象,不可以直接在函数内写num++
事件函数参数传递
- 普通参数和事件对象 向handle()函数内传入具体的参数并打印输出 如果需要传递对应的事件对象,函数的最后一个参数代表事件对象: 固定格式代码:
<button type="button" @click="handle(123,$event)">点击</button>
事件修饰符
- .stop阻止冒泡
<div @click="handle">
<button @click.stop="bubbing">冒泡</butto>
</div>
原生js的实现方法:
- .prevent 阻止默认行为
<a href="http://www.baidu.com" @click.prevent="skip">百度</a>
原生js的实现方式:
总结:<div id="app">
<div>
<div>{{num}}</div>
<div @click="handle">
<button @click.stop="bubbing">冒泡</button>
</div>
<div>
<a href="http://www.baidu.com" @click.prevent="skip">百度</a>
</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0,
},
methods: {
handle: function() {
this.num++;
},
bubbing: function(event) {
// 阻止冒泡
// event.stopPropagation();
},
skip: function(event) {
// 阻止默认行为
// event.preventDefault();
}
}
})
</script>
按键修饰符
- .enter 回车键 < input v-on:keyup.enter="submit" >
- .delete 删除键
自定义按键修饰符
先写一个函数打印输出键码
methods:{
handleCount: function (event) {
console.log(event.keyCode)
}
}
那我们现在来自定义一个按键修饰符:通过上一步我们知道了键码,3的键码是99,那我们直接在keyup之后加一个99,这个时候,只有输入3的时候会console值,即执行函数,键盘上输入其他的都不会执行。
<div>
号码:<input type="text" v-on:keyup.99="handleCount" v-model="number">
</div>
简单计算器
注意:此处认定输入的数为整数
属性绑定
v-bind用法
动态地绑定
一个或多个 attribute,或一个组件 prop 到表达式
示例功能:动态添加url到a标签中,点击切换之后,改变url的值
v-model用法
在表单控件或者组件上创建双向绑定
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
样式绑定
class样式处理
- 对象语法
<div v-bind:class="{active: isActive}"></div>
<div v-on:click="change">切换隐藏</div>
methods部分,注意这里有一个小细节,this.isActive = !this.isActive;
,而并非this.isActive = false;如果赋值给false,则再次点击切换的时候,div并不会显示出来
change: function () {
this.isActive = !this.isActive;
}
- 数组语法 active和error均为class类名
<div v-bind:class="[activeClass, errorClass]"></div>
<div v-on:click="change">切换隐藏</div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染为:
<div class="active text-danger"></div>
分支循环结构
分支结构
- v-if
- v-else
- v-else-if
- v-show,控制元素样式是否显示
v-if和v-show的区别
v-if控制元素是否渲染到页面,v-show控制元素是否显示(已经渲染到了页面)
判断函数综合运用:输出成绩等级
循环结构
注意名称一定要一致
data: {
fruits: ['apple','orange','banana']
},
<ul>
<li v-for="item in fruits">{{item}}</li>
</ul>
基于数据重构UI效果,先提供一个Vue模板,然后基本这个模板做事件的绑定,即JS控制逻辑的处理,而这两个是通过Vue实例对象粘合到一块的,才能够实现完善的前端功能
Vue常用特性
表单操作
我们平时写表单的时候,会使用submit提交,但是submit会自动提交表单,为了更加方便达到相关要求,如下:
注意这里为了阻止submit的默认提交表单操作,我们使用prevent
自定义指令
当内置指令不满足需求的时候,我们可以自定义指令
举例说明自定义指令的语法规则(获取元素的焦点)
计算属性
Vue引入的新概念,使模板内容更加简洁 实例:使用计算属性,简化控制逻辑,实现字母顺序调换
按照之前所学的JS,如果需要调换字符串的数据,徐娅先使用split()函数,将字符串拆分成数组,再使用reverse()函数调换数组的顺序,并返回原数组,最后使用join()函数将数组转换成字符串,这个过程就相对比较复杂。
计算属性必须要有返回值
侦听器
当data内的数据发生变化,会触发侦听器内绑定的方法,处理一些异步的或者开销较大的操作
案例,当如👇所示的姓和名内容改变的时候,下面的fullname也会发生改变 结果如下: val表示变化后的值扩展:这个案例也可以用计算属性实现,比较简单 ,注意哦,计算属性computed一定要有返回值return
过滤器
作用:格式化数据
示例:比如将字符串格式为首字母大写等生命周期
主要阶段
所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对 property 和方法进行运算。
-
挂载(初始化相关属性)
beforeCreate
created
beforeMount
mounted
-
更新(元素或组件的变更操作)
beforeUpdate
updated
-
销毁(销毁相关属性)
beforeDestory
destoryed
mounted重要讲解
- 类型:Function
- 详细:
这个函数一旦触发,代表初始化已经完成,之后经常用到的场景是:调用后台接口获取数据,把数据填充到模板中。
el
实例被挂载后调用,这时 el
被新创建的 vm.$el
替换了。如果实例挂载到了一个文档内的元素上,当 mounted
被调用时 vm.$el
也在文档内。
注意 :mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
该钩子在服务器端渲染期间不被调用。
综合案例练习
如👆图所示,实现的功能:- 输入编号和名称后,点击添加可将内容添加到表格中
- 点击修改之后,编号id不可修改,名称修改完成后更新列表,不单独添加一行
- 点击删除之后,删除整行
详细代码:👉 源代码
岁月极美,在于它必然的流逝。 春花、秋月、夏日、冬雪。
组件化开发
- 标准
- 分治
- 重用
- 组合
组件化规范: Web Components(创建封装好功能的定制元素[可以理解成自定义标签])
组件注册
全局组件注册语法
参数1是组件名称,单数2是一个对象,对象中两个比较重要的属性,data表示内部需要的数据,template表示模板的内容
组件用法
可以直接在html引用组件名称
<div id="app">
<button-counter></button-counter>
</div>
组件注册注意事项
- data必须是一个函数
本质上来讲,使用函数会形成一个闭包环境,保证每一个组件都会拥有一份独立的数据。
- 组件模板内容必须是单个的跟元素 例如👇面,我们给button添加一个兄弟元素button,浏览器就会报错
template: '<div><button @click = "count ++">点击了{{count}}次</button><button>测试</button></div>'
- 组件模板内容可以是模板字符串(需要浏览器兼容ES6语法)
例如上面的template的包含的内容,都显示在一行,那就不是很美观了,所以就用到了我们这里的模板字符串,需要在template后加两个
``
号,增加代码的可读性
template: `
<div>
<button @click = "count ++">点击了{{count}}次</button>
<button>测试</button>
</div>
`
- 组件命名方式
- 短横线方式
Vue.component('my-component-name', { /* ... */ })
- 驼峰方式
注意:如果使用该方法,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,在普通的标签模板中,必须使用短横线的方式命名
Vue.component('MyComponentName', { /* ... */ })
局部组件注册
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 components 选项中定义你想要使用的组件:
new Vue({
el: '#app',
components: {
// ”组件的名称“:组件的内容(可以抽取到对象中)
'component-a': ComponentA,
'component-b': ComponentB
}
})
示例:
<div id="app">
<he-a></he-a>
<he-b></he-b>
</div>
// 局部组件注册
// 定义组件HeA
let HeA = {
data: function() {
return {
msg: 'hello'
}
},
template: '<div>{{msg}}</div>'
};
//定义组件HeB
let HeB = {
data: function() {
return {
msg: 'hello22'
}
},
template: '<div>{{msg}}</div>'
};
//通过components注册
let vm = new Vue({
el: '#app',
data: {
},
components: {
'he-a': HeA,
'he-b': HeB
}
})
组件插槽
组件插槽的作用
- 父组件向子组件传递内容
左边的蓝色的表示父组件
黄昏是一天最美丽的时刻,
愿每一颗流浪的心,在一盏灯光下,得到永远的归宿。
接口调用方式
- 原生ajax
- 基于jQuery的ajax
- fetch
- axios
这里补充一下客户端与服务器的通讯模式,客户端通过浏览器发送请求,这个请求通过互联网到达服务器,到达服务器之后,服务器会返回对应的内容,而返回的内容主要有两种格式,可以是一个完整的HTML页面,也可以是特定格式的数据,比如json
HTTP请求方式
- GET 查询
- POST 添加
- PUT 修改
- DELETE 删除
Promise用法
异步调用
- 异步效果分析
- 定时任务
- Ajax
- 事件函数
Promise概述
是异步编程的一种解决方案,从语法上来讲,Promise是一个对象,从它可以获取异步操作的消息。
Promise基本用法
- 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
- resolve和reject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
then参数中的函数返回值
- 返回Promise实例对象,返回的实例对象会调用下一个then
- 返回普通值,返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值
Promise常用的api
- p.then()得到异步任务的正确结果
- p.catch()获取异常消息
- p.finally()成功与否都会执行(非正式标准)
接口调用-fetch用法
语法结构
fetch(url).then(url2)
.then(url3)
...
.then(fn)
基本用法
fetch请求参数:- 常用配置选项
- method(String):HTTP请求方法,默认为GET
- body(String):HTTP的请求参数
- header(Object):Http的请求头,默认为{} GET请求方式的参数传递有两种方式:
POST请求方式的参数传递
路由的基本概念与原理
- 后端路由:
- 概念:根据不同的用户url请求,返回不同的内容
- 本质:url请求地址与服务器资源之间的对应关系
- 概念:根据不同的用户事件,显示不同的页面内容
- 本质:用户事件与事件处理函数之间的对应关系
前端路由负责事件监听,触发事件之后,通过事件函数渲染不同内容