主頁 > 前端設計 > Vue基礎入門

Vue基礎入門

2021-07-31 08:22:57 前端設計

文章目錄

  • Vue基礎入門
    • 1、Vue基礎入門
      • 1.1 前置知識
      • 1.2 前端的發展(了解)
      • 1.3 Vue是什么
      • 1.4 第一個Vue程式
        • 1.4.1 Vue程式分析
    • 2、Vue指令
      • v-text
      • v-html
      • v-on(基礎)
      • v-show
      • v-if
      • v-bind
      • v-for
      • v-on(補充)
      • v-model
    • 3、Vue網路應用
      • 3.1 什么是Axios
      • 3.2 Axios基本使用
      • 3.3 Vue整合Axios
    • 4、案例
      • 4.1 計數器
      • 4.2 圖片切換
      • 4.3 記事本
        • index.css
        • 記事本.html
      • 4.4 天氣查詢
        • main.js
        • index.css
        • 天氣查詢.html
      • 4.5 音樂播放器
        • index.css
        • main.js
        • 音樂播放器.html
    • 5、其他資料(福利)

Vue基礎入門

這個筆記是學習Vue.js的時候做的,視頻鏈接:黑馬程式員vue前端基礎教程-4個小時帶你快速入門vue

這個教程只是基礎入門,真的基礎,,,如果想實際開發的話,還遠遠不夠,我是學后端的,所以前端我也不太會,但是可以交流一下,在學習程序中可以參考我做的這個筆記,也可以參考別人的,反正希望大家都能學好,這個是我寫的第一篇博客,有什么不足的地方,歡迎指正和點贊,后續會寫更多的博客

別人的github上有這個Vue.js入門案例的素材,寫完筆記才發現,巨虧,,,點擊下面的鏈接即可,

有需要的也可以看看這個,別人寫的比較好的筆記

文章最后有福利,但是還是希望大家能耐心看完這篇文章,然后高抬貴手,點個贊,謝謝~

1、Vue基礎入門

1.1 前置知識

在學習 Vue 之前,建議先學HTML,CSS,JavaScript,AjAx,對前端基礎有一定的了解和掌握再來學Vue,因為Vue是建立在這些基礎上的一個JavaScript框架,


1.2 前端的發展(了解)

在聊 Vue 之前先來了解一下前端的發展歷程,我學東西喜歡把前因給弄清楚,才不至于學得一臉懵逼,

  • 靜態頁面

    最初的網頁以HTML為主,是純靜態的網頁,網頁是只讀的,資訊流只能從服務端到客戶端單向流通,開發人員
    也只關心頁面的樣式和內容,

  • 動態頁面

    1995年,網景工程師Brendan Eich 花了10天時間設計了JavaScript語言,
    隨著JavaScript的誕生,我們可以操作頁面的DOM元素及樣式,頁面有了一些動態的效果,但是依然是以靜態為主,

  • 異步重繪

    2005年開始,ajax逐漸被前端開發人員所重視,因為不用重繪整個頁面就可以更新頁面的資料和渲染效果,實際上就是一個區域重繪的效果,當每次頁面上的資料發生變化,只需要重新渲染資料發生變化的區域即可,不用重繪整個頁面,大大縮短了回應時間,提高了用戶體驗,
    此時的開發人員不僅僅要撰寫HTML樣式,還要懂ajax與后端互動,然后通過JS操作DOM元素來實作頁面動態效果,比較流行的框架如 jQuery 就是典型代表,

到這里,基本的前端撰寫是沒有問題了,也可以從后臺獲取資料模型,
通過JS操作頁面的DOM元素,將從后臺獲取到的資料模型,渲染到頁面中了,
同時結合AjAx實作了頁面的區域重繪,
但也存在一些問題,如下:

開發人員從后端獲取需要的資料模型,然后要通過DOM操作Model,將資料渲染到View中,

而后當用戶操作視圖,我們還需要通過DOM獲取View中的資料,然后同步到Model中,

開發人員仍然要面對很繁瑣的DOM操作,這就是存在的問題,

  • 2008年,google的Chrome發布,隨后就以極快的速度占領市場,超過IE成為瀏覽器市場的主導者,
  • 2009年,Ryan Dahl在谷歌的Chrome V8引擎基礎上,打造了基于事件回圈的異步IO框架:Node.js,
  • 2010年,NPM作為node.js的包管理系統首次發布,開發人員可以遵循Common.js規范來撰寫Node.js模塊,然后發布到NPM上供其他開發人員使用,目前已經是世界最大的包模塊管理系統,
  • node.js的偉大之處不在于讓JS邁向了后端開發,而是構建了一個龐大的生態系統,
  • 隨后,在node的基礎上,涌現出了一大批的前端框架,Vue 就是其中一個,

剛剛在上面我們發現了一些存在的問題,為了解決上面的這些問題,提出了 MVVM 模式,

MVVM模式

  • M:即Model,模型,包括資料和一些基本操作
  • V:即View,視圖,頁面渲染結果
  • VM:即View-Model,模型與視圖間的雙向操作(無需開發人員干涉)

MVVM模式采用了資料雙向系結機制,也就是說,View的變動,會自動反映在ViewModel上,反之亦然,這樣,開發者就不用手動偵聽事件并觸發相應的View的更新了,因為這些都由MVVM中的VM搞定了,

MVVM中的VM要做的事情就是把DOM操作完全封裝起來,開發人員不用再關心Model和View之間是如何互相影響的:
1、只要Model發生了改變,View上自然就會表現出來,
2、當用戶修改了View,Model中的資料也會跟著改變,

備注:Vue就是MVVM模式的一種實作框架,

關于MVVM模式可以參考下面的鏈接:

維基百科(需要翻墻)

淺析前端開發中的 MVC/MVP/MVVM 模式

秒懂MVVM模式在Android中的應用


1.3 Vue是什么

Vue 是一套用于構建用戶界面漸進式JavaScript框架,與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用,Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有專案整合,另一方面,當與現代化的工具鏈以及各種支持類別庫結合使用時,Vue 也完全能夠為復雜的單頁應用提供驅動,
前端框架三巨頭:Vue.js、React.js、AngularJS,vue.js以其輕量易用著稱,vue.js和React.js發展速度最快,
特點:

  • 漸進式的JavaScript框架

  • 簡化DOM操作

  • 回應式資料驅動

    漸進式:

  • 可以選擇性的使用該框架的一個或一些組件,這些組件的使用也不需要將框架全部組件都應用;

  • 而且用了這些組件也不要求你的系統全部都使用該框架,


1.4 第一個Vue程式

Vue.js官網

步驟:

新建一個HTML檔案,撰寫簡單的html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue-HelloWorld</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>

打開官網,匯入開發版本的Vue.js(要在使用Vue之前引入),

<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

創建Vue實體物件,設定 eldata 屬性,

<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue!'
        }
    })
</script>

使用簡潔的(差值運算式)模板語法 {{}} 把資料渲染到頁面上,

