1. Vue基础

1.1 Vue简介

  • JavaScript框架
  • 简化Dom操作
  • 响应式的数据操作

1.2 第一个Vue程序

1.2.1 导入开发环境

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

或者(新手推荐使用)

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

1.2.2 编写页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">{
  {message}}</div>

<script> var vue = new Vue({
      el:"#app", data:{
      message:"i love java !" } }) </script>
</body>
</html>

1.2.3 运行结果

1.3 el挂载点

提出问题

  1. vue实例的作用范围是什么呢?
{
  { message }}
<div class="text">{
  { message }},{
  { info }}}</div>
<script> var el2 = new Vue({
      el:".text", data:{
      message:"测试class选择器~", info: "内部信息" } }); </script>

测试结果:

2. 是否可以使用其它选择器

答:el挂载点命中的有id选择器(#),class选择器(.)和标签选择器(标签名)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>el</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>

<div>{
  { message }}</div>
<div class="text">{
  { message }}</div>
<div id="app">{
  { message }}</div>
<script> var el1 = new Vue({
      el:"div", data:{
      message:"测试标签选择器~" } }); var el2 = new Vue({
      el:".text", data:{
      message:"测试class选择器~" } }); var el3 = new Vue({
      el: "#app", data:{
      message:"测试id选择器~" } }); </script>

</body>
</html>
  1. 是否可以设置其它的dom元素呢?

可以使用常用的标签库,如p标签,h1标签,但推荐使用div标签。

注意

1.4 data数据对象

data域可以存储基本数据类型,还可以存储其它数据类型:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <h2>{
  {name}}</h2>
    <ul>
        <li>{
  {info.age}}}</li>
        <li>{
  {info.tel}}</li>
    </ul>
    <h2>{
  {lan[0]}}</h2>
    <h2>{
  {lan[1]}}</h2>
    <h2>{
  {lan[2]}}</h2>
</div>

<script> var data = new Vue({
      el:"#app", data:{
      name: "liuzeyu", info:{
      age: 14, tel:10086 }, lan:["C++","C","Java"] } }); </script>
</body>
</html>

运行结果:

2. 本地应用

2.1 v-text指令

v-text是一个标签体的属性,可以用于直接替换标签体内容,如果只需要进行部分替换,可以直接使用{ {}}

<div id="app">
    <h2 v-text="message+'@'"></h2>
    <h2>{
  {message}},北京@</h2>
</div>
<script> var v = new Vue({
      el: "#app", data: {
      message:"测试v-text!!!" } }); </script>

运行结果:

2.2 v-htmlt 指令

v-html指令会将带有html标签的字符串转成html

<div id="app">
    <h2 v-html="href">百度</h2>
    <h2 v-text="href">百度</h2>
</div>

<script> var html = new Vue({
      el:"#app", data:{
      href:"<a href='http://www.baidu.com'>百度</a>" } }); </script>

运行结果:

2.3 v-on 指令

v-on指令绑定事件函数,常见的投点击事件,双击事件,鼠标事件

<body>

<div id="app">
    <input type="button" value="v-on指令" v-on:click="doIt" >
    <input type="button" value="v-on简写" @click="doIt">
    <input type="button" value="v-on双击" @dblclick="doIt">
    <h3 @click="doFood" v-text="food"></h3>
</div>

<script> var on = new Vue({
      el:"#app", data:{
      food:"西红柿炒蛋..." }, methods:{
      doIt:function () {
      alert("haha"); }, doFood:function () {
      this.food +="好吃好吃" } } }); </script>
</body>

其中使用this关键字,点击h3会给内容追加字符串,可以不用操作dom元素。


补充:传递自定义参数修饰符

    <input type="button" value="传参" @click="doStudy">
    doStudy:function (msg) {
   	 alert(msg);
	}

2.4 计数器

<body>

<div id="app">
    <button @click="sub">-</button>
    <span v-text="num">{
  {num}}</span>
    <button @click="add">+</button>
</div>

<script> var counter = new Vue({
      el:"#app", data:{
      num: 0 }, methods:{
      sub:function () {
      this.num --; if( this.num < 0 ){
      alert("求求你不要再减了..."); } }, add:function () {
      this.num ++; if(this.num > 10){
      alert("求求你不要再加了..."); } } } }); </script>
</body>

2.5 v-show指令

  • v-show指令的作用:根据表达式的真假切换元素的显示状态
  • 本质是通过操纵<mark>dom标签的属性display</mark>来切换显示状态
  • 表达式的值为true,显示标签的display属性为none
