Vue
这是一个Vue的入门学习笔记,参考的是黑马程序员的一个4小时快速入门课程,内容比较基础,但很适合没有接触过Vue,但开发需要用到的人快速上手,内容为个人记录,仅供参考!
原视频教程:
基础知识
Vue是一个基于JavaScript的前端框架,可以更便捷的进行前端开发。
HTML中导入Vue 2.X版本:
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
第一个程序:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello Vue!'
}
})
</script>
</body>
</html>
el
挂载点:
- 作用范围:利用CSS的选择器将Vue实例挂在到目标元素,将其
{{}}
内部的同名数据替换。可以作用到命中的元素及其子元素中。 - 挂载点可以用在id选择器也可以用在类选择器,但是id是唯一的,一般建议选择挂在到id选择器。
- 可以设置到
<div>
以外的dom元素中,但不能用于<HTML>
和<BODY>
data
数据对象:
- Vue的数据定义在
data
中 data
中可以写复杂类型数据,语法遵循js规则
本地应用
v-text
指令,和thymeleaf的th:text
用法类似,替换静态文本
v-html
指令,内容中有html结构会被解析为标签
v-on
指令,为元素绑定事件,绑定的方法定义在methods中
简单的计数器功能实现
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="app">
<div class="input-num">
<button @click="sub">
-
</button>
<span>{{num}}</span>
<button @click="add">
+
</button>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
num:1
},
methods: {
add:function(){
if (this.num<10) {
this.num++;
}
else{
alert('已经最大了!');
}
},
sub:function(){
if (this.num>0) {
this.num--;
}
else{
alert('已经最小了!');
}
}
},
})
</script>
</body>
</html>
v-show
指令,显示和隐藏元素
v-if
指令,和v-show
类似,不同在于v-show
是操纵元素的样式style,v-if
是直接操纵dom元素:
可以看到用v-if操纵的p标签直接没有了。
v-bind
指令,为元素绑定属性,完整写法是v-bind:属性名
,简写为:属性名
简单的图片切换
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
.center{
text-align: center;
}
.image{
width: 700px;
}
</style>
</head>
<body>
<div id="app">
<div class="center">
<h2>图片切换</h2>
<!-- 主图 -->
<div>
<img class="image" :src="imgArr[index]"/>
</div>
<!-- 左 -->
<a @click="prev" href="javascript:void(0)" v-show="index!=0">
<button>上一张</button>
</a>
<!-- 右 -->
<a @click="next" href="javascript:void(0)" v-show="index<imgArr.length-1">
<button>下一张</button>
</a>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
imgArr:[
"./images/1.jpg",
"./images/2.jpg",
"./images/3.jpg",
"./images/4.jpg",
"./images/5.jpg",
"./images/6.jpg",
"./images/7.jpg",
"./images/8.jpg",
"./images/9.jpg",
"./images/10.jpg",
"./images/11.jpg",
"./images/12.jpg",
"./images/13.jpg",
"./images/14.jpg",
],
index:0
},
methods: {
prev:function(){
this.index--;
},
next:function(){
this.index++;
}
},
})
</script>
</body>
</html>
v-for
指令,根据数据生成列表结构,经常跟数组一起使用,语法:(item, index) in 数据
v-model
指令,将数据和表单元素的值双向绑定
简单的记事本功能实现
和传统的基于DOM的开发方式不同,vue基于数据开发,更加简单方便
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
#todoapp {}
#todolist {
list-style: none;
}
footer{
display: flex;
justify-content: center;
}
</style>
</head>
<body style="text-align: center">
<!-- 主体 -->
<div id="todoapp">
<!-- 输入框 -->
<div>
<h1>记事本</h1>
<input v-model="inputvalue" @keyup.enter="add" />
</div>
<!-- 列表区域 -->
<div class="main">
<ul id="todolist">
<li v-for="(item, index) in list">
<div>
<span>{{index+1}}.</span>
<label>{{item}}</label>
<button class="destroy" @click="remove(index)">×</button>
</div>
</li>
</ul>
</div>
<!-- 统计和清空 -->
<footer v-show="list.length!=0">
<span class="todo-count" style="order: 1">items left</span>
<div style="order: 0; margin-right: 5px;"> {{list.length}} </div>
<button @click="clear" style="order: 2; margin-left: 30px;">Clear</button>
</footer>
</div>
<!-- 底部 -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#todoapp",
data: {
list: ["吃饭", "睡觉", "写代码"],
inputvalue: ""
},
methods: {
add: function () {
this.list.push(this.inputvalue);
},
remove: function (index) {
this.list.splice(index, 1);
},
clear:function(){
this.list=[];
}
}
})
</script>
</body>
</html>
网络应用
axios:网络请求库,需安装和导包
官网:起步 | Axios 中文文档 | Axios 中文网 (axios-http.cn)
文档:https://github.com/axios/axios
使用unpkg CDN:
axios使用get或post方法发送请求
then方法中的回调函数会在请求成功或失败时触发,回调函数形参可以获取响应内容或错误信息
综合应用
音乐播放器
主界面,使用网易云接口
以下是html,css,js源代码
<!--player.html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="app">
<div id="main">
<div class="search_bar">
<input id="input_search" type="text" v-model="query" @keyup.enter="searchMusic"/>
</div>
<div id="mainContent">
<!-- 音乐列表 -->
<div id="left_list" class="row">
<h2>歌曲列表</h2>
<ul class="music_list">
<li v-for="item in musicList">
<a href="javascript:;" @click="playMusic(item.id)">{{item.name}}</a>
</li>
</ul>
</div>
<!-- 封面 -->
<div id="musicCover" class="row">
<img :src="musicCover">
</div>
<!-- 热门评论 -->
<div id="rightComments" class="row">
<h2>热门评论</h2>
<div id="hotComments">
<dl v-for="item in hotComments">
<div style="display:flex">
<dt><img :src="item.user.avatarUrl"></dt>
<dd id="nickname">{{item.user.nickname}}</dd>
</div>
<dd id="content">{{item.content}}</dd>
</dl>
</div>
</div>
</div>
<div id="audio">
<audio ref="audio" :src="musicUrl" controls autoplay loop>
您的浏览器不支持 audio 标签。
</audio>
</div>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- axios接口地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 自己的js -->
<script src="./js/main2.js"></script>
</body>
</html>
/* style.css */
body{
background-color: white;
}
.search_bar {
text-align: center;
}
#input_search {
width: 500px;
height: 40px;
padding: 0 5px;
margin: 10px 0;
}
.row {
display: inline-block;
height: 550px;
border: 1px solid;
padding: 10px;
}
#mainContent {
display: flex;
height: 570px;
justify-content: center;
}
#left_list {
width: 200px;
}
.music_list {
list-style: none;
border: 1px solid;
height: 470px;
padding-left: 5px;
overflow-y: scroll;
}
a{
text-decoration: none;
}
#musicCover {
width: 550px;
display: flex;
border: 1px solid;
}
#rightComments{
width: 400px;
}
#hotComments {
border: 1px solid;
width: inherit;
height: 470px;
overflow-y: scroll;
}
#hotComments img {
width: 40px;
border-radius: 50%;
}
#hotComments dl {
margin: 10px;
border: 1px solid;
padding: 10px;
}
#hotComments dd{
margin: 0;
}
#nickname{
font-weight: bold;
padding-left: 20px;
line-height: 45.6px;
}
#content{
font-size: small;
}
#audio {
display: flex;
justify-content: center;
}
audio{
width: 1216px;
border: 1px solid;
}
ul {
margin: 0;
}
// main2.js文件
/*
歌曲搜索接口
请求地址:https://autumnfish.cn/search
请求方法:get
请求参数:keywords(查询关键字)
响应内容:歌曲搜索结果
歌曲url获取接口
请求地址:https://autumnfish.cn/song/url
请求方法:get
请求参数:id(歌曲id)
响应内容:歌曲url地址
歌曲详情获取
请求地址:https://autumnfish.cn/song/detail
请求方法:get
请求参数:ids(歌曲id)
响应内容:歌曲详情(包括封面)
热门评论获取
请求地址:https://autumnfish.cn/comment/hot?type=0
请求方法:get
请求参数:id(歌曲id,地址中的type固定为0)
响应内容:歌曲热评
*/
var app = new Vue({
el: "#app",
data: {
query: '',
musicList: [],
musicUrl:"",
musicCover:"",
hotComments:[]
},
methods: {
//歌曲搜索
searchMusic: function () {
var that = this;
axios.get("https://autumnfish.cn/search?keywords=" + this.query)
.then(function (response) {
// console.log(response);
that.musicList = response.data.result.songs;
})
.catch(function (err) { })
},
//歌曲播放
playMusic: function (musicId) {
var that = this;
//歌曲地址获取
axios.get("https://autumnfish.cn/song/url?id=" + musicId)
.then(function (response) {
// console.log(response);
// console.log(response.data.data[0].url);
that.musicUrl=response.data.data[0].url;
})
.catch(function (err) { })
//歌曲地址获取
axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
.then(function (response) {
// console.log(response);
// console.log(response.data.songs[0].al.picUrl);
that.musicCover = response.data.songs[0].al.picUrl;
})
.catch(function (err) { })
//歌曲热评获取
axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
.then(function (response) {
// console.log(response);
// console.log(response.data.songs[0].al.picUrl);
that.hotComments = response.data.hotComments;
})
.catch(function (err) { })
}
}
})