<div id="app">
    {{message}}
</div>

完整代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue-HelloWorld</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>

<div id="app">
    {{ message }}
</div>

<script>
    var app = new Vue({
        /*el:通過該屬性和div進行系結,div的id屬性值和該屬性值相同,
        也可以是其他選擇器,但推薦使用id選擇器*/
        el: '#app',
        /*data:放置要渲染的資料*/
        data: {
            /*message:要和{{ }}中的字串一樣*/
            message: 'Hello Vue!'
        }
    })
</script>
</body>
</html>

1.4.1 Vue程式分析

{{ }}:差值運算式,和下面學到的v-text指令差不多,

理解成Vue的一種語法即可,用于把資料渲染到頁面中,

el:Vue程式掛載點

  • el的作用是什么?

    el是用來設定Vue實體掛載(管理)的元素,
    
  • Vue實體的作用范圍是什么?

    Vue會管理el屬性對應的元素和它內部的后代元素,
    
  • 是否可以使用其他選擇器?

    可以使用其他選擇器,但是建議使用id選擇器,
    因為id選擇器一般是唯一的,
    
  • 是否可以設定其他的DOM元素?

    Vue可以設定在雙標簽中,但不支持HTML和 body 標簽,
    也不支持設定在單標簽中,因為單標簽之間不能寫內容,
    

data:Vue的資料物件,用于存放資料的,

  • 可以存字串
  • 可以存陣列
  • 可以存物件

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data資料物件</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <p>{{msg}}</p>
    <p>{{people.name}}</p>
    <p>{{people.age}}</p>
    <p>{{hobby[0]}}</p>
    <p>{{hobby[2]}}</p>
    <p>{{hobby[5]}}</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            //字串
            msg: '隔壁老王來了',
            //物件
            people: {
                name: '老王',
                age: 18
            },
            //陣列
            hobby: [
                '打籃球', '打游戲',
                '看美女', '旅游',
                '聽音樂', '看電影']
        },
        methods: {
            add: function () {
                console.log("add...");
            }
        }
    });
</script>
</body>
</html>

data總結

  • data用于定義Vue中用到的資料
  • data中可以寫復雜型別的資料
  • 渲染復雜型別資料時,遵循JS的語法即可,如:物件的 . 語法,陣列的索引語法,

拓展:methods

  • methods中用于定義方法(函式),

2、Vue指令

1、內容系結,事件系結(v-text,v-html,v-on(基礎))

v-text

作用:

  • 設定標簽文本的文本值(textContent),無論設定什么內容,只會決議為文本
  • v-text會替換標簽內的文本值,{{}}不會替換,相當于拼接字串
  • v-text和{{}} 都支持運算式

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-text指令</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>

<div id="app">
    <div>
        <!--會被替換-->
        <h2 v-text="msg">廣州</h2>
        <!--相當于拼接-->
        <h2>{{msg}}廣州</h2>
    </div>
    <div>
        <!--兩種方式都可以進行字串拼接-->
        <h2 v-text="info+'北京'">廣州</h2> <!--“廣州”會被替換-->
        <h2>{{info + "廣州"}}</h2>
    </div>
</div>

<script>
    var app = new Vue({
        el: '#app',
        data: {
            msg: '深圳',
            info: '666'
        }
    })
</script>
</body>
</html>

v-html

作用:

  • 設定標簽的innerHTML,如果設定的是文本,則原樣顯示,如果設定的是html,則會被決議成對應的網頁效果,
  • 決議文本用v-text,決議html用v-html

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-html指令</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>

<div id="app">
    <div>
        <!--普通文本和v-text顯示效果一樣-->
        <!--‘哈哈哈’會被全部替換-->
        <p v-html="content">哈哈哈</p>
        <p v-text="content">哈哈哈</p>
    </div>
    <div>
        <!--v-html決議為網頁效果-->
        <p v-html="msg"></p>
        <!--v-text決議為純文本-->
        <p v-text="msg"></p>
    </div>
</div>

<script>
    var app = new Vue({
        el: '#app',
        data: {
            content: "嘿嘿嘿~~",
            msg: "<a href='https://www.baidu.com'>百度</a>"
        }
    })
</script>
</body>
</html>

v-on(基礎)

作用:

  • 為元素系結事件,如:滑鼠點擊,滑鼠移出,按下鍵盤事件…
  • 事件名不用寫on
  • 指令可以簡寫為@
  • 事件系結的方法(也就是事件觸發時執行的函式)定義在methods
  • 方法內部可以通過this來呼叫data中的資料,方法中的this指代的是當前Vue實體

代碼如下:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>v-on基礎</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <input type="button" value="v-on指令" v-on:click="doWatchTV"/>
    <input type="button" value="v-on指令-@簡寫" @click="doWatchTV"/>
    <input type="button" value="v-on指令-@雙擊" @dblclick="doWatchTV"/>
    <h2 @click="changeFood">{{food}}</h2>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            food: "西紅柿炒蛋"
        },
        methods: {
            doWatchTV: function () {
                alert("看電視");
            },
            changeFood: function () {
                /*方法中的this指向的是Vue實體物件*/
                this.food += "超好吃的!"
            }
        }
    })
</script>
</body>
</html>

2、顯示,條件系結,屬性系結(v-show,v-if,v-bind)

v-show

作用:

  • 根據給定運算式,判斷運算式值的真偽,來控制元素的顯示和隱藏(原理是修改元素的display屬性值),
  • 指令后面的內容最終都會決議為布林值,原理是修改元素的display屬性值,實作顯示隱藏,
  • 在要控制的元素標簽里使用v-show指令,值為布林值,true顯示,false隱藏,
  • 資料改變之后,對應元素的值也會同步更新,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-show指令</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <span v-show="isShow">{{ msg }}</span>
    <div v-show="age>=18">老王 {{age}} 歲了,可以看到了,哇哈哈哈~~~</div>
    <button @click="changeShow">改變文字顯示狀態</button>
    <button @click="changeAge">年齡累加</button>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            msg: '老王666',
            age: 17,
            content: "",
            isShow: false
        },
        methods: {
            changeShow: function () {
                this.isShow = !this.isShow;
            },
            changeAge: function () {
                this.age++;
            }
        }
    })
</script>
</body>
</html>

v-if

作用:

  • 根據運算式的真偽,切換元素的顯示隱藏(原理是操作的是DOM元素),
  • 操作DOM的性能消耗較大,v-if是直接從DOM中移除元素,因此頻繁切換的元素使用v-show

用法:

  • v-show一樣的用法,只是本質不一樣,把v-show換成v-if即可,

v-bind

作用:

  • 設定元素的屬性,如a標簽的href屬性,img的src屬性,class類樣式屬性…

用法:

  • v-bind:屬性名=運算式
  • :屬性名=運算式

代碼如下:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>v-bind指令</title>
</head>
<style>
    .demo {
        width: 100px;
        height: 100px;
        margin-top: 12px;
        background-color: aliceblue;
    }

    #active {
        border-radius: 50%;
        background-color: red;
    }
    #active2 {
        border-radius: 50%;
        background-color: green;
    }