<body>
<div id="app">
    <img src="public/favicon.ico" v-show="isShow">
    <input type="button" value="切换" @click="change">
</div>

<script> var show = new Vue({
      el:"#app", data:{
      isShow:false }, methods:{
      change:function () {
      this.isShow = !this.isShow; } } }); </script>
</body>

2.6 v-if指令

  • v-if指令的作用:根据表达式的真假切换元素的显示状态
  • 本质是通过操纵dom元素来切换显示状态
  • 表达式的值为true,存在存在于dom树中,表达式值为false,从dom树中移除
<body>
<div id="app">
    <p v-if="isShow">刘泽煜</p>
    <input type="button" value="切换" @click="change">
</div>

<script> var v_if = new Vue({
      el:"#app", data:{
      isShow:true }, methods:{
      change:function () {
      this.isShow = !this.isShow; } } }); </script>
</body>

运行结果:

<mark>对比 v-if 和 v-show:</mark>

两者都是显示和隐藏标签内容,但是v-if操作的是dom树的标签,需要删除和添加标签节点,如果是经常需要改变的标签不适合适应,会影响到效率。
v-show则是为标签添加属性和删除属性,适用于经常操作的标签。

2.7 v-bind指令

v-bind为<mark>标签的属性值</mark>添加值,可以增加和修改

<body>

<div id="app">
    <img v-bind:src="imgSrc" width="10%" height="10%">
    <br>
    <img :src="imgSrc" alt="" width="10%" height="10%">
    <hr>
    <img :src="imgSrc" alt="" width="10%" height="10%" :class="isActive?'active':''">
    <img :src="imgSrc" alt="" width="10%" height="10%" :class="{active:isActive}">
    <input type="button" @click="addStyle" value="为照片添加样式">
    <br>
</div>

<script> var img = new Vue({
      el:"#app", data:{
      imgSrc:"http://pngimg.com/uploads/sky_lantern/sky_lantern_PNG65.png", isActive:false }, methods:{
      addStyle:function () {
      this.isActive = !this.isActive; } } }); </script>
</body>

运行结果:

2.8 v-for指令

  • v-for指令的作用是根据数据生成的列表结构
  • 数组常与v-for结合使用
  • 语法是(item,index) in 数据
  • 数组长度的更新会同步到页面上,是响应式的
<body>
<div id="app">
<ul>
    <li v-for="addr in address">{
  {addr}}</li>
</ul>
<hr>
<ul>
    <li v-for="(item,index) in address">{
  {index+1}},{
  {item}}</li>
</ul>

</div>
<script> var v_for = new Vue({
      el:"#app", data:{
      address:["北京","上海","广州","深圳"] person:{
      name:"liuzeyu", age:18 } } }); </script>
</body>

运行结果:

2.9 v-model

v-model的作用是可以将表单得到的值和data中的值进行绑定,并且数据同步是双向的,所谓的双向:指的是我们在input中输入的信息,会被赋值给Vue中的data message变量,之后,message变量又会重新赋值给span标签内容。

<body>


<div id="app">
    <input type="text" v-model="message">
    <span>{
  { message }}</span>
</div>

<script> var model = new Vue({
      el:"#app", data:{
      message:"卧槽!" } }); </script>
</body>

运行结果:

2.10 小黑记事本

需求:


