01-案例-天气预报查询:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>天知道</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/iconfont.css" />
<link rel="stylesheet" href="css/main2.css" />
<style>
.tem .iconfont {
font-size: 50px;
}
/* 进入动画,离开动画执行动画体 */
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
/* 进入动画体的时候延迟 */
.fade-enter-active:nth-child(1){
transition-delay: 0s;
}
.fade-enter-active:nth-child(2){
transition-delay: 0.3s;
}
.fade-enter-active:nth-child(3){
transition-delay: 0.6s;
}
.fade-enter-active:nth-child(4){
transition-delay: 0.9s;
}
.fade-enter-active:nth-child(5){
transition-delay: 1.2s;
}
/* 从下面状态到正常状态,从正常状态到下面状态 */
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: translateY(80px);
}
</style>
</head>
<!--
分析过程
1.搜索功能
1.1 input框 v-model = "cityName" @keyup.enter = 'search搜索事件'
1.2 搜索按钮 @click="search搜索事件"
1.3 search搜索事件
a.发送axios请求,获取查询的天气,存起来list数组中
b.给显示天的li标签设置v-for
2.loading动画
给搜索按钮绑定一个loading类, 一开始绑定的布尔值是false .
搜索事件里面改成true, 完成搜索后又改回false.
3.热门城市搜索
给热门城市这些a标签设置一个事件. 把热门城市名给带过去.
热门城市名就赋值给cityName
调用搜索方法search
4.多元素动画
4.1动画都是由先决条件的, 进入/离开 v-if/v-show
用!loading就可以
点击搜索按钮还没有出来数据, loading是true, 那!loading不就是false. 那就不显示.
搜索完成了数据已经来了, loading就是false, 那!loading不就是true, 那就显示.
4.2做动画的多元素要用transition-group 包起来, transition-group标签后面还要有一个name属性.
做动画的多元素的每一个元素都要有一个key
name属性的值,是样式的前缀.
4.3
.fade-enter-active 进入动画执行体 不要在这里写其他的样式,在这里写transition或者animation
.fade-leave-active 离开动画执行体 不要在这里写其他的样式,在这里写transition或者animation
.fade-enter 进入时,从什么状态到正常状态,这里就写这个什么状态.
.fade-leave-to 离开时,从正常状态到离开状态,这里就写这个什么状态.
//进入动画有延时.
.xxx-enter-active:nth-child(1) {
transition-delay: 0s;
}
5.默认城市搜索
5.1 把搜索城市变量名cityName 赋值一个默认城市名
5.2 把搜索事件search写在生命周期钩子函数 created 里面.
-->
<body>
<div class="wrap" id="wrap">
<div class="search_form">
<div class="logo"><img src="img/logo.png" alt="logo" /></div>
<div class="form_group">
<input type="text" class="input_txt" placeholder="请输入查询的天气" v-model="cityName" @keyup.enter="search" />
<button class="input_sub" @click="search" :class="{loading:loading}">搜 索</button>
</div>
<div class="hotkey">
<a href="javascript:;" @click="hotKeySearch">北京</a>
<a href="javascript:;" @click="hotKeySearch">上海</a>
<a href="javascript:;" @click="hotKeySearch">广州</a>
<a href="javascript:;" @click="hotKeySearch">深圳</a>
<!-- 这是第一种方式传递热词,传参 -->
<!-- <a href="javascript:;" @click="hotKeySearch(武汉)">武汉</a> -->
</div>
</div>
<ul class="weather_list">
<transition-group name="fade">
<li v-if="!loading" v-for="(item, index) in list" :key="index">
<div class="info_type">
<!--雨 -->
<span class="iconfont" v-if="item.type.includes('雨')"></span>
<!-- 晴 -->
<span class="iconfont" v-else-if="item.type.includes('晴')"></span>
<!-- 阴 -->
<span class="iconfont" v-else-if="item.type.includes('阴')"></span>
<!-- 雪 -->
<span class="iconfont" v-else-if="item.type.includes('雪')"></span>
<!-- 云 -->
<span class="iconfont" v-else-if="item.type.includes('云')"></span>
<!-- 雷 -->
<span class="iconfont" v-else-if="item.type.includes('雹')"></span>
<!-- 雹 -->
<span class="iconfont" v-else-if="item.type.includes('晴')"></span>
<!-- 雾 -->
<span class="iconfont" v-else></span>
</div>
<div class="info_temp">{{item.high}}</b><br />{{item.low}}</div>
<div class="info_date"><b>{{showCity}}</b><span>{{item.date}}</span></div>
</li>
</transition-group>
</ul>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
var app = new Vue({
el: '#wrap',
data: {
// 用户输入搜索天气的城市
cityName: "深圳",
// 存放五个天气1的数组
list: [],
// 用来做天气预测里面展示城市的变量
showCity: "",
// 显示loading动画是否展示的布尔值(一开始不展示)
loading: false
},
methods: {
search() {
if (!this.cityName) {
alert('请输入正确的城市!不能为空哦!');
return;
}
// 把控制loading动画的布尔值改成true(按搜索开始展示)
this.loading = true
// 搜索事件里面发送axios请求
axios({
method: 'get',
url: 'http://wthrcdn.etouch.cn/weather_mini',
params: {
city: this.cityName
}
}).then((res) => {
//console.log(res);
//把返回的天气数据给保存起来
this.list = res.data.data.forecast
this.showCity = res.data.data.city
//把控制loading动画的布尔值改成false(搜索成功之后就不展示了)
this.loading = false
})
},
hotKeySearch(e) {
// 1.把热门城市名用参数的方式传递下来
// this.cityName=city
// 2.把热门城市名,通过事件对象的方式给拉下来
this.cityName = e.target.innerText
this.search()
}
},
//生命周期钩子函数 created
created() {
// 一进入页面就有默认城市(深圳)的天气展示
this.search()
},
});
</script>
</body>
</html>
效果展示说明: 页面一打开自动发送请求深圳天气预报
点击搜索按钮跟回车可以拿到用户在输入框输入的城市的天气预报
输入框下面的热门城市也可以发送请求拿到天气预报
拿到的天气预报都装在li标签里面, 利用昨天学的 在vue中的过渡动画 将每个li中的数据以动画的形式展示在页面上
02- 补充关于事件对象$event:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- <button @click="btnClick">点我啊</button> -->
<!-- btnClick($event)这才是完整写法
$event:事件对象,也就是事件驱动源
如果事件后面带括号,需要使用事件对象,就一定要在括号里面传入实参$event
如果事件后面没有括号,vue帮我们默认传递了实参$event
-->
<body>
<div id='app'>
<button @click="btnClick1">点我1</button>
<button @click="btnClick2()">点我2</button>
<button @click="btnClick3(10)">点我3</button>
<button @click="btnClick4(10,$event)">点我4</button>
<button @click="btnClick5($event)">点我5</button>
</div>
<script src='./vue.js'></script>
<script>
var app = new Vue({
el:'#app',
data:{
msg:"你好鸭"
},
methods:{
btnClick1(e){
console.log(e);//事件对象
},
btnClick2(e){
console.log(e);//undefined
},
btnClick3(e){
console.log(e);//10
},
btnClick4(num,e){
console.log(num);//10
console.log(e);//事件对象
},
btnClick5(e){
console.log(e);//事件对象
},
}
});
</script>
</body>
</html>
效果展示说明: vue中$ event 是事件对象
如果写了事件有()要用事件对象就要把$event传过去,没写()不写参数就是默认会传递事件对象过去
03- 组件安装:
- 1.安装node
- 2.npm指向淘宝镜像(下载比较快) 命令: npm install -g cnpm --registry=https://registry.npm.taobao.org
- 3.下载vue的脚手架插件 命令:npm install -g @vue/cli
再输入命令:vue -V /(如果安装成功会返回:@vue/cli 4.0.5类似这样的版本信息) - 4.安装单文件组件依赖包,命令:npm install @vue/cli-service-global -g
如果是cnpm安装的用命令:cnpm install @vue/cli-service-global -g
如果是yarn安装的用命令:yarn global add @vue/cli-service-global - 5.在.vue的文件中写好代码,要运行,就是说要运行单文件组价,首先在相应目录下,一定要是.vue文件所在的文件夹哦!这个目录下打开cmd或者powerShell(按住shift右键)出现小黑框,此时里面的路径是所在文件夹的路径,再运行命令:vue serve 单文件组件名,再把出来的地址localhost:8080这种复制到浏览器ok了
安装vue/cli脚手架出错解决方案 (如果 vue -V无法显示版本信息,说明安装失败)
1.更换网络连接换WiFi
2.更换安装的工具,
a.比如用cnpm安装,先安装cnpm(指向淘宝镜像)命令:npm install -g cnpm --registry=https://registry.npm.taobao.org
再用cnpm安装vue/cl,命令:npm install -g @vue/cli
b.比如用yarn安装,先安装yarn,命令:npm install -g yarn
再用yarn安装vue/cl,命令:yarn global add @vue/cli
3.清除npm缓存之后重新安装,
a.清除缓存命令npm cache clean -f
a.重新执行安装的命令
b.在用脚手架搭建vue项目时,提示:无法加载文件 C:\Users\电脑用户名\AppData\Roaming\npm\vue.ps1,因为在此系统禁止运行脚本,这是你笔记本禁止运行脚本,解决办法命令: set-ExecutionPolicy RemoteSigned
04- 组件结构:
<template>
<!--
1.这里就是写html的地方
注意点: 需要用一个标签包裹
-->
<div>
<button @click='btnClick'>点我呀</button>
<p class="oneP">我是一个p,{{msg}}</p>
<div class="oneDiv">我是一个div,{{info}}</div>
</div>
</template>
<script>
/*
2.这里就是用来写js代码的代码
注意:
a.不需要再写new Vue({}); 下面这个export default {}大括号就相当于是以前的new Vue的大括号
b.不需要在大括号里面写el了. 因为vue组件已经知道template里面的标签就是挂载点.
c.data现在不再是一个对象了,而是一个返回对象的函数.
其他的都是一样的写
*/
export default {
data() {
return {
msg:'这是一个寂寞的天',
info:'下着有些伤心的雨'
}
},
methods: {
btnClick(){
this.msg = '哈哈哈哈';
}
},
created() {
},
mounted() {
},
};
</script>
<style>
/*
3.这里是写css的地方.
注意:
如果要引入外部的css文件. 用@import url(路径)
*/
.oneP {
width: 200px;
height: 200px;
background-color: green;
}
@import url('./index.css');
</style>
效果展示说明 上面是在后缀.vue文件写的,此文件三大部分: template
、 script
、 style
是单文件组价…写好之后运行:在cmd窗口该vue文件根目录下输入vue serve 组件结构.vue
这里组件结构.vue
是需要运行的单文件组件的路径
05- 如何在组件中引入其他组件
App.vue文件(主组件)
<template>
<!--
如何在组件中引入其他的组件?
1.导入组件:import 自定义一个组件名 from "组件路径"
a.自定义一个组件名可以自己随便写,一般情况下和组件名一致
b.组件路径的./不要省略
c.组件路径引入的文件后缀可以省略.vue
2.注册组件:都要写在components对象里面
3.使用组件 :当做标签来使用,目前不要在你当标签的这个组件中间写内容
-->
<div>
<p class="one">我是App.vue主组件</p>
<!-- 3.使用组件,这里的标签就是注册组件时写在左边的son -->
<son></son>
</div>
</template>
<script>
//1.导入组件
import son from "./components/son"
export default {
// 2.注册组件
components:{
son:son//可以简写成一个son就行es6语法,其中后面那个son是导入组件时自己自定义的组件名
}
}
</script>
<style>
.one{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
son.vue文件(要引入的其他组件)
<template>
<div class="divBox">要引入的其他组件</div>
</template>
<script>
export default {
}
</script>
<style>
.divBox{
width: 200px;
height: 200px;
background-color: red;
}
</style>
效果展示说明 小黑框运行vue serve App.vue,然后浏览器输入地址即可
06- 利用 在组件中引入其他组件 做京东页面(图片而已)
App.vue文件(主组件)
<template>
<div>
<!-- 3.使用组件 -->
<top></top>
<middle></middle>
<bottom></bottom>
</div>
</template>
<script>
// 1.导入组件
import top from "./components/top";
import middle from "./components/middle";
import bottom from "./components/bottom";
export default {
// 2.注册组件
components: {
top, //top:top,
middle,
bottom
}
};
</script>
<style>
</style>
bottom.vue文件(要引入的其他文件):
<template>
<div>
<img class="W" src="../assets/bottom.png" alt="">
</div>
</template>
<script>
export default {
}
</script>
<style>
.W {
width: 100%;
}
</style>
middle.vue文件(要引入的其他文件):
<template>
<div>
<img class="W" src="../assets/middle.png" alt="">
</div>
</template>
<script>
export default {
}
</script>
<style>
.W {
width: 100%;
}
</style>
top.vue文件(要引入的其他文件):
<template>
<div>
<img class="W" src="../assets/top.png" alt="">
</div>
</template>
<script>
export default {
}
</script>
<style>
.W {
width: 100%;
}
</style>
效果展示说明: 把某个界面或者说某个小功能,封装起来就叫组件(就是对html css js的一个综合封装),组件也是Vue的实例,所以它也有自己的data和methods以及生命周期钩子等
这里是我截的三张图,如果实际开发中,有三个人做,就可以分模块化开发,比如一个人做top(就在top.vue文件中写代码),一个做middle部分(就在middle.vue文件中写代码),一个做bottom部分(就在bottom.vue文件中写代码)
组件的好处不就体现出来了:可复用,同时会简化代码结构,易于维护,同时利于多人协同开发。
07- 组件中如何使用外部插件(例如axios):
App.vue文件(主组件)
<template>
<div class="main">
<input type="text" name id v-model="songName" @keyup.enter="btnClick" placeholder="请输入歌曲名"/>
<button @click="btnClick">搜索</button>
<ul class="ulBox">
<li v-for="(item, index) in list" :key="index" @dblclick="play(item.id)">{{item.name}}</li>
</ul>
<!-- 播放标签 -->
<audio :src="songUrl" controls autoplay></audio>
</div>
</template>
<script>
// 使用axios
// 1:安装(安装外部插件axios),到相应目录下执行该命令:npm i axios
// 2:导包(在单文件组件中导入外部插件) import axios from "axios"
// 3:使用(在相应代码位置使用)
import axios from "./node_modules/axios";
export default {
data() {
return {
// 存放用户输入的搜索歌曲
songName: "",
// 存放搜索对应的所有歌曲数组
list: [],
// 存放歌曲播放地址
songUrl: ""
};
},
methods: {
// 点击搜索事件
btnClick() {
// 发送axios请求,得到搜索对应的歌曲显示在li中
axios({
method: "get",
url: "http://183.237.67.218:3000/search",
params: {
keywords: this.songName
}
}).then(res => {
//console.log(res);
//把返回的所有歌曲存起来
this.list = res.data.result.songs;
});
},
play(id) {
//发送axios请求,得到点击的歌曲的播放地址
axios({
method: "get",
url: "http://183.237.67.218:3000/song/url",
params: {
id
}
}).then(res => {
//console.log(res);
//把返回的歌曲播放地址给存起来
this.songUrl = res.data.data[0].url;
});
}
}
};
</script>
<style>
* {
margin: 0;
padding: 0;
}
.main {
width: 400px;
height: 500px;
margin: 0 auto;
}
.ulBox {
width: 100%;
height: 100%;
background: pink;
margin: 10px auto;
overflow: auto;
}
.ulBox li{
cursor: default;
user-select: none;
}
</style>
效果展示说明 组件中使用外部插件三步走:安装包,导包,使用,上面代码注释也有写
这是做的一个播放器,点搜索按钮或者回车可以 以搜索的歌曲发送请求,得到所有歌曲展示在ul中的li中
双击歌曲,以歌曲id发送请求得到歌曲的播放地址,再赋值给audio标签里面的src属性
完成!