</style>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <!--標簽屬性的系結-->
    <!--方式一-->
    <div>
        <a v-bind:href="aHref">百度</a>
    </div>
    <!--方式二 簡寫-->
    <div>
        <a :href="aHref">百度一下</a>
    </div>
    <!--元素樣式的系結-->
    <!--方式一:三元運算式-->
    <div :id="isActive?'active':''" class="demo" @click="changeActive">
    </div>
    <!--方式二:物件方式 active2這個選擇器是否生效,取決于isActive的值,
    不知道為什么沒生效...
    -->
    <div :id="{active2:isActive}" class="demo" @click="changeActive">
    </div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            isActive: false,
            aHref: "https://www.baidu.com"
        },
        methods: {
            changeActive: function () {
                console.log("changeActive...");
                this.isActive = !this.isActive;
            }
        }
    })
</script>
</body>
</html>

3、串列回圈,表單元素系結(v-for,v-on(補充),v-model)

v-for

作用:

  • 用于生成串列和遍歷資料,
  • 可以結合其他指令一起使用,

用法:

  • 情況1:v-for=“當前回圈到的元素 in 待回圈的資料” :key=“唯一值”
  • 情況2:v-for="(當前回圈到的元素,當前的索引) in 待回圈的資料" :key=“索引”
  • vue中,回圈的時候,key屬性加不加不會報錯,只是為了提高頁面的渲染性能,建議加上,不影響顯示效果,
  • 如果沒有id,可以考慮使用索引替代,切記key的值不能重復,只要遵循不重復的原則即可,值是什么無所謂,

代碼如下:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>v-for指令</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>

<div id="app">
    <!--普通陣列-->
    <p>第一種寫法</p>
    <ul>
        <li v-for="item in arr">
            {{item}}
        </li>
    </ul>
    <br/>
    <p>第二種寫法</p>
    <ul>
        <li v-for="(item,index) in arr" :key="index">
            {{index+1}}--{{item}}
        </li>
    </ul>

    <div>
        <!--物件陣列,v-bind:屬性名=屬性值 是進行屬性系結的,可簡寫為 :屬性名=屬性值-->
        <h3 v-for="(item,index) in people" :key="index" v-bind:title="item.name">
            {{index}}-->{{item.name}}
        </h3>
    </div>

    <!--測驗陣列資料變化對v-for的影響-->
    <div>
        <button @click="add">添加資料</button>
        <button @click="remove">移除資料</button>
    </div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            /*普通陣列*/
            arr: ["Java", "HTML", "JavaScript", "Vue.js"],
            /*物件陣列*/
            people: [
                {name: "老王"},
                {name: "小紅"},
                {name: "小歐"}
            ]
        },
        methods: {
            add: function () {
                this.people.push({name: "小盧"});
            },
            remove: function () {
                /*shift();默認移除最左邊的元素*/
                this.people.shift();
            }
        }
    })
</script>
</body>
</html>

v-on(補充)

補充:

  • 事件傳參
    • 定義方法時需要定義形參來接收傳入的實參,
  • 事件修飾符:v-on補充-修飾符
    • 事件的后面加上 .修飾符 可以對事件的觸發進行更好的控制,
    • .enter限制的按鍵為回車鍵,事件修飾符還有很多,參照官網即可,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-on補充</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <!--事件方法傳參-->
    <button @click="doSomething('老王',hobby[0].name)">點擊彈窗</button>
    <!--事件修飾符:鍵盤按下enter鍵觸發doSomething事件-->
    <input type="text" @keydown.enter="doSomething('小盧',hobby[2].name)"/>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            hobby: [{name: '睡覺'}, {name: '打游戲'},
                {name: '看美女'}, {name: '旅游'},
                {name: '聽音樂'}, {name: '看電影'}]
        },
        methods: {
            doSomething: function (p1, p2) {
                alert("我叫" + p1 + ",喜歡" + p2);
            }
        }
    })
</script>
</body>
</html>

v-model

作用:

  • 獲取和設定表單元素的值(雙向資料系結),
  • 只能獲取和設定表單元素的值,實作data表單元素資料的雙向系結,不能系結非表單的元素,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model指令</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <input type="text" v-model="msg">
    <br>
    <br>
    <button @click="setMsg">修改message</button>
    <br>
    <h3>{{msg}}</h3>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            msg: 'v-model指令'
        },
        methods: {
            getMsg: function () {
                alert(this.msg);
            },
            setMsg: function () {
                this.msg = "老王666";
            }
        }
    })
</script>
</body>
</html>

3、Vue網路應用

3.1 什么是Axios

Axios 是一個基于 Promise 的 HTTP(網路請求) 庫,簡單講就是可以發送get、post請求等,功能較單一,

Axios同時也是一個JS庫,通過Promise實作XHR封裝,其中Promise是控制手段,XHR是實際發送Http請求的客戶端,

就像$.ajax是通過callback+XHR實作一樣,你也可以造個輪子叫XXX的,都是AJAX技術的一種具體實作,

簡單來說: AJAX技術是實作網頁的區域資料重繪,你可以通過XHR、Fetch、WebSocket等API實作

axios的GitHub地址

3.2 Axios基本使用

用法:

  • axios必須先匯入才可以使用,
  • 使用get或post方法即可發送對應的請求,
  • then方法中的回呼函式會在請求成功或失敗時觸發,
    • 第一個回呼函式在成功時觸發,
    • 第二個回呼函式在失敗時觸發,
  • 通過回呼函式的形參可以獲取回應內容或錯誤資訊,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>axios基本使用</title>
</head>
<body>
<input type="button" value="axios:get請求" class="get">
<input type="button" value="axios:post請求" class="post">
<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/list666?num=6")
        axios.get("https://autumnfish.cn/api/joke/list?num=6")
            .then(
                /*成功*/
                function (success) {
                    console.log(success);
                },
                /*失敗*/
                function (error) {
                    console.log(error);
                }
            )
    };
    /*
         介面2:用戶注冊
         請求地址:https://autumnfish.cn/api/user/reg
         請求方法:post
         請求引數:username(用戶名,字串)
         回應內容:注冊成功或失敗
     */
    document.querySelector(".post").onclick = function () {
        // axios.post("https://autumnfish.cn/api/user/reg333", {username: "axios基本使用"})
        axios.post("https://autumnfish.cn/api/user/reg", {username: "axios基本使用"})
            .then(
                /*成功*/
                function (success) {
                    console.log(success);
                },
                /*失敗*/
                function (error) {
                    console.log(error);
                }
            )
    }
</script>
</body>
</html>

3.3 Vue整合Axios

隨機獲取一條笑話,并通過Vue渲染到頁面上,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue整合axios</title>
</head>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <button @click="getJoke">獲取一條笑話</button>
    <p>{{msg}}</p>
