1、axios
1.1 Ajax回顾
1.1.1 什么是Ajax?
- Ajax 是指一种创建交互式网页应用的开发技术。Ajax = 异步 JavaScript 和 XML。
1.1.2 Ajax的作用
- Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新(局部更新)。传统的网页如果需要更新内容,必须重载整个网页页面。
- 简单记:Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术,维护用户体验性,进行网页的局部刷新。
1.1.3 异步与同步
- 浏览器访问服务器的方式
- 同步访问:客户端必须等待服务器端的响应,在等待过程中不能进行其他操作。
- 异步访问:客户端不需要等待服务的响应,在等待期间浏览器可以进行其他操作。
1.2 axios介绍
VUE中结合网络数据进行应用的开发
- 目前十分流行的网络请求库,专门用来发送请求,其内部还是ajax,进行封装之后使用更加方便。
- axios作用:在浏览器中可以帮助我们完成 ajax异步请求的发送。
1.3 axios入门
使用步骤:
- 导包
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- 请求方式以GET和POST举例
GET
axios.get(地址?key=value&key2=value2).then(function(response){},function(error){});
POST
axios.post(地址,{key:value,key2:value2}).then(function(response){},function(error){})
- 根据接口文档,访问测试接口进行测试
接口1:随机笑话
请求地址:https://autumnfish.cn/api/joke/list
请求方法:get
请求参数:num(笑话条数,数字)
响应内容:随机笑话
接口2:用户注册
请求地址:https://autumnfish.cn/api/user/reg
请求方法:post
请求参数:username(用户名,字符串)
响应内容:注册成功或失败
代码示例
<body>
<input type="button" value="get请求" id="get" />
<input type="button" value="post请求" id="post" />
</body>
<script src="js/axios.min.js"></script>
<script>
/*
随机笑话接口测试
请求地址:https://autumnfish.cn/api/joke/list
请求方法:get
请求参数:num(笑话条数,数字)
响应内容:随机笑话
*/
document.getElementById("get").onclick = function() {
axios.get("https://autumnfish.cn/api/joke/list?num=2").then(
function(resp) {
// 调用成功
console.log(resp);
},
function(err) {
// 调用失败
console.log(err);
}
);
};
/*
用户注册
请求地址:https://autumnfish.cn/api/user/reg
请求方法:post
请求参数:username:"用户名"
响应内容:注册成功或失败
*/
document.getElementById("post").onclick = function() {
axios
.post("https://autumnfish.cn/api/user/reg", {
username: "吃豆芽的张飞"
})
.then(
function(resp) {
console.log(resp);
},
function(err) {
console.log(err);
}
);
};
</script>
1.4 axios总结
- axios 必须导包才能使用。
- 使用get或者post方法,就可以发送请求。
- then方法中的回调函数,会在请求成功或者请求失败的时候触发。
- 通过回调函数的形参可以获取响应的内容,或者错误信息。
1.5 获取笑话案例
通过vue+axios 完成一个获取笑话的案例。
接口:随机获取一条笑话
请求地址:https://autumnfish.cn/api/joke
请求方法:get
请求参数:无
响应内容:随机笑话
代码示例
<body>
<div id="app">
<input type="button" value="点击获取一个笑话" @click="getJoke" />
<p>{{ joke }}</p>
</div>
</body>
<script src="../js/vue.min.js"></script>
<script src="../js/axios.min.js"></script>
<script>
/*
请求地址:https://autumnfish.cn/api/joke
请求方法:get
请求参数:无
响应内容:随机笑话
*/
var VM = new Vue({
el: "#app",
data: {
joke: "笑口常开"
},
methods: {
getJoke: function() {
// 把this进行保存
var that = this;
// 异步访问
axios.get("https://autumnfish.cn/api/joke").then(
function(resp) {
console.log(resp.data);
// 在回调函数内部,this无法正常使用,需要提前保存起来
that.joke = resp.data;
},
function(error) {}
);
}
}
});
</script>
案例总结
- axios回调函数中this指向已经改变,无法访问data中的数据。
- 解决方案:将this进行保存,回调函数中直接使用保存的this即可。
1.6 天气查询案例
1.6.1 需求分析
- 功能分析:回车查询
- 输入内容,点击回车 (v-on.enter)。
- 访问接口,查询数据 (axios v-model)。
- 返回数据,渲染数据。
1.6.2 接口文档
请求地址:http://wthrcdn.etouch.cn/weather_mini
请求方法:get
请求参数:city (要查询的城市名称)
响应内容:天气信息
1.6.3 案例演示
自定义JS文件
作为一个标准的应用程序,将创建VUE实例的代码抽取到main.js 文件中。
main.js
/**
* 请求地址:http://wthrcdn.etouch.cn/weather_mini
* 请求方法:get
* 请求参数:city (要查询的城市名称)
* 响应内容:天气信息
*/
var VM = new Vue({
el: "#app",
data: {
city: "",
// 定义数组保存 天气信息
weatherList: []
},
methods: {
// 编写查询天气的方法
searchWeather: function() {
console.log("天气查询");
console.log(this.city);
var that = this;
// 调用接口
axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city).then(
function(resp) {
console.log(resp.data.data.forecast);
// 获取天气信息,保存到weatherList中
that.weatherList = resp.data.data.forecast;
},
function(error) {}
);
}
}
});
HTML页面代码
<body>
<div class="wrap" id="app" v-cloak>
<div class="search_form">
<div class="logo">天气查询</div>
<div class="form_group">
<input
type="text"
class="input_txt"
placeholder="请输入要查询的城市"
v-model="city"
@keyup.enter="searchWeather"
/>
<button class="input_sub">回车查询</button>
</div>
</div>
<ul class="weather_list">
<li v-for="item in weatherList">
<div class="info_type">
<span class="iconfont">{{ item.type }}</span>
</div>
<div class="info_temp">
<b>{{ item.low }}</b>
~
<b>{{ item.high }}</b>
</div>
<div class="info_date">
<span>{{ item.date }}</span>
</div>
</li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 自己的js -->
<script src="js/main.js"></script>
</body>
1.6.4 案例总结
- 应用的逻辑代码,建议与页面进行分离,使用单独的JS文件编写。
- axios回调函数中的 this的指向改变,无法正常使用,需要另外保存一份。
- 服务器返回的数据比较复杂时,获取数据时要注意层级结构。
1.7 解决页面闪烁问题
当访问天气预报案例页面时,使用插值表达式的地方出现了闪烁问题,如何解决呢?
v-cloak指令
- 作用:解决插值表达式闪烁问题。
- 当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。可以使用 v-cloak 指令来解决这一问题。
1)添加样式
<style>
/* 通过属性选择器,设置、添加了v-cloak */
[v-cloak] {
display: none;
}
</style>
2)在id为app的div中添加 v-cloak
<div class="wrap" id="app" v-cloak>
2、computed计算属性
2.1 什么是计算属性
- 在Vue应用中,在模板中双向绑定一些数据或者表达式,但是表达式如果过长,或者逻辑更为复杂时,就会变得臃肿甚至难以维护和阅读,比如下面的代码:
<div>
写在双括号中的表达式太长了,不利于阅读
{{text.split(',').reverse().join(',')}}
</div>.
将这段操作text.split(',').reverse().join(',') 放到计算属性中,最终返回一个结果值就可以
- computed 的作用:减少运算次数,缓存运算结果,运用于重复相同的计算。
2.2 代码示例
<body>
<div id="app">
<!-- <h1>{{ a * b }}</h1>
<h1>{{ a * b }}</h1> -->
<!-- <h1>{{ res() }}</h1>
<h1>{{ res() }}</h1> -->
<h1>{{ res2 }}</h1>
<h1>{{ res2 }}</h1>
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
var VM = new Vue({
el: "#app",
data: {
a: 10,
b: 20
},
methods: {
res: function() {
console.log("res方法执行了!");
return this.a * this.b;
}
},
// 使用计算属性进行优化,减少运算次数,用于重复的运算
computed: {
res2: function() {
console.log("res2方法执行了!");
return this.a * this.b;
}
}
});
</script>
2.3 computed总结
- 定义函数也可以实现与计算属性相同的效果,都可以简化运算。
- 不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
3、filter过滤器
3.1 什么是过滤器
- 过滤器是对即将显示的数据做进一步的筛选处理,然后进行显示,值得注意的是过滤器并没有改变原来的数据,只是在原数据的基础上产生新的数据。
- 数据加工车间,对值进行筛选加工。
3.2 过滤器使用位置
- 双花括号的插值表达式内。
{{ msg | filterA }} msg是需要处理的数据, filterA是过滤器, | 这个竖线是管道,通过这个管道将数据传输给过滤器进行过滤加工操作。
- v-bind绑定的值的地方。
<h1 v-bind:id=" msg | filterA"> {{ msg }} </h1>
3.3 过滤器
3.3.1 局部过滤器
需求:通过过滤器给价格前面添加一个符号$
<body>
<div id="app">
<!-- 使用插值表达式,调用过滤器 -->
<p>电脑价格:{{ price | addIcon }}</p>
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
// 局部过滤器,在Vue实例的内部创建filter
var VM = new Vue({
el: "#app", // 挂载点
// model
data: {
price: 200
},
// 局部过滤器
filters: {
// 定义处理函数,value = price
addIcon(value) {
return "$" + value;
}
}
});
</script>
3.3.2 全局过滤器
需求:将用户名开头字母大写。
<body>
<div id="app">
<p>{{ user.name | changeName }}</p>
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
// 在创建Vue实例之前,创建全局过滤器
Vue.filter("changeName", function(value) {
// 将姓名的开头字母大写
return value.charAt(0).toUpperCase() + value.slice(1);
});
var VM = new Vue({
el: "#app",
data: {
user: { name: "jerry" }
}
});
</script>
3.4 总结
- 过滤器常用来处理文本格式化的操作。
- 过滤器可以用在两个地方:双花括号插值表达式中和 v-bind 表达式中。
- 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号 | 传输数据。
4、watch侦听器
4.1 什么是侦听器
- Vue.js 提供了一个方法 watch,它用于观察Vue实例上的数据变动。
- 作用:当你有一些数据需要随着其它数据变动而变动时,可以使用侦听属性。
4.2 案例演示
需求:监听姓名变化,实时显示。
<body>
<div id="app">
<label>名:<input type="text" v-model="firstName"/></label>
<label>姓:<input type="text" v-model="lastName"/></label>
{{ fullName }}
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
var VM = new Vue({
el: "#app",
data: {
firstName: "",
lastName: "",
fullName: ""
},
// 侦听器
watch: {
firstName: function(nval, oval) {
// 参数1:新值,参数2:旧值
this.fullName = nval + " " + this.lastName;
},
lastName: function(nval, oval) {
this.fullName = this.firstName + " " + nval;
}
}
});
</script>
5、Component组件
5.1 组件介绍
- 组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
- 将相同的功能进行抽取,封装为组件,这样前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。
- 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。
- vue的组件有两种:全局组件 和 局部组件。
5.2 全局组件
语法格式:
Vue.component("组件名称", {
template: "html代码", // 组件的HTML结构代码
data() {
//组件数据
return {};
},
methods: {
// 组件的相关的js方法
方法名() {
// 逻辑代码
}
}
});
注意:
- 组件名以小写开头,采用短横线分割命名,例如:hello-world;
- 组件中的data 必须是一个函数,注意与Vue实例中的data区分;
- 在template模板中,只能有一个根元素。
代码示例:
<body>
<div id="app">
<!-- 使用组件 -->
<lagou-header></lagou-header>
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
// 定义全局组件
// 组件的命名规则:一般用短横线进行连接,左边是公司名,右边是组件的作用名称
Vue.component("lagou-header", {
template: "<div>HTML<h1 @click='hello'>{{msg}}</h1></div>", // template模板中,只能有一个根元素
// 组件中的data是一个函数
data() {
return {
msg: "这是lagou-header组件中的数据部分"
};
},
methods: {
hello() {
alert("你好!");
}
}
});
var VM = new Vue({
el: "#app",
data: {},
methods: {}
});
</script>
5.3 局部组件
- 相比起全局组件,局部组件只能在同一个实例内才能被调用。局部组件的写法和全局组件差不多。 唯一不同就是:局部组件要写在Vue实例里面。
语法格式:
new Vue({
el: "#app",
components: {
组件名: {
// 组件结构
template: "HTML代码",
// data数据
data() {
return { msg: "xxxx" };
}
}
}
});
注意:
- 创建局部组件,注意 components,末尾有 ‘s’,而全局组件是不用+ ‘s’ 的。这意味着,components 里可以创建多个组件。
代码示例:
<body>
<div id="app">
<web-msg></web-msg>
</div>
</body>
<script src="js/vue.min.js"></script>
<script>
// 创建局部组件
var VM = new Vue({
el: "#app",
components: {
// 组件名
"web-msg": {
template: "<div><h1>{{msg1}}</h1><h1>{{msg2}}</h1></div>",
data() {
return {
msg1: "开发进行中...",
msg2: "开发已完成!"
};
}
}
}
});
</script>
5.4 组件与模板分离
由于把html语言写在组件里面很不方便,也不太好看所以将它们分开写。
代码示例:
<body>
<div id="app">
<!-- 使用组件 -->
<web-msg></web-msg>
</div>
<!-- 将模板写在HTML中,给模板一个id -->
<template id="t1">
<div>
<button @click="show">{{ msg }}</button>
</div>
</template>
</body>
<script src="js/vue.min.js"></script>
<script>
var VM = new Vue({
el: "#app",
components: {
"web-msg": {
template: "#t1",
data() {
return {
msg: "点击查询"
};
},
methods: {
show: function() {
alert("正在查询中,请稍后...");
}
}
}
}
});
</script>
总结:
- 上面这种写法,浏览器会把 html 里的 template 标签过滤掉。所以 template 标签的内容是不会在页面中展示的。直到它被 JS 中的 Vue 调用。
- 在 html 中,template 标签一定要有一个 id,因为通过 id 是最直接被选中的。 data 和 methods等参数,全部都要放到 Vue 实例里面写。
6、Vue生命周期
6.1 生命周期图示
-
每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。
-
了解生命周期的好处:
- 找错误;
- 解决需求;
-
下图展示了实例的生命周期。
6.2 钩子函数介绍
- 生命周期中的钩子函数。
- 钩子函数:钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作。
函数 | 说明 |
---|---|
beforeCreate() | 在创建Vue实例之前执行这个方法。例如 加载动画操作。 |
created() | 函数执行时,实例创建完成,属性绑定好了,但是DOM页面还没有生成。 |
beforeMount() | 函数执行时,模板已经在内存中编辑完成了,尚未被渲染到页面中。 |
mounted() | 函数执行时,模板已经被渲染到页面,执行完就会显示到页面。 |
beforeUpdate() | 函数执行时,内存中的数据已经更新,但是还没有渲染到页面。 |
updated() | 函数执行时,内存中的数据已经更新,此方法执行完显示页面。 |
beforeDestroy() | 函数在实例销毁之前调用。 |
destroyed() | 函数在Vue 实例销毁后调用 |
7、Vue Router 路由
7.1 什么是路由?
- 在Web开发中,路由是指根据URL分配到对应的处理程序。 路由允许我们通过不同的 URL 访问不同的内容。
- 通过 Vue.js 可以实现多视图单页面web应用(single page web application,SPA)。
7.2 什么是SPA?
- 单页面Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
- 单页应用不存在页面跳转,它本身只有一个HTML页面。我们传统意义上的页面跳转在单页应用的概念下转变为了 body 内某些元素的替换和更新,举个例子:
- 整个body的内容从登录组件变成了欢迎页组件,从视觉上感受页面已经进行了跳转。但实际上,页面只是随着用户操作,实现了局部内容更新,依然还是在index.html 页面中。
- 单页面应用的好处:
- 用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。
- 适合前后端分离开发,服务端提供http接口,前端请求http接口获取数据,使用JS进行客户端渲染。
7.3 路由相关的概念
- router:
是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用(SPA)变得易如反掌,router 就相当于一个管理者,它来管理路由。 - route:
ruter相当于路由器,route就相当于一条路由。比如:Home按钮 => home内容, 这是一条route,news按钮 => news内容,这是另一条路由。 - routes:
是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, {about按钮 => about 内容}]。 - router-link组件:
router-link 是一个组件,是对标签的一个封装。该组件用于设置一个导航链接,切换不同 HTML内容。 to 属性为目标地址,即要显示的内容。 - router-view组件:
路由导航到指定组件后,进行渲染显示页面。
7.4 使用路由
- Vue.js 路由需要载入 vue-router 库。
//方式1: 本地导入
<script src="vue-router.min.js"></script>
//方式2: CDN
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- 使用步骤:
- 定义路由所需的组件。
- 定义路由,每个路由都有两部分: path (路径) 和component (组件)。
- 创建router路由器实例,管理路由。
- 创建Vue实例,注入路由对象,使用$mount() 指定挂载点。
Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),
之后要手动挂载上。new Vue时,el和$mount并没有本质上的不同。
- HTML代码:
<body>
<div id="app">
<h1>网上冲浪.com</h1>
<p>
<!-- 添加超链接,router-link组件来进行导航,to属性指定链接 -->
<router-link to="/home">go to home</router-link>
<router-link to="/news">go to news</router-link>
</p>
<!-- 路由的出口,路由匹配到组件之后,要渲染到这里 -->
<router-view></router-view>
</div>
</body>
- JS代码:
<!-- 导入Vue和router库 -->
<script src="js/vue.min.js"></script>
<script src="js/vue-router.min.js"></script>
<script>
// 1.定义路由所需的组件
const home = { template: "<div>首页 纵览天下大事</div>" };
const news = { template: "<div>新闻 用事实说话</div>" };
// 2.定义路由,每个路由有两部分,path(路径),component(组件)
const routes = [
{ path: "/home", component: home },
{ path: "/news", component: news }
];
// 3.创建路由管理器实例
const router = new VueRouter({
routes: routes
});
// 4.创建Vue实例,将router注入到Vue实例中,让整个应用都拥有路由的功能
var VM = new Vue({
router
}).$mount("#app"); // $mount是手动挂载代替el
</script>
7.5 路由总结
- router是Vue中的路由管理器对象,用来管理路由。
- route是路由对象,一个路由就对应了一条访问路径,一组路由用routes表示。
- 每个路由对象都有两部分:path(路径)和component (组件)。
- router-link 是对a标签的封装,通过to属性指定连接。
- router-view 路由访问到指定组件后,进行页面展示。