实现对记事本的增加,删除,统计条数,清空功能。

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <title>小黑记事本</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta name="robots" content="noindex, nofollow" />
    <meta name="googlebot" content="noindex, nofollow" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
  </head>

  <body>
    <!-- 主体区域 -->
    <section id="todoapp">
      <!-- 输入框 -->
      <header class="header">
        <h1>小黑记事本</h1>
        <input autofocus="autofocus" autocomplete="off" placeholder="请输入任务" class="new-todo" v-model="inputValue" @keyup.enter="addTodo" />
      </header>
      <!-- 列表区域 -->
      <section class="main">
        <ul class="todo-list">
          <li class="todo" v-for="(item,index) in hobbies">
            <div class="view" >
              <span class="index" >{
  {index}}.</span>
              <label>{
  {item}}</label>
              <button class="destroy" @click="remove(index)"></button>
            </div>
          </li>
        </ul>
      </section>
      <!-- 统计和清空 -->
      <footer class="footer" v-if="hobbies.length != 0">
        <span class="todo-count"> <strong>{
  {hobbies.length}}</strong> items left </span>
        <button class="clear-completed" @click="clear">
          Clear
        </button>
      </footer>
    </section>
    <!-- 底部 -->
    <footer class="info">
      <p>
        <a href="http://www.itheima.com/" ><img src="./img/black.png" alt="" /></a>
      </p>
    </footer>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script> var v = new Vue({
      el:"#todoapp", data:{
      hobbies:["唱歌","吃饭","跳舞"], inputValue:"" }, methods:{
      addTodo:function () {
      this.hobbies.push(this.inputValue); }, remove:function (index) {
      this.hobbies.splice(index,1); //点击一次删除一个 }, clear:function () {
      this.hobbies =[]; //将数组置为空 } } },); </script>
  </body>
</html>

使用到的指令:

1. v-for:遍历集合
2. v-model:数据的双向绑定
3. @click = “”:点击函数

使用到的函数:

1. [].length:求数组的长度
2. [].splice(index,count):删除索引对应的数据
3. [].push:为数组添加元素

3. 网络应用

3.1 axios的基本使用

axios的两种请求方式:

  • get:格式:axios.get(“调用的接口地址?参数1=值1&参数2=值2”).then(回调函数1,回调函数2);
  • post:axios.post(“接口调用地址”,{参数1:“值1”,参数2:“值2”}).then(回调函数1,回调函数2);

<!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>axios基本使用</title>
</head>

<body>
    <input type="button" value="get请求" class="get">
    <input type="button" value="post请求" class="post">

    <!-- 官网提供的 axios 在线地址 -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script> /* 接口1:随机笑话 请求地址:https://autumnfish.cn/api/joke/list 请求方法:get 请求参数:num(笑话条数,数字) 响应内容:随机笑话 */ document.querySelector(".get").onclick = function(){
      axios.get("https://autumnfish.cn/api/joke/list?num=1").then(function (response) {
      console.log(response.data.jokes); },function (err) {
      console.log(err); }) }; /* 接口2:用户注册 请求地址:https://autumnfish.cn/api/user/reg 请求方法:post 请求参数:username(用户名,字符串) 响应内容:注册成功或失败 */ document.querySelector(".post").onclick=function () {
      axios.post("https://autumnfish.cn/api/user/reg",{
     username:"liuzeyu"}).then( function (response) {
      console.log(response.data); },function (err) {
      console.log(err); } ); } </script>
</body>

</html>

3.2 使用axios+vue获取随机笑话

<!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>axios+vue</title>
</head>

<body>
    <div id="app">
        <input type="button" value="获取笑话" @click="getJoke">
        <p> {
  { joke }}</p>
    </div>
    <!-- 官网提供的 axios 在线地址 -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> /* 接口:随机获取一条笑话 请求地址:https://autumnfish.cn/api/joke 请求方法:get 请求参数:无 响应内容:随机笑话 */ var v = new Vue({
      el:"#app", data:{
      joke: }, methods:{
      getJoke:function () {
      var that = this; axios.get("https://autumnfish.cn/api/joke").then( function (response) {
      that.joke = response.data; }, function (err) {
      this.joke = err; } ); } } }); </script>
</body>

</html>

3.3 天知道

<!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/index.css" />
  </head>

  <body>
    <div class="wrap" id="app">
      <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="city" @keyup.enter="search" />
          <button class="input_sub" @click="search">
            搜 索
          </button>
        </div>
        <div class="hotkey">
          <a href="javascript:;" @click="hotadd('北京')">北京</a>
          <a href="javascript:;" @click="hotadd('上海')">上海</a>
          <a href="javascript:;" @click="hotadd('广州')">广州</a>
          <a href="javascript:;" @click="hotadd('深圳')">深圳</a>
        </div>
      </div>
      <ul class="weather_list" >
        <li v-for="(item,index) 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="main.js"></script>
  </body>
</html>

js文件

var v = new Vue({
   
    el:"#app",
    data:{
   
        city:"",
        weatherList:""
    },
    methods:{
   
        search:function () {
   
            // console.log(this.city);
            var that = this;
            axios.get("http://wthrcdn.etouch.cn/weather_mini?city="+this.city).then(function (response) {
   
                // console.log(response.data.data.forecast);
                that.weatherList = response.data.data.forecast;
            },function (err) {
   

            });
        },
        hotadd:function (city) {
   
            this.city = city;
            this.search();
        }
    }
});

运行结果:

4. 综合应用

实现一个在线的音乐播放器:

模块开发:

  1. 歌曲搜索
  2. 歌曲播放
  3. 歌曲封面
  4. 歌曲评论
  5. 播放动画
  6. mv播放

涉及到的接口开发文档:

  1:歌曲搜索接口
    请求地址:https://autumnfish.cn/search
    请求方法:get
    请求参数:keywords(查询关键字)
    响应内容:歌曲搜索结果
  2:歌曲url获取接口
    请求地址:https://autumnfish.cn/song/url
    请求方法:get
    请求参数:id(歌曲id)
    响应内容:歌曲url地址
  3.歌曲详情获取
    请求地址:https://autumnfish.cn/song/detail
    请求方法:get
    请求参数:ids(歌曲id)
    响应内容:歌曲详情(包括封面信息)
  4.热门评论获取
    请求地址:https://autumnfish.cn/comment/hot?type=0
    请求方法:get
    请求参数:id(歌曲id,地址中的type固定为0)
    响应内容:歌曲的热门评论
  5.mv地址获取
    请求地址:https://autumnfish.cn/mv/url
    请求方法:get
    请求参数:id(mvid,0表示没有mv)
    响应内容:mv的地址

静态页面:

<!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>悦听player</title>
  <!-- 样式 -->
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>
  <div class="wrap">
    <!-- 播放器主体区域 -->
    <div class="play_wrap" id="player">
      <div class="search_bar">
        <img src="images/player_title.png" alt="" />
        <!-- 搜索歌曲 -->
        <input type="text" autocomplete="off" v-model="query" @keyup.enter="searchMusic" />
      </div>
      <div class="center_con">
        <!-- 搜索歌曲列表 -->
        <div class='song_wrapper'>
          <ul class="song_list">
           <li v-for="item in musicList">
             <a href="javascript:;" @click="playMusic(item.id)"></a>
             <b>{
  {item.name}}</b>
             <span><i v-show="item.mvid != 0" @click="playMv(item.mvid)"></i></span>
           </li>
          </ul>
          <img src="images/line.png" class="switch_btn" alt="">
        </div>
        <!-- 歌曲信息容器 -->
        <div class="player_con" :class="{playing :isPlaying}">
          <img src="images/player_bar.png" class="play_bar" />
          <!-- 黑胶碟片 -->
          <img src="images/disc.png" class="disc autoRotate" />
          <img :src="musicCover" class="cover autoRotate" />
        </div>
        <!-- 评论容器 -->
        <div class="comment_wrapper">
          <h5 class='title'>热门留言</h5>
          <div class='comment_list'>
            <dl v-for="item in musicComments">
              <dt><img :src="item.user.avatarUrl" alt=""></dt>
              <dd class="name">{
  {item.user.nickname}}</dd>
              <dd class="detail">
                {
  {item.content}}
              </dd>
            </dl>
          </div>
          <img src="images/line.png" class="right_line">
        </div>
      </div>
      <div class="audio_con">
        <audio ref='audio' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"></audio>
      </div>
      <div class="video_con" style="display: none;" v-show="isShow">
        <video controls="controls" :src="mvUrl"></video>
        <div class="mask" @click="closeMv"></div>
      </div>
    </div>
  </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>

  <script src="main.js"></script>
</body>

</html>

js文件:

var v = new Vue({
   
    el:"#player",
    data:{
   
        query:"",
        musicList:[],
        musicUrl:"",
        musicCover:"",
        musicComments:[],
        isPlaying:false,
        isShow:false,
        mvUrl:""
    },
    methods:{
   
        //搜索音乐
        searchMusic:function () {
   
            var that  = this;
            axios.get("https://autumnfish.cn/search?keywords="+this.query).then(function (response) {
   
                that.musicList = response.data.result.songs;
                console.log(response);
            },function (err) {
   
                //console.log(err);
            });
        },
        //点击播放音乐
        playMusic:function (musicId) {
   
            var that = this;
            axios.get("https://autumnfish.cn/song/url?id="+musicId).then(function (response) {
   
                that.musicUrl = response.data.data[0].url;
            },function (err) {
   
                console.log(err);
            });
            axios.get("https://autumnfish.cn/song/detail?ids="+musicId).then(
                function (response) {
   
                    that.musicCover = response.data.songs[0].al.picUrl;
                },function (err) {
   

                }
            );
            axios.get("https://autumnfish.cn/comment/hot?type=0&id="+musicId).then(function (response) {
   
                that.musicComments = response.data.hotComments;
            },function (err) {
   


            });

        },
        pause:function () {
   
            this.isPlaying = false;
        },
        play:function () {
   
            this.isPlaying = true;
        },
        //播放MV
        playMv:function (mvid) {
   
            var that = this;
            axios.get("https://autumnfish.cn/mv/url?id="+mvid).then(function (response) {
   
                that.isShow = true;
                that.mvUrl = response.data.data.url;
            },function (err) {
   

            });
        },
        //关闭MV
        closeMv:function () {
   
            this.isShow = false;
        }

    }
});

参考:黑马视频学习