</div>
<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 app = new Vue({
        el: '#app',
        data: {
            msg: '一條笑話'
        },
        methods: {
            getJoke: function () {
                var that = this;
                /*把this這個參考傳遞給that,因為在axios成功和失敗的回呼函式無法訪問this,
                this實際上指向的就是當前Vue的實體,拿到this,然后才能把回應資料渲染到頁面上*/
                axios.get("https://autumnfish.cn/api/joke")
                    .then(
                        /*請求成功的回呼*/
                        function (success) {
                            that.msg = success.data;
                        },
                        /*請求失敗的回呼*/
                        function (error) {
                            that.msg = "請求發生錯誤,請重新請求!";
                        }
                    )
            }
        }
    })
</script>
</body>
</html>

總結

  • axios回呼函式中的this已經改變,無法訪問到data中的資料,
  • 把this保存到其他變數中(參考傳遞),回呼函式中直接使用保存的this即可,
  • this可以通過 . 呼叫其他方法和data中的資料,
  • 網路應用和本地應用最大的區別就是改變了資料來源,

4、案例

4.1 計數器

需求:

  • 點擊加號數字加一,但不能超過10;
  • 點擊減號數字減一,但不能小于0;
  • 否則給出提示,

實作思路:

  • 使用Vue指令為按鈕系結點擊事件
  • data中定義要顯示的數字,并賦初值,使用 {{}} 在頁面上顯示數字
  • 當事件觸發時,改變頁面上的數字,也就是data中的數字值,在methods中定義兩個方法,進行處理,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>計數器</title>
</head>
<style>
    .bon {
        margin-left: 8px;
    }
</style>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <button class="bon" @click="add">+</button>
    <span>{{num}}</span>
    <button class="bon" @click="sub">-</button>
</div>

<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 1
        },
        methods: {
            add: function () {
                console.log("add...");
                console.log(this.num);
                if (this.num < 10) {
                    this.num++;
                } else {
                    alert("不能超過10");
                }
            },
            sub: function () {
                console.log(this.num);
                console.log("sub...");
                if (this.num > 0) {
                    this.num--;
                } else {
                    alert("不能小于0");
                }
            }
        }
    })
</script>
</body>
</html>

4.2 圖片切換

需求:

  • 點擊上一張顯示上一張圖片,點擊下一張顯示下一張圖片,
  • 當前如果是第一張圖片,則不顯示上一張的按鈕,反之則顯示,
  • 當前如果是最后一張圖片,則不顯示下一張的按鈕,反之則顯示,

實作思路:

  • 使用Vue指令v-on:click@click為按鈕系結點擊事件,
  • data中定義要顯示的圖片陣列(images),以及圖片陣列的index,并賦初值,
  • methods中定義當點擊上一張和下一張的時執行方法,
  • 使用v-bind:bind 系結imgsrc屬性,圖片的路徑從圖片陣列(images)中動態獲取,
  • 使用v-showv-if配合索引來判斷和控制按鈕是否顯示和隱藏,

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圖片切換</title>
</head>
<style>
    .img_div {
        margin: 18px auto;
        width: 560px;
        height: 350px;
    }
    img {
        width: 560px;
        height: 350px;
    }
</style>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
    <div class="img_div">
        <!-- 拼接圖片路徑 -->
        <img :src="'images/'+images[index]" alt="">
    </div>

    <div>
        <button v-show="index>0" @click="forward">上一張</button>
        <br/>
        <button v-show="index<images.length-1" @click="next">下一張</button>
    </div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            index: 0,
            /*圖片名稱陣列*/
            images: [
                "bg01.jpg", "bg02.jpg",
                "bg03.jpg", "bg04.jpg",
                "bg05.jpg", "bg06.jpg",
                "bg07.jpg", "bg08.jpg",
                "bg09.jpg", "bg10.jpg"
            ]
        },
        methods: {
            /*上一張*/
            forward: function () {
                this.index--;
            },
            /*下一張*/
            next: function () {
                this.index++;
            }
        }
    })
</script>
</body>
</html>

4.3 記事本

需求:

  • 實作資料的新增,
  • 單條洗掉和清空資料,
  • 串列展示,資料條數統計,
  • 當串列無資料時,底部的資料條數和批量洗掉隱藏,

實作思路:

  • 新增:用表單進行輸入,配合v-on,結合事件修飾符,v-model等實作,
  • 單條洗掉:v-on為元素系結單擊事件,單擊則洗掉對應資料,傳遞對應索引洗掉陣列元素即可,
  • 清空資料:清空串列數(陣列)據即可,
  • 串列展示:v-for實作,
  • 資料統計:取陣列的長度即可,
  • 元素的隱藏和顯示:v-showv-if

代碼如下:

index.css

html,
body {
    margin: 0;
    padding: 0;
}

body {
    background: #fff;
}

button {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font-size: 100%;
    vertical-align: baseline;
    font-family: inherit;
    font-weight: inherit;
    color: inherit;
    -webkit-appearance: none;
    appearance: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
    line-height: 1.4em;
    background: #f5f5f5;
    color: #4d4d4d;
    min-width: 230px;
    max-width: 550px;
    margin: 0 auto;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-weight: 300;
}

:focus {
    outline: 0;
}

.hidden {
    display: none;
}

#todoapp {
    background: #fff;
    margin: 180px 0 40px 0;
    position: relative;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}

#todoapp input::-webkit-input-placeholder {
    font-style: italic;
    font-weight: 300;
    color: #e6e6e6;
}

#todoapp input::-moz-placeholder {
    font-style: italic;
    font-weight: 300;
    color: #e6e6e6;
}

#todoapp input::input-placeholder {
    font-style: italic;
    font-weight: 300;
    color: gray;
}

#todoapp h1 {
    position: absolute;
    top: -160px;
    width: 100%;
    font-size: 60px;
    font-weight: 100;
    text-align: center;
    color: rgba(175, 47, 47, .8);
    -webkit-text-rendering: optimizeLegibility;
    -moz-text-rendering: optimizeLegibility;
    text-rendering: optimizeLegibility;
}

.new-todo,
.edit {
    position: relative;
    margin: 0;
    width: 100%;
    font-size: 24px;
    font-family: inherit;
    font-weight: inherit;
    line-height: 1.4em;
    border: 0;
    color: inherit;
    padding: 6px;
    border: 1px solid #999;
    box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.new-todo {
    padding: 16px;
    border: none;
    background: rgba(0, 0, 0, 0.003);
    box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}

.main {
    position: relative;
    z-index: 2;
    border-top: 1px solid #e6e6e6;
}

.toggle-all {
    width: 1px;
    height: 1px;
    border: none; /* Mobile Safari */
    opacity: 0;
    position: absolute;
    right: 100%;
    bottom: 100%;
}

.toggle-all + label {
    width: 60px;
    height: 34px;
    font-size: 0;
    position: absolute;
    top: -52px;
    left: -13px;
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
}

.toggle-all + label:before {
    content: "?";
    font-size: 22px;
    color: #e6e6e6;
    padding: 10px 27px 10px 27px;
}

.toggle-all:checked + label:before {
    color: #737373;
}

.todo-list {
    margin: 0;
    padding: 0;
    list-style: none;
    max-height: 420px;
    overflow: auto;
}

.todo-list li {
    position: relative;
    font-size: 24px;
    border-bottom: 1px solid #ededed;
    height: 60px;
    box-sizing: border-box;
}

.todo-list li:last-child {
    border-bottom: none;
}

.todo-list .view .index {
    position: absolute;
    color: gray;
    left: 10px;
    top: 20px;
    font-size: 16px;
}

.todo-list li .toggle {
    text-align: center;
    width: 40px;
    /* auto, since non-WebKit browsers doesn't support input styling */
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto 0;
    border: none; /* Mobile Safari */
    -webkit-appearance: none;
    appearance: none;
}

.todo-list li .toggle {
    opacity: 0;
}

.todo-list li .toggle + label {
    /*
          Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
          IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
      */
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center left;
}

.todo-list li .toggle:checked + label {
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E");
}

.todo-list li label {
    word-break: break-all;
    padding: 15px 15px 15px 60px;
    display: block;
    line-height: 1.2;
    transition: color 0.4s;
}

.todo-list li.completed label {
    color: #d9d9d9;
    text-decoration: line-through;
}

.todo-list li .destroy {
    display: none;
    position: absolute;
    top: 0;
    right: 10px;
    bottom: 0;
    width: 40px;
    height: 40px;
    margin: auto 0;
    font-size: 30px;
    color: #cc9a9a;
    margin-bottom: 11px;
    transition: color 0.2s ease-out;
}

.todo-list li .destroy:hover {
    color: #af5b5e;
}

.todo-list li .destroy:after {
    content: "×";
}

.todo-list li:hover .destroy {
    display: block;
}

.todo-list li .edit {
    display: none;
}

.todo-list li.editing:last-child {
    margin-bottom: -1px;
}

.footer {
    color: #777;
    padding: 10px 15px;
    height: 20px;
    text-align: center;
    border-top: 1px solid #e6e6e6;
}

.footer:before {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 50px;
    overflow: hidden;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6,
    0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6,
    0 17px 2px -6px rgba(0, 0, 0, 0.2);
}

.todo-count {
    float: left;
    text-align: left;
}

.todo-count strong {
    font-weight: 300;
}

.filters {
    margin: 0;
    padding: 0;
    list-style: none;
    position: absolute;
    right: 0;
    left: 0;
}

.filters li {
    display: inline;
}

.filters li a {
    color: inherit;
    margin: 3px;
    padding: 3px 7px;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: 3px;
}

.filters li a:hover {
    border-color: rgba(175, 47, 47, 0.1);
}

.filters li a.selected {
    border-color: rgba(175, 47, 47, 0.2);
}

.clear-completed,
html .clear-completed:active {
    float: right;
    position: relative;
    line-height: 20px;
    text-decoration: none;
    cursor: pointer;
}

.clear-completed:hover {
    text-decoration: underline;
}

.info {
    margin: 50px auto 0;
    color: #bfbfbf;
    font-size: 15px;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
    text-align: center;
}

.info p {
    line-height: 1;
}

.info a {
    color: inherit;
    text-decoration: none;
    font-weight: 400;
}

.info a:hover {
    text-decoration: underline;
}

/*
	Hack to remove background from Mobile Safari.
	Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio: 0) {
    .toggle-all,
    .todo-list li .toggle {
        background: none;
    }

    .todo-list li .toggle {
        height: 40px;
    }
}

@media (max-width: 430px) {
    .footer {
        height: 50px;
    }

    .filters {
        bottom: 10px;
    }
}

記事本.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>記事本</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css"/>
</head>
<body>
<!-- 主體區域 -->
<section id="todoapp">
    <!-- 輸入框 -->
    <header class="header">
        <h1>記事本</h1>
        <!--v-model:表單資料和data中的inputValue進行雙向系結
        @keyup.enter(v-on:keyup.enter):鍵盤上的enter鍵抬起時,觸發(執行)add方法-->
        <input autofocus="autofocus" autocomplete="off"
               placeholder="請輸入任務" class="new-todo"
               v-model="inputValue" @keyup.enter="add"/>
    </header>
    <!-- 串列區域 -->
    <section class="main">
        <ul class="todo-list">
            <li class="todo" v-for="(item,index) in list" :key="index">
                <div class="view">
                    <span class="index">{{index+1}}</span>
                    <label>{{item}}</label>
                    <!--從index位置開始移除,移除1個元素-->
                    <button class="destroy" @click="remove(index,1)"></button>
                </div>
            </li>
        </ul>
    </section>
    <!-- 統計和清空 -->
    <footer class="footer">
        <span class="todo-count" v-show="list.length!=0">
            共有
            <strong>{{list.length}}</strong></span>
        <button class="clear-completed" @click="clear" v-if="list.length!=0">
            清空
        </button>
    </footer>
</section>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: "#todoapp",
        data: {
            /*資料串列*/
            list: ["吃飯", "睡覺", "打豆豆"],
            /*文本框輸入的值*/
            inputValue: ""
        },
        methods: {
            /*新增*/
            add: function () {
                if (this.inputValue == "") {
                    alert("輸入不能為空!");
                    return;
                }
                this.list.push(this.inputValue);
                this.inputValue = "";
            },
            /*移除單個元素*/
            remove: function (index, count) {
                /*從index位置開始移除,移除count個元素*/
                this.list.splice(index, count);
            },
            /*清空陣列*/
            clear: function () {
                this.list = [];
            }
        }
    })
</script>
</body>
</html>

4.4 天氣查詢

需求:

  • 根據對應的城市,查詢對應的天氣,并展示到頁面上,

實作思路:

  • v-model實作表單資料和data的系結,從而獲取輸入的城市名,
  • v-on結合事件修飾符實作回車查詢,
  • 利用axios請求天氣介面,獲取資料,
  • v-for實作資料的渲染,

代碼如下:

main.js

/*
  請求地址:http://wthrcdn.etouch.cn/weather_mini
  請求方法:get
  請求引數:city(城市名)
  回應內容:天氣資訊

  1. 點擊回車
  2. 查詢資料
  3. 渲染資料
*/
new Vue({
    el: "#app",
    data: {
        city: "",
        weatherList: []
    },
    methods: {
        getWeather: function () {
            if (typeof this.city == "undefined" || this.city == null || this.city == "") {
                alert("城市不能為空!");
                return;
            }
            let that = this;
            axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city)
                .then(
                    /*請求成功的函式回呼*/
                    function (success) {
                        console.log("請求成功!");
                        console.log(success.data.data);
                        that.weatherList = success.data.data.forecast;
                    }
                    /*,function (error) {
                        /!*請求失敗的函式回呼*!/
                        alert("請求發生錯誤,請重新請求!");
                    }*/
                ).catch(function (error) {
                /*請求失敗的函式回呼*/
                alert("請求發生錯誤,請重新請求!");
            })
        },
        queryWeather: function (city) {
            this.city = city;
            this.getWeather();
        }
    }
});

index.css

body {
    font-family: 'Microsoft YaHei';
}

.wrap {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    /* background: radial-gradient(#f3fbfe, #e4f5fd, #8fd5f4); */
    /* background:#8fd5f4; */
    /* background: linear-gradient(#6bc6ee, #fff); */
    background: #fff;

}

.search_form {
    width: 640px;
    margin: 100px auto 0;
}

.logo img {
    display: block;
    margin: 0 auto;
}

.form_group {
    width: 640px;
    height: 40px;
    margin-top: 45px;
}

.input_txt {
    width: 538px;
    height: 38px;
    padding: 0px;
    float: left;
    border: 1px solid #41a1cb;
    outline: none;
    text-indent: 10px;
}

.input_sub {
    width: 100px;
    height: 40px;
    border: 0px;
    float: left;
    background-color: #41a1cb;
    color: #fff;
    font-size: 16px;
    outline: none;
    cursor: pointer;
    position: relative;
}

.input_sub.loading::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: url('../img/loading.gif');
}

.hotkey {
    margin: 8px 0 0 2px;
}

.hotkey a {
    font-size: 14px;
    color: #666;
    padding-right: 15px;
}

.weather_list {
    height: 200px;
    text-align: center;
    margin-top: 50px;
    font-size: 0px;
}

.weather_list li {
    display: inline-block;
    width: 140px;
    height: 200px;
    padding: 0 10px;
    overflow: hidden;
    position: relative;
    background: url('../img/line.png') right center no-repeat;
    background-size: 1px 130px;
}

.weather_list li:last-child {
    background: none;
}

/* .weather_list .col02{
    background-color: rgba(65, 165, 158, 0.8);
}
.weather_list .col03{
    background-color: rgba(94, 194, 237, 0.8);
}
.weather_list .col04{
    background-color: rgba(69, 137, 176, 0.8);
}
.weather_list .col05{
    background-color: rgba(118, 113, 223, 0.8);
} */

.info_date {
    width: 100%;
    height: 40px;
    line-height: 40px;
    color: #999;
    font-size: 14px;
    left: 0px;
    bottom: 0px;
    margin-top: 15px;
}

.info_date b {
    float: left;
    margin-left: 15px;
}

.info_type span {
    color: #fda252;
    font-size: 30px;
    line-height: 80px;
}

.info_temp {
    font-size: 14px;
    color: #fda252;
}

.info_temp b {
    font-size: 13px;
}

.tem .iconfont {
    font-size: 50px;
}

天氣查詢.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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" @keydown.enter="getWeather"/>
            <!--點擊搜索按鈕查詢天氣-->
            <button class="input_sub" @click="getWeather">
                搜 索
            </button>
        </div>
        <!--點擊查詢城市天氣-->
        <div class="hotkey">
            <span>熱門城市:</span>
            <a href="javascript:;" @click="queryWeather('北京')">北京</a>
            <a href="javascript:;" @click="queryWeather('上海')">上海</a>
            <a href="javascript:;" @click="queryWeather('廣州')">廣州</a>
            <a href="javascript:;" @click="queryWeather('深圳')">深圳</a>
        </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>
</html>

4.5 音樂播放器

需求:

  • 歌曲的搜索,播放/暫停,
  • 歌曲封面隨播放歌曲的不同而不同,
  • 歌曲的評論,
  • 歌曲封面的碟片隨歌曲播放而轉動(影片),
  • MV的播放/暫停,以及顯示,點擊MV空白處關閉MV,
  • 自動播放下一首歌,若當前歌曲是最后一首,則從頭開始播放(串列回圈),

實作思路:

  • 歌曲搜索
    • 按下回車進行查詢:v-on,.enter
    • 查詢資料:axios呼叫音樂介面,v-model將輸入內容和data進行系結,
    • 渲染資料:v-for回圈遍歷音樂資料即可,
  • 歌曲播放
    • 點擊播放:v-on(@),系結點擊事件,
    • 歌曲地址獲取:axios請求歌曲URL獲取介面即可,
    • 歌曲地址設定:v-bind:屬性名=屬性值(:屬性名=屬性值),設定src屬性的值即可,
  • 歌曲封面
    • 獲取封面圖片:axios請求對應介面獲取即可,
    • 設定封面圖片:v-bind:屬性名=屬性值(:屬性名=屬性值),設定圖片的src屬性的值即可,
  • 播放影片
    • 監聽音樂的播放和暫停:首先,audio標簽的play事件會在音頻播放的時候觸發,
    • audio標簽的pause事件會在音頻暫停的時候觸發,
    • v-on為音樂的播放(play)和暫停(pause)系結監聽事件,
    • 同時設定一個標志,播放和暫停時,改變標志的狀態即可,
    • 配合v-bind,播放音樂時為盒子(div)加上類樣式修飾即可播放影片,
    • 即:類樣式是否生效,取決于我們所設定的標志,值為true則類樣式生效,
  • 歌曲MV相關功能
    • 歌曲MV圖示的顯示和隱藏:根據歌曲是否有MV,結合v-ifv-show實作即可,
    • MV的獲取:axios請求MV獲取介面即可,
    • 遮罩層顯示和隱藏:v-showv-if,配合v-on實作,
    • MV地址切換:v-bind設定對應標簽的src屬性值即可,
  • 自動播放下一首(串列回圈)
    • 播放當前歌曲時,把當前歌曲的索引記錄起來,
    • audio標簽添加播放結束的監聽,若當前歌曲播放結束,則拿到剛剛所記錄的歌曲索引,
    • 判斷歌曲索引是否是最后一個,若不是,則索引值加一,呼叫播放歌曲的方法,進行播放下一首,
    • 如果當前歌曲是最后一首,則把索引置為 0,呼叫播放歌曲的方法,進行歌曲的播放,
    • 該功能使用原生JavaScript實作,

代碼如下:

index.css

body,
ul,
dl,
dd {
    margin: 0px;
    padding: 0px;
}

.wrap {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: url("../images/bg.jpg") no-repeat;
    background-size: 100% 100%;
}

.play_wrap {
    width: 800px;
    height: 544px;
    position: fixed;
    left: 50%;
    top: 50%;
    margin-left: -400px;
    margin-top: -272px;
    /* background-color: #f9f9f9; */
}

.search_bar {
    height: 60px;
    background-color: #1eacda;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
    z-index: 11;
}

.search_bar img {
    margin-left: 23px;
}

.search_bar input {
    margin-right: 23px;
    width: 296px;
    height: 34px;
    border-radius: 17px;
    border: 0px;
    background: url("../images/zoom.png") 265px center no-repeat rgba(255, 255, 255, 0.45);
    text-indent: 15px;
    outline: none;
}

.center_con {
    height: 435px;
    background-color: rgba(255, 255, 255, 0.5);
    display: flex;
    position: relative;
}

.song_wrapper {
    width: 200px;
    height: 435px;
    box-sizing: border-box;
    padding: 10px;
    list-style: none;
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: 1;
}

.song_stretch {
    width: 600px;
}

.song_list {
    width: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    height: 100%;
}

.song_list::-webkit-scrollbar {
    display: none;
}

.song_list li {
    font-size: 12px;
    color: #333;
    height: 40px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    width: 580px;
    padding-left: 10px;
}

.song_list li:nth-child(odd) {
    background-color: rgba(240, 240, 240, 0.3);
}

.song_list li a {
    display: block;
    width: 17px;
    height: 17px;
    background-image: url("../images/play.png");
    background-size: 100%;
    margin-right: 5px;
    box-sizing: border-box;
}

.song_list li b {
    font-weight: normal;
    width: 122px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.song_stretch .song_list li b {
    width: 200px;
}

.song_stretch .song_list li em {
    width: 150px;
}

.song_list li span {
    width: 23px;
    height: 17px;
    margin-right: 50px;
}

.song_list li span i {
    display: block;
    width: 100%;
    height: 100%;
    cursor: pointer;
    background: url("../images/table.png") left -48px no-repeat;
}

.song_list li em,
.song_list li i {
    font-style: normal;
    width: 100px;
}

.player_con {
    width: 400px;
    height: 435px;
    position: absolute;
    left: 200px;
    top: 0px;
}

.player_con2 {
    width: 400px;
    height: 435px;
    position: absolute;
    left: 200px;
    top: 0px;
}

.player_con2 video {
    position: absolute;
    left: 20px;
    top: 30px;
    width: 355px;
    height: 265px;
}

.disc {
    position: absolute;
    left: 73px;
    top: 60px;
    z-index: 9;
}

.cover {
    position: absolute;
    left: 125px;
    top: 112px;
    width: 150px;
    height: 150px;
    border-radius: 75px;
    z-index: 8;
}

.comment_wrapper {
    width: 180px;
    height: 435px;
    list-style: none;
    position: absolute;
    left: 600px;
    top: 0px;
    padding: 25px 10px;
}

.comment_wrapper .title {
    position: absolute;
    top: 0;
    margin-top: 10px;
}

.comment_wrapper .comment_list {
    overflow: auto;
    height: 410px;
}

.comment_wrapper .comment_list::-webkit-scrollbar {
    display: none;
}

.comment_wrapper dl {
    padding-top: 10px;
    padding-left: 55px;
    position: relative;
    margin-bottom: 20px;
}

.comment_wrapper dt {
    position: absolute;
    left: 4px;
    top: 10px;
}

.comment_wrapper dt img {
    width: 40px;
    height: 40px;
    border-radius: 20px;
}

.comment_wrapper dd {
    font-size: 12px;
}

.comment_wrapper .name {
    font-weight: bold;
    color: #333;
    padding-top: 5px;
}

.comment_wrapper .detail {
    color: #666;
    margin-top: 5px;
    line-height: 18px;
}

.audio_con {
    height: 50px;
    background-color: #f1f3f4;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
}

.myaudio {
    width: 800px;
    height: 40px;
    margin-top: 5px;
    outline: none;
    background-color: #f1f3f4;
}

/* 旋轉的影片 */
@keyframes Rotate {
    from {
        transform: rotateZ(0);
    }
    to {
        transform: rotateZ(360deg);
    }
}

/* 旋轉的類名 */
.autoRotate {
    animation-name: Rotate;
    animation-iteration-count: infinite;
    animation-play-state: paused;
    animation-timing-function: linear;
    animation-duration: 5s;
}

/* 是否正在播放 */
.player_con.playing .disc,
.player_con.playing .cover {
    animation-play-state: running;
}

.play_bar {
    position: absolute;
    left: 200px;
    top: -10px;
    z-index: 10;
    transform: rotate(-25deg);
    transform-origin: 12px 12px;
    transition: 1s;
}

/* 播放桿 轉回去 */
.player_con.playing .play_bar {
    transform: rotate(0);
}

/* 搜索歷史串列 */
.search_history {
    position: absolute;
    width: 296px;
    overflow: hidden;
    background-color: rgba(255, 255, 255, 0.3);
    list-style: none;
    right: 23px;
    top: 50px;
    box-sizing: border-box;
    padding: 10px 20px;
    border-radius: 17px;
}

.search_history li {
    line-height: 24px;
    font-size: 12px;
    cursor: pointer;
}

.switch_btn {
    position: absolute;
    right: 0;
    top: 0;
    cursor: pointer;
}

.right_line {
    position: absolute;
    left: 0;
    top: 0;
}

.video_con video {
    position: fixed;
    width: 800px;
    height: 546px;
    left: 50%;
    top: 50%;
    margin-top: -273px;
    transform: translateX(-50%);
    z-index: 990;
}

.video_con .mask {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 980;
    background-color: rgba(0, 0, 0, 0.8);
}

.video_con .shutoff {
    position: fixed;
    width: 40px;
    height: 40px;
    background: url("../images/shutoff.png") no-repeat;
    left: 50%;
    margin-left: 400px;
    margin-top: -273px;
    top: 50%;
    z-index: 995;
}

main.js

/*
  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的地址
*/

/**
 * 判斷物件是否為空
 * @param obj 要判空的物件
 * @returns {boolean} 為慷訓傳true,不為慷訓傳false
 */
function isEmpty(obj) {
    if (typeof obj == "undefined" || obj == null || obj == "") {
        return true;
    } else {
        return false;
    }
}

var app = new Vue({
    el: "#player",
    data: {
        /*要查詢的關鍵字*/
        queryKey: "",
        /*歌曲資料串列*/
        musicList: [],
        /*歌曲url*/
        musicUrl: "",
        /*當前播放歌曲的索引*/
        currentIndex: 0,
        /*歌曲封面圖片url*/
        musicPicUrl: "",
        /*歌曲熱門評論*/
        hotCommentList: [],
        /*是否播放影片,false為不播放*/
        isPlaying: false,
        /*歌曲MV路徑*/
        songMvUrl: "",
        /*MV遮罩層的顯示狀態,false為不顯示*/
        isShow: false,
    },
    methods: {
        /*搜索歌曲*/
        searchMusic: function () {
            if (isEmpty(this.queryKey)) {
                alert("搜索關鍵字不能為空!");
                return;
            }
            let that = this;
            axios.get("https://autumnfish.cn/search?keywords=" + this.queryKey)
                .then(
                    /*請求成功的回呼*/
                    function (success) {
                        console.log(success.data.result.songs);
                        that.musicList = success.data.result.songs;
                    }
                    /*請求失敗的回呼*/
                ).catch(function (error) {
                alert("請求發生錯誤,請重新請求!");
                return;
            })
        },
        /*播放音樂*/
        playMusic: function (musicId, currentIndex) {
            /*記錄當前播放歌曲索引*/
            this.currentIndex = currentIndex;
            let that = this;
            /*歌曲url獲取*/
            axios.get("https://autumnfish.cn/song/url?id=" + musicId)
                .then(
                    /*請求成功的回呼*/
                    function (success) {
                        // console.log(success.data.data[0].url);
                        that.musicUrl = success.data.data[0].url;
                    }
                    /*請求失敗的回呼*/
                ).catch(function (error) {
                alert("請求發生錯誤,請重新請求!");
                return;
            });

            /*歌曲詳情獲取(包含歌曲圖片等資訊)*/
            axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
                .then(
                    /*請求成功的回呼*/
                    function (success) {
                        that.musicPicUrl = success.data.songs[0].al.picUrl;
                    }
                    /*請求失敗的回呼*/
                ).catch(function (error) {
                alert("請求發生錯誤,請重新請求!");
                return;
            });
            /*獲取歌曲熱門評論*/
            axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
                .then(
                    /*請求成功的回呼*/
                    function (success) {
                        // console.log(success);
                        // console.log(success.data.hotComments);
                        that.hotCommentList = success.data.hotComments;
                    }
                    /*請求失敗的回呼*/
                ).catch(function (error) {
                alert("請求發生錯誤,請重新請求!");
                return;
            });
        },

        /*影片播放*/
        animationPlay: function () {
            // console.log("播放...");
            this.isPlaying = true;
        },
        /*影片暫停*/
        animationPause: function () {
            // console.log("暫停...");
            this.isPlaying = false;
        },
        /*獲取歌曲的MV*/
        playSongMV: function (mvId) {
            // alert(mvId);
            let that = this;
            axios.get("https://autumnfish.cn/mv/url?id=" + mvId)
                .then(
                    /*請求成功的回呼*/
                    function (success) {
                        // console.log(success);
                        that.songMvUrl = success.data.data.url;
                        /*顯示MV遮罩層*/
                        that.isShow = true;
                        // console.log("呼叫成功,url:" + that.songMvUrl)
                    },
                    /*請求失敗的回呼*/
                    function (error) {
                        alert("請求發生錯誤,請重新請求!");
                        return;
                    }
                )
        },
        /*隱藏MV遮罩層,并停止MV*/
        hideMv: function () {
            if (confirm("你確定要關閉當前播放的MV視頻嗎?")) {
                this.isShow = false;
                this.songMvUrl = "";
            } else {
                return;
            }
        }
    }
});

/*自動播放下一首歌曲,原生js實作*/
let audio = document.getElementById("audioPlay");
audio.loop = false;
/*為‘audio’標簽添加播放結束事件*/
audio.addEventListener('ended', function () {
    // alert("歌曲播放結束!");
    // console.log(app.musicList);
    let list = app.musicList;
    let index = app.currentIndex;
    if (index < list.length - 1) {
        /*如果不是最后一首*/
        let nextMusic = list[index + 1];
        app.playMusic(nextMusic.id, index + 1);
    } else {
        /*如果是最后一首*/
        app.playMusic(list[0].id, 0);
    }
}, false);

音樂播放器.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音樂播放器</title>
    <!-- 自定義css -->
    <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=""/>
            <!-- 搜索歌曲 -->
            <!--v-model:對表單輸入框進行系結
            @keydown.enter(v-bind:keydown.enter):按下回車鍵搜索-->
            <input type="text" autocomplete="off" placeholder="輸入歌名或歌手"
                   v-model="queryKey" @keydown.enter="searchMusic"/>
        </div>
        <div class="center_con">
            <!-- 搜索歌曲串列 -->
            <div class='song_wrapper'>
                <ul class="song_list">
                    <li v-for="(song,index) in musicList" :key="index">
                        <a href="javascript:;" @click="playMusic(song.id,index)"></a>
                        <b>{{song.name}}</b>
                        <!--當歌曲的mvid!=0的時候表示有MV,則顯示MV圖示,
                        因為圖示不需要頻繁的顯示和隱藏,所以用‘v-if’指令-->
                        <span><i v-if="song.mvid!=0" @click="playSongMV(song.mvid)"></i></span>
                    </li>
                </ul>
                <img src="images/line.png" class="switch_btn" alt="">
            </div>
            <!-- 歌曲資訊容器 -->
            <!--v-bind系結屬性class,‘playing’這個類樣式是否生效,影片是否播放取決于‘isPlaying’的值-->
            <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 class="cover autoRotate" :src="musicPicUrl"/>
            </div>
            <!-- 評論容器 -->
            <div class="comment_wrapper">
                <h5 class='title'>熱門留言</h5>
                <div class='comment_list'>
                    <dl v-for="(comment,index) in hotCommentList" :key="index">
                        <dt><img :src="comment.user.avatarUrl" alt=""></dt>
                        <dd class="name">{{comment.user.nickname}}</dd>
                        <dd class="detail">{{comment.content}}</dd>
                    </dl>
                </div>
                <img src="images/line.png" class="right_line">
            </div>
        </div>
        <div class="audio_con">
            <!--播放歌曲實際上就是改變‘audio’的src屬性值-->
            <!--當點擊播放(@play="animationPlay")和暫停(@pause="animationPause")時,觸發對應的方法改變影片播放的標志-->
            <audio ref='audio' controls autoplay class="myaudio" id="audioPlay"
                   :src="musicUrl" @play="animationPlay" @pause="animationPause">
            </audio>
        </div>
        <!--MV遮罩層的div,默認不顯示-->
        <!--設定MV遮罩層并設定MV地址-->
        <!--v-if是通過添加和移除dom元素來實作顯示隱藏,v-show是通過改變元素的display屬性值實作顯示隱藏,
        style="display: none;"和v-if不能同時使用-->
        <div class="video_con" style="display: none;" v-show="isShow">
            <video controls="controls" autoplay :src="songMvUrl"></video>
            <!--點擊MV外面隱藏(關閉)遮罩層和歌曲MV-->
            <div class="mask" @click="hideMv"></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>
<!-- 自定義js -->
<script src="./js/main.js"></script>
</body>
</html>

總結

  • 對于本地無法獲取的資料,基本上都會有對應的介面,

5、其他資料(福利)

網上一個大佬寫的Vue.js總結(圖片)

學習Vue.js的一個網站

如果想深入學習Vue.js,可以看看官方檔案:Vue.js官方檔案

也可以看看這個視頻教程:2021最新Vue迅速上手教程丨vue3.0入門到精通

上面這些是個人覺得比較好的教程資料,可以參考一下,沒有打廣告的意思,只是想給大家一個參考,不喜勿噴,謝謝,

最后希望大家看完都能有所識訓,本人學后端的,寫前端的東西難免有說錯的地方,文章如有說錯的地方,歡迎批評指正,

后面還會繼續寫博客的,如果這篇文章對你有所幫助,請高抬貴手,點個贊,謝謝,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/291056.html

標籤:其他

上一篇:JS中使用reduce函式配合css3影片實作超好看的文字效果

下一篇:通過javascript封裝一個getType函式能夠獲取所有不同的資料型別,例如Symbol,null,object等

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more