主頁 > 前端設計 > Vue2學習筆記

Vue2學習筆記

2022-01-17 20:04:26 前端設計

Vue

(一)Vue簡介

  • Vue是一個JavaScript框架,有其獨特的使用規則,按照其規則使用,可以事半功倍
  • 它可以大大簡化Dom操作
  • 具有回應式資料驅動
  • 官方檔案 官方檔案

一.Vue特點

  1. 采用組件化模式,提高代碼復用率、且讓代碼更好維護(組件.vue==HTML+CSS+JS)
  2. 宣告式編碼,讓編碼人員無需直接操作DOM,提高開發效率
  3. 使用虛擬DOM+優秀的Diff演算法,盡量復用DOM結點

(二)Vue核心基礎

一、Vue基礎

1.匯入(安裝)

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

2.el:掛載點

<div id="app">
  {{ message }}
</div>
//第一種寫法
var app = new Vue({
  el: '#app',  //el:掛載點
  data: {  // data:資料物件
    message: 'Hello Vue!'
  }
})

//第二種寫法
var app = new Vue({
  data: {  // data:資料物件
    message: 'Hello Vue!'
  }
})
app.$mount('#app');  //掛載

掛載點 :選擇HTML元素,Vue會管理該元素及其后代元素(不要掛載和標簽)

注意:掛載只能一一對應,不能一對多,也不能多對一

3.data:資料物件

可以嵌套物件,陣列等復雜資料,語法與JS語法一致

//data物件寫法
data:{
    massage:'hello!'
}

//data函式寫法
//注意!組件中必須用這種寫法
data(){
    return{
        massage:'hello!'
    }
}
//注意!凡是由Vue管理的函式只能定義為普通函式,不能是箭頭函式!!!

4.MVVM模型

  • M:模型(Model):對應data中的資料
  • V:視圖(View):DOM
  • VM:視圖模型(ViewModel):Vue實體物件
  • data中所有的屬性最終都會出現在VM上(資料代理)

5.Object.defineProperty()回顧

let test={
    name:'test'
}

let a=18;

//為物件添加屬性,第三個引數為配置項物件
Object.defineProperty(test,'age',{
    value:18,
    enumerable:true,  //控制屬性是否可以列舉,默認為false
    writable:true,  //控制屬性是否可以被修改,默認false
    configurable:true,  //控制屬性是否可以被洗掉,默認false

    //當有人讀取test的age屬性時,get函式(getter)會被呼叫,而且回傳值就是age的值
    get(){
        console.log('有人讀取了age屬性');
        return a;
    },

    //當有人修改test的age屬性時,set函式(setter)會被呼叫,而且會收到修改的具體值
    set(value){
        console.log('有人修改了age屬性,且值是'+value);
        a=value;
    }
})

6.資料代理(重點難點)

資料代理:通過一個物件代理另一個物件中屬性的操作(讀/寫)

  • 資料代理的好處:更加方便的操作data中的資料
  • 基表原理:
    • 通過Object.defineProperty()將data物件中的所有屬性添加到VM上
    • 為每一個添加到VM上的屬性定義一個getter和setter
    • 在getter和setter內部去操作(讀/寫)data中對應屬性

二、Vue指令

1.v-text

v-text : 設定標簽的文本值(textContent)

<div id="app">
    <h1 v-text="massage+'!!!!'"></h1>
    <h1 v-text="massage+inf"></h1>
    <h1> {{massage}}啊!{{inf}}</h1>
</div>
var app=new Vue({
    el:'#app',
    data:{
        massage:'你好',
        inf:'世界'
    }
})

2.v-html

v-html : 設定標簽的innerHTML

<div id="app">
    <h1 v-text="link"></h1>
    <h1 v-html="link"></h1>
</div>
var app=new Vue({
    el:'#app',
    data:{
        link:'<a href="https://www.baidu.com">百度</a>'
    }
})

注意:v-html存在安全性問題!!!

  • 在網站上動態渲染任何HTML是非常危險的,容易導致XSS攻擊
  • 一定要在可信的內容上使用v-html,一定不能用在用戶提交的內容上!

3.v-on

3.1 v-on : 為元素系結事件
//語法
<div id="app">
    <input type="button" value="點我一下" v-on:事件="事件回應函式名">
    <input type="button" value="點我一下" @事件="事件回應函式名">  <!--更簡單的寫法-->
</div>

//實體
<div id="app">
    <input type="button" value="點我一下" @click="fun">
</div>
var app=new Vue({
    el:'#app',
    methods:{  //事件回應函式寫這里
        fun:function(){
            alert('你好啊!');
        }
    }
})
3.2 v-on補充:傳遞自定義引數,事件修飾符
<div id="app">
    <input type="button" value="點我一下" @click="fun(name)">
    <!-- $event占位,用于傳遞事件物件 -->
    <input type="text" @keyup.enter="fun($event,'李四')"> <!-- Vue提供了鍵盤按鍵的便捷系結方式 @keyup.按鍵名="事件回應函式" -->
</div>
var app=new Vue({
    el:'#app',
    data:{
        name:'張三'
    },
    methods:{ 
        fun:function(event,name){
            console.log(event);
            alert('你好啊!'+name);
        }
    }
})

:更多詳細用法查看檔案!官方檔案

3.3 Vue中的事件修飾符
  1. prevent:阻止默認事件(常用)
  2. stop:阻止事件冒泡(常用)
  3. once:事件只觸發一次(常用)
  4. capture:使用事件的捕獲模式
  5. self:只有event.target是當前操作元素時才觸發事件
  6. passive:事件的默認行為立即執行,無需等待事件回呼執行完畢
.test5,.test2{
    width: 500px;
    height: 100px;
    padding: 20px;
    background-color: skyblue;
}
.test41{
    width: 500px;
    height: 100px;
    background-color: springgreen;
    padding: 20px;
}
.test42{
    width: 400px;
    height: 50px;
    background-color: skyblue;
}
.test6{
    width: 300px;
    height: 100px;
    overflow: auto;
}
.test61{
    width: 200px;
    height: 1000px;
    background-color: skyblue;
}
<div id="root">
    <!-- prevent:阻止默認事件(常用) -->
    <a href="https://www.baidu.com" @click.prevent='test1'>百度一下</a>
    <!-- stop:阻止事件冒泡(常用) -->
    <div class="test2" @click='test2'>
        <button @click.stop='test2'>test2</button>
    </div>
    <!-- once:事件只觸發一次(常用) -->
    <button @click.once='test3'>test3</button>
    <!-- capture:使用事件的捕獲模式 -->
    <div class="test41" @click.capture="test4('test41')">
        test41
        <div class="test42" @click="test4('test42')">
            test42
        </div>
    </div>
    <!-- self:只有event.target是當前操作元素時才觸發事件 -->
    <div class="test5" @click.self='test5'>
        <button @click='test5'>test5</button>
    </div>
    <!-- passive:事件的默認行為立即執行,無需等待事件回呼執行完畢 -->
    <div class="test6" @wheel.passive="test6">
        test6
        <div class="test61"></div>
    </div>
</div>
var vm=new Vue({
    el:'#root',
    data:{

    },
    methods:{
        test1(){
            alert('就不百度一下!');
        },
        test2(){
            alert('不會冒泡喲!');
        },
        test3(){
            alert('再點一次我就不會彈出來了!');
        },
        test4(i){
            alert(i+'捕獲到了點擊事件!');
        },
        test5(e){
            alert('你點的是'+e.target);
        },
        test6(){
            for(var i=0;i<10000000;i++){
                console.log('test6');
            }
        }
    }
})

:修飾符可以多個連著使用

3.4 鍵盤事件
  • Vue常用事件別名

    • enter:回車
    • delete:洗掉/退格
    • esc:退出
    • space:空格
    • tab:換行(特殊,必須配合keydown使用,因為tab默認事件是切換焦點)
    • up:上
    • down:下
    • left:左
    • right:右
  • Vue未提供別名的按鍵,可以使用按鍵原始的Key值去系結,但是注意如果Key值為兩個以上單詞,轉化為-連接命名(例如:CapsLock:caps-lock)

    //獲取鍵值,鍵碼
    //為某一元素系結按鍵事件(keydown,keyup都行)
    console.log(event.key,event.keyCode);
    
  • 系統修飾鍵(用法特殊):ctrl,alt,shift,meta(win鍵)

    • 配合keyup使用:按下修飾鍵同時,再按下其他鍵,隨后釋放其他鍵,事件才觸發,
    • 配合keydown使用:正常觸發事件
  • 可以使用kkeyCode去指定具體按鍵,但是不推薦!!!

    • 不同鍵盤同一鍵鍵碼可能不同
    • 瀏覽器逐漸不支持
  • Vue.config.keyCodes.自定義鍵名=鍵碼,可以自定義鍵名,不推薦!!!

:鍵指定可以連著寫實作Ctrl+y等事件系結

4.v-show

v-show : 根據運算式真偽,切換元素的顯示和隱藏(操作樣式:display)

<div id="app">
    <img src="" v-show="true"> <!-- 直接布林值 -->
    <img src="" v-show="isShow"> <!-- 變數 -->
    <img src="" v-show="age>=18"> <!-- 運算式 -->
</div>
var app=new Vue({
    el:'#app',
    data:{
        isShow:true,
        age:20
    }
})

5.v-if/v-else-if/v-else

v-if : 根據運算式真偽,切換元素顯示和隱藏(操作Dom元素,直接將Dom元素移除或添加)

  • 用起來和普通編程語言條件分支陳述句一樣
<div id="app">
    <img src="" v-if="true"> <!-- 直接布林值 -->
    <img src="" v-if="isShow"> <!-- 變數 -->
    <img src="" v-if="age>=18"> <!-- 運算式 -->
    
    <div v-if="n===1">a</div>
    <div v-else-if="n===2">b</div>
    <div v-else-if="n===3">c</div>
    <div v-else>d</div>
    
    <!-- 需求:條件相同,顯示不同內容 -->
    <div v-if="n===1">a</div>
    <div v-if="n===1">b</div>
    <div v-if="n===1">c</div>
    <!-- 解決方案一 會破環原HTML結構,進而影響樣式等生效,不推薦使用-->
    <div v-if="n===1">
        <div>a</div>
        <div>b</div>
        <div>c</div>
    </div>
    <!-- 解決方案二 -->
    <template v-if="n===1">
        <div>a</div>
        <div>b</div>
        <div>c</div>
    </template>
    <!-- template只能與v-if一起使用,不能和v-show一起使用 -->
</div>
var app=new Vue({
    el:'#app',
    data:{
        isShow:true,
        age:20,
        n:2
    }
})

6.v-bind

v-bind : 設定元素屬性(如:src,title,class等)

<div id="app">
    <img v-bind:src="imgsrc"> <!-- v-bind:屬性名="屬性值" -->
    <img :alt="ingalt+'!!!'"> <!-- 簡寫為 :屬性名="屬性值" -->
    <img v-bind:class="isActive?'active':''">
    <img v-bind:class="{active:isActive}">
</div>
var app=new Vue({
    el:'#app',
    data:{
        imgsrc:'./01.jpg',
        imgalt:'圖片1',
        isActive:false
    }
})
6.1 通過class系結樣式
<div id="root">
    <!-- 字串寫法,適用于:樣式的類名不確定,需要動態指定(只有一個樣式(類)) -->
    <div :class="test1" @click="change1">test1</div>
    <!-- 陣列寫法,適用于:樣式的個數不確定,名字不確定 -->
    <div class="basic" :class="test2" @click="change2">test2</div>
    <!-- 物件寫法,適用于:樣式個數確定,名字確定,但是用不用不確定 -->
    <div class="basic" :class="test3" @click="change3">test3</div>
</div>
.class1{
    width: 200px;
    height: 200px;
    background-color: skyblue;
}
.class2{
    width: 200px;
    height: 400px;
    background-color: skyblue;
}
.class3{
    width: 400px;
    height: 200px;
    background-color: skyblue;
}
.class4{
    width: 200px;
    height: 200px;
    background-color: slateblue;
}
.basic{
    width: 100px;
    height: 100px;
    background-color: skyblue;
}
.plus1{
    border: black solid 3px;
}
.plus2{
    border-radius: 10px;
}
.plus3{
    color: blue;
}
var vm=new Vue({
    el:'#root',
    data:{
        test1:'class1',
        test2:[],
        test3:{
            plus1:false,
            plus2:false,
            plus3:false,
        }
    },
    methods:{
        change1(){
            var classArr=['class1','class2','class3','class4'];
            var index=Math.floor(Math.random()*4);
            console.log(index);
            this.test1=classArr[index];
        },
        change2(){
            var classArr=['plus1','plus2','plus3'];
            if(this.test2.length<3){
                this.test2.push(classArr[this.test2.length]);
            }else{
                for(var i=0;i<3;++i){
                    this.test2.pop();
                }
            }
        },
        change3(){
            var a,b,c;
            a=Math.floor(Math.random()*2);
            b=Math.floor(Math.random()*2);
            c=Math.floor(Math.random()*2);
            if(a)this.test3.plus1=!this.test3.plus1;
            if(b)this.test3.plus2=!this.test3.plus2;
            if(c)this.test3.plus3=!this.test3.plus3;
        }
    }
})
6.2 通過style系結
<div id="root">
    <!-- 物件寫法 -->
    <div class="basic" :style="styleObj">test1</div>
    <!-- 陣列方法 -->
    <div class="basic" :style="styleArr">test2</div>
</div>
.basic{
    width: 100px;
    height: 100px;
    background-color: skyblue;
    border-radius: ;
}
var vm=new Vue({
    el:'#root',
    data:{
        styleObj:{
            fontSize:'30px',
            color:'red',
        },
        styleArr:[
            {
                fontSize:'30px',
                color:'red'
            },
            {marginTop:'10px'},
            {
                border:'black solid 2px',
                borderRadius:'10%'
            }
        ]
    },
})

7.v-for

7.1 v-for : 根據資料生成串列結構
  • 可以遍歷:陣列、物件、字串(不常用)、指定次數(不常用)
  • 用in或者of都行
<div id="root">
    <!-- 遍歷陣列 -->
    <h1>學生串列</h1>
    <ul>
        <li v-for="(item,index) in students" :key="index">
            {{item.id}}:{{item.name}}-{{item.age}}
        </li>
    </ul>

    <!-- 遍歷物件 -->
    <h1>學生資訊</h1>
    <ul>
        <li v-for="(value,key) of student" :key="key">
            {{key}}:{{value}}
        </li>
    </ul>

    <!-- 遍歷字串 -->
    <h1>hello</h1>
    <ul>
        <li v-for="(char,index) of str" :key="index">
            {{index}}:{{char}}
        </li>
    </ul>

    <!-- 遍歷指定次數 -->
    <h1>12345</h1>
    <ul>
        <li v-for="(v,index) in 5" :key="index">
            {{index}}:{{v}}
        </li>
    </ul>
</div>
 var vm=new Vue({
     el:'#root',
     data:{
         students:[
             {id:0,name:'張三',age:18},
             {id:1,name:'李四',age:20},
             {id:2,name:'王五',age:18},
             {id:3,name:'趙六',age:19},
         ],
         student:{
             id:0,
             name:'張三',
             age:18
         },
         str:'hello'
     },
 })
7.2 v-for中的key屬性(重點難點)

面試題:react、vue中key有什么作用?(key的原理是什么?)

要點:就是為了提高效率

  • 虛擬DOM中key的作用:key是虛擬DOM物件的標識,當資料發生變化時,Vue會根據新資料生成新的虛擬DOM,隨后Vue進行新的虛擬DOM舊的虛擬DOM的差異比較(diff演算法)
  • 比對規則:
    • 舊的虛擬DOM中找到了與新的虛擬DOM相同的key:
      • 若虛擬DOM中內容沒變,直接使用之前的真實DOM!(提高效率)
      • 如果虛擬DOM中內容變了,則生成新的真實DOM,隨后替換掉頁面中之前的真實DOM,
    • 舊虛擬DOM中未找到與新的虛擬DOM相同的key:
      • 創建新的真實DOM,隨后渲染到頁面中
  • v-for用索引值(index)作為key可能會引發的問題(不寫key,Vue就會默認這樣使用):
    • 如果對資料進行逆序添加、逆序洗掉等破環順序的操作:
      • 會產生沒有必要的真實DOM更新,效率低
    • 如果結構中還有輸入類DOM:
      • 會產生錯誤DOM更新,效率低,界面還會出錯(亂序)
  • 開發中如何選擇key
    • 最好使用每條資料的唯一標識作為key
    • 如果不存在對資料進行逆序添加、逆序洗掉等破環順序的操作,僅僅用于渲染展示,使用索引(index)也是沒有問題的

8.v-model

8.1 v-model : 獲取和設定表單元素的值(雙向資料系結)
<div id="app">
    <input type="text" v-model:value="massage"> <!-- 簡寫如下 -->
    <input type="text" v-model="massage">  <!-- 文本框內容與massage雙向系結(輸入值改變,massage值會相應改變) -->
    <h1>{{massage}}</h1>
</div>
var app=new Vue({
    el:'#app',
    data:{
        massage:'你好!'
    }
})
8.2 v-mdel補充
  • 如果是文本框,則v-model系結的是value值,用戶輸入的就是value

  • 如果是單選框,責v-model系結的是value值,必須要給標簽配置value

  • 如果是多選框,則:

    • 沒有配置value,那么系結的就是checked(true or false)
    • 配置了value
      • 如果v-modle的初始值是非陣列,那么系結的就是checked(true or false)
      • 如果v-modle的初始值是陣列,那么系結的就是value組成的陣列
  • v-model修飾符

    • number:輸入字串轉化為有效數字
    • lazy:失去焦點才收集更新資料
    • trim:去掉字串首尾的空格
  • 實體

    <div id="root">
        <form @submit.prevent="output">
            <!-- v-model.trim 會自動去掉字串前后空格 -->
            用戶名: <input type="text" v-model.trim="userinf.username"> <br><br>
            密碼: <input type="password" v-model="userinf.password" autocomplete="on"> <br><br>
            <!-- type="number" 可以限制用戶輸入只能是數字 -->
            <!-- v-model.number 可以自動將輸入的內容轉化為數值型別 -->
            年齡: <input type="number" v-model.number="userinf.age"> <br><br>
            性別:
            男<input type="radio" name="gender" value="" v-model="userinf.gender"><input type="radio" name="gender" value="" v-model="userinf.gender"> <br><br>
            班級:
            <select v-model="userinf.class">
                <option value="">請選擇班級</option>
                <option value="一班">一班</option>
                <option value="二班">二班</option>
                <option value="三班">三班</option>
            </select> <br><br>
            愛好:
            學習<input type="checkbox" value="學習" v-model="userinf.hobby">
            打游戲<input type="checkbox" value="打游戲" v-model="userinf.hobby">
            開車<input type="checkbox" value="開車" v-model="userinf.hobby"> <br><br>
            <!-- v-model.lazy 失去焦點才會收集更新資訊 -->
            其他資訊:<textarea v-model.lazy="userinf.other"></textarea> <br><br>
            <input type="checkbox" v-model="userinf.agree">是否同意<a href="#">用戶協議</a> <br><br>
            <button>提交</button>
        </form>
    </div>
    
    var vm = new Vue({
        el: '#root',
        data: {
            userinf:{
                username:'',
                password:'',
                age:'',
                class:'',
                hobby:[],
                other:'',
                agree:''
            }
        },
        methods: {
            output(){
                console.log(JSON.stringify(this.userinf));
            }
        },
    })
    

9.v-cloak

  • 沒有值
  • 是一個特殊的屬性,Vue實體創建完畢并接管容器后,會自動洗掉v-colak屬性
  • 使用css配合v-cloak可以解決網速慢時頁面展示出未被Vue決議的模板頁面的問題
<!DOCTYPE html>
<html lang="ch">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>
    <!-- 整個頁面核心結構 -->
    <div id="root">
        <h1 v-cloak>{{name}}</h1>
    </div>
</body>
<!-- 如果網路卡頓,Vue.js無法在打開頁面時立即加載 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el: '#root',
        data: {
           name:'Vue'
        },
    })
</script>
</html>

10.v-once

  • v-once所在結點在初次動態渲染后,就會被視為靜態內容
  • 以后資料改變不會引起v-once所在結點的更新,可以優化性能
<div id="root">
    <h1 v-once>初始n: {{n}}</h1>
    <h1 >n: {{n}}</h1>
    <button @click="n++">n+1</button>
</div>
var vm = new Vue({
    el: '#root',
    data: {
        n:1
    },
})

11.v-pre

  • Vue會跳過其所在結點的決議程序
  • 可以利用它跳過:沒有用指令,插值等結點,提高性能
<div id="root">
    <h1>歡迎訪問該系統!!!!!</h1>
    <h1 >n: {{n}}</h1>
    <button @click="n++">n+1</button>
</div>
var vm = new Vue({
    el: '#root',
    data: {
        n:1
    },
})

三、計算屬性(重點難點)

計算屬性:根據原有的屬性經過加工處理計算出來的屬性叫做計算屬性(computed)

  • 原理:底層借助了Object.defineproperty方法提供的getter和setter
  • get什么時候執行
    • 初次讀取計算屬性
    • 當計算屬性依賴的資料發生改變時會被再次呼叫
  • 優勢:與methods實作相比,內部有快取機制(可復用),效率更高
  • 注意:
    • 計算屬性最侄訓被處理為vm的一個屬性,直接讀取使用即可
    • 計算屬性如果需要被修改,則必須使用setter,setter中對應修改計算屬性的依賴資料即可
<div id="root">
    性:<input type="text" v-model="firstname"> <br><br>
    名:<input type="text" v-model="lastname"> <br><br>
    性名: <span>{{name}}</span>
</div>
var vm=new Vue({
    el:'#root',
    data:{
        firstname:'張',
        lastname:'三'
    },
    computed:{
        //這里得寫成一個物件,但是Vue會把它決議處理為vm中的屬性
        name:{
            //getter,setter中的this都已經被Vue預先處理為了vm,方便使用
            get(){
                return this.firstname+'-'+this.lastname;
            },
            set(value){
                var values=value.split('-');
                this.firstname=values[0];
                this.lastname=values[1];
            }
        }
        //當只需要讀取,不需要修改時,可以簡寫為
        // name(){
        //     return this.firstname+'-'+this.lastname;
        // }
    }
})

四、偵聽(監視)屬性

1.偵聽(監視)屬性

  • 當偵聽(監視)屬性變化時,handler自動呼叫,進行相關操作
  • 偵聽(監視)屬性必須存在,才能被偵聽(監視)
<div id="root">
    <h1>你真是個大{{description}}</h1>
    <button @click='change'>點我</button>
</div>
var vm=new Vue({
    el:'#root',
    data:{
        isCool:true
    },
    methods:{
        change(){
            this.isCool=!this.isCool;
        }
    },
    computed:{
        description(){
            return this.isCool? '帥哥':'聰明';
        }
    },
    watch:{
        isCool:{
            immediate:true,  //初始化時讓handler呼叫一次
            // 當被偵聽(監視)的值變化時,handler被呼叫
            handler(newvalue,oldvalue){
                console.log('isCool被改變了,從'+oldvalue+'改成了'+newvalue);
            }
        },
        //當偵聽(監視)時配置項只有handler時,可以簡寫為
        // isColl(){
        //     console.log('isCool被改變了,從'+oldvalue+'改成了'+newvalue);
        // }
    }
})

// 另一種寫法
// vm.$watch('isCool',{
//     immediate:true,  //初始化時讓handler呼叫一次
//     // 當被偵聽(監視)的值變化時,handler被呼叫
//     handler(newvalue,oldvalue){
//         console.log('isCool被改變了,從'+oldvalue+'改成了'+newvalue);
//     }
// })
//當偵聽(監視)時配置項只有handler時,可以簡寫為
// vm.$watch('isCool',function(){
//     console.log('isCool被改變了,從'+oldvalue+'改成了'+newvalue);
// })

2.深度偵聽(監視)

  • Vue中的watch默認不偵聽(監視)物件內部值的改變(一層)
  • 配置項deep:true可以偵聽(監視)物件內部屬性值的改變(多層)
  • Vue自身是可以偵聽(監視)物件內部值改變,但是Vue提供的watch默認不可以
  • 使用watch時根據實際使用需求,決定是否采用深度偵聽(監視)

3.計算屬性(computed)和偵聽(監視)屬性(watch)的區別

  • computed能完成的功能,watch都可以完成,
  • watch能完成的功能,computed不一定能成功,例如:watch可以進行異步操作
  • 兩個都行的用computed更簡單
  • 注意!!
    • 所被Vue管理的函式,最好寫成普通函式,這樣this的指向才是vm或組件實體物件
    • 所有不被Vue管理的函式(定時器回呼函式,ajax回呼函式,Promise的回呼函式等),最好寫成箭頭函式,這樣this的指向才是vm或組件實體物件

4.偵聽(監視)原理(重點難點)

偵聽(監視):包括Vue對于資料改變,動態更新頁面中用到該資料的DOM,以及watch中偵聽(監視)資料地秤實作(同樣的邏輯)

  • Vue會偵聽(監視)data中所有層級的資料

  • 如何偵聽(監視)物件中的資料?

    • 通過setter實作偵聽(監視),而且要是在創建Vue實體物件時就傳入的資料才會被Vue偵聽(監視)

    • 物件中后追加的屬性,Vue默認不偵聽(監視),進而也不會做出回應式處理

    • 如果想讓后追加的屬性也可以被Vue偵聽(監視),并回應式處理,需要使用:

      Vue.set()
      vm.$set()
      
  • 如何偵聽(監視)陣列中的資料?

    • 通過包裹陣列更新元素方法實作,本質上就是兩個處理

      • 通過原生對應的方法對陣列進行更新
      • 重新決議模板,渲染頁面
    • 在Vue中修改某陣列中某元素一定要用如下幾種方法:

      //這些方法用起來和原生JS中Array物件的這些方法一樣,但是實際上底層邏輯不一樣,Vue對這些方法做了如上述的包裹處理
      push()
      pop()
      shift()
      unshift()
      splice()
      sort()
      reverse()
      //Vue的set方法
      //注意!! 這兩個方法用起來一樣,但是都有局限,
      //不能為vm或者vm的根資料物件(即 data等)添加屬性!!!
      Vue.set()
      vm.$set()
      
  • 實體

    <div id="root">
        <button @click="student.age++">年齡加一歲</button> <br>
        <button @click.once="addgender">添加性別屬性,默認男</button> <br>
        <button @click.once="addaf">在朋友們最前面加一個朋友</button> <br>
        <button @click.once="updateff">修改第一個朋友的名字</button> <br>
        <button @click.once="addh">添加一個愛好</button> <br>
        <button @click.once="updatafh">修改第一個愛好</button> <br>
        <h1>姓名 {{student.name}}</h1>
        <h2>綽號 {{student.nickname}}</h2>
        <h3>年齡 {{student.age}}</h3>
        <h3 v-if="student.gender">性別 {{student.gender}}</h3>
        <h3>朋友們</h3>
        <ul>
            <li v-for="(f,index) in student.friends" :key="index">
                {{f.name}}--{{f.age}}
            </li>
        </ul>
        <h3>愛好</h3>
        <ul>
            <li v-for="(h,index) in student.hobby" :key="index">
                {{h}}
            </li>
        </ul>
    </div>
    
    var vm = new Vue({
        el: '#root',
        data: {
            student: {
                name: '張三',
                nickname: '法外狂徒',
                age: 20,
                friends: [
                    { name: '羅老師', age: 18 },
                    { name: '李四', age: 22 },
                ],
                hobby: ['抽煙', '賭博', '干壞事']
            }
        },
        methods: {
            addgender() {
                // 第一種
                // Vue.set(this.student,'gender','男');
                // 第二種
                this.$set(this.student, 'gender', '男');
            },
            addaf() {
                this.student.friends.unshift({ name: '王五', age: 40 });
            },
            updateff() {
                this.student.friends[0].name = '王大炮'
            },
            addh() {
                this.student.hobby.push('開車');
            },
            updatafh() {
                // 第一種
                // this.student.hobby.splice(0,1,'學習');
                // 第二種
                // Vue.set(this.student.hobby, 0, '學習');
                // 第三種
                this.$set(this.student.hobby, 0, '學習');
            }
        }
    })
    

五、過濾器

過濾器:對要顯示的資料進行特定格式化后再顯示(適用于一些簡單邏輯處理)

  • 語法:
    • 注冊過濾器:Vue.filter(name,callback)(全域過濾器) ,new Vue({filters:{}})(區域過濾器)
    • 使用過濾器:{{xxx | 過濾器名}} 或 v-bind:屬性 = “xxx | 過濾器名”
  • 備注:
    • 過濾器相對于一個函式,但是使用時不需要呼叫(即使用())默認會接收需要被過濾的資料作為第一個引數,也可以接收額外的引數
    • 多個過濾器可以串聯
    • 過濾器不會改變原始資料,而是對原始資料進行操作,如何產生新的資料
    • 一個中文前端插件庫:BootCDN
      • 日期時間處理庫(功能強大):moment.js
      • 輕量日期時間處理庫:day.js

六、自定義Vue指令

  • 定義語法:

    • 區域指令

      new Vue({
          directives:{
              指令名:配置物件
              //配置物件
              bind() //指令與元素成功系結的時候呼叫
              inserted() //指令所在元素被插入頁面時呼叫
              update() //指令所在模板被重新決議時呼叫
          }  //物件形式
          
          //簡寫
          directives:{
          	指令名(){}  //寫成一個函式
              //這個函式相對于定義了上述配置項的bind()和update()
      	}
      })
      
    • 全域指令

      Vue.directive(指令名,配置物件)
      Vue.directive(指令名,配置函式)
      
  • 備注

    • 指令定義時不加v-,但是使用的時候需要加v-
    • 指令名如果是多個單詞,使用kebab-case命名方式,不用駝峰命名方式,

七、生命周期(重點難點)

  • 生命周期,又叫做生命周期回呼函式、生命周期函式、生命周期鉤子
  • 生命周期是Vue在關鍵時刻幫我們呼叫了一些特殊名稱的函式
  • 生命周期函式名稱不可更改,但是函式邏輯是由程式員根據需求撰寫的
  • 生命周期函式中的this指向的是vm或組件實體物件

Vue生命周期

常用的生命周期鉤子

  • mounted:發送ajax請求、啟動定時器、系結自定義事件、訂閱訊息等(初始化操作)
  • beforeDestroy:清除定時器、解除自定義事件系結、取消訂閱訊息等(收尾作業)

銷毀Vue實體

  • 銷毀后借助Vue開發者工具將看不見任何資訊
  • 銷毀后自定義事件會失效,但是Vue的作業成果(最后一次更新后的真實DOM)會保留,原生DOM的事件依然有效
  • 一般不會在beforeDestroy鉤子中操作Vue實體相關資料,因為即使操了,Vue也不會再進行更新等流程

(三)Vue組件化編程

一、簡介

  • 模塊:向外提供特定功能的JS檔案

    • JS檔案在實際開發中很多很復雜
    • 可以復用JS,簡化JS的撰寫,提高效率
    • 模塊化:當應用的JS都以模塊形式來撰寫,那么這個應用就是一個模塊化的應用
  • 組件:用來實作區域(特定)功能效果的代碼及依賴資料集合(html/css/js/img/mp3…)

    • 實際開發中一個界面的功能很復雜
    • 復用編碼,簡化專案編碼,便于理清專案結構,提高運行效率
    • 組件化:當應用都是以組件的形式來搭建撰寫的,那么這個應用就是一個組件化的應用
    • 非單檔案組件:一個檔案中包含了一個到多個組件
    • 單檔案組件:一個檔案中只包含一個檔案

二、基礎

1.非單檔案組件

1.1 基礎使用
  • 定義組件

    • 使用Vue.extend(options)創建,其中options和創建Vue實體時傳入的配置項基基本一樣,有如下區別
      • el配置項不能使用,因為最終組件都會被一個Vue實體管理,由Vue(大哥)決定他及他的組件(小弟)為哪個容器服務
      • data必須用函式形式,因為組件為了被復用,用函式才能避免資料存在參考關系
      • 注:組件中用template配置組件結構
  • 注冊組件

    • 區域注冊:創建Vue實體時的components配置項
    • 全域注冊:Vue.component(‘組件名’,組件);
    • 組件名不要與HTML標簽名沖突
  • 使用組件

    • 組件標簽(類似于HTML標簽)
  • 實體

    <div id="root">
        <h1>root</h1>
        <heade></heade>
        <hr>
        <bodyer></bodyer>
        <foote></foote>
    </div>
    <div id="root1">
        <h1>root1</h1>
        <foote></foote>
    </div>
    
    // 定義組件header
    var heade=Vue.extend({
        template:`
            <div>
            	<h1>歡迎訪問{{name}}系統!</h1>
            </div>
    `,
        data(){
            return {
                name:'智慧張三'
            }
        }
    })
    // 定義組件bodyer
    var bodyer=Vue.extend({
        template:`
            <div>
            	<h1>{{name}}串列</h1>
            	<ul>
                    <li v-for="(s,index) in students">
                    	{{s.name}}---{{s.age}}
                    </li>
                </ul>
            </div>
    `,
        data(){
            return {
                name:'學生',
                students:[
                    {name:'張三',age:18},
                    {name:'羅老師',age:30},
                ]
            }
        }
    })
    
    var foote=Vue.extend({
        template:`
            <div>
            	<h2>版本號{{num}}!</h2>
            </div>
    `,
        data(){
            return {
                num:'v1.0.1'
            }
        }
    })
    
    // 注冊組件(全域)
    Vue.component('foote',foote)
    
    var vm = new Vue({
        el: '#root',
        data: {
    
        },
        // 注冊組件(區域)
        components:{
            heade,
            bodyer
        }
    })
    
    new Vue({
        el: '#root1',
    })
    
1.2 組件命名等注意事項
  • 組件命名

    • 一個單詞
      • 首字母小寫
      • 首字母大寫
    • 多個單詞
      • kebab-case命名法
      • 單詞首字母全大寫(需要Vue腳手架支持)
    • 注意:
      • 組件命名需要回避HTML標簽
      • 可以使用name屬性指定組件在Vue開發者工具中的展現名字(組件定義時)
  • 組件標簽

    • 第一種寫法:雙標簽,如:<bodyer></bodyer>
    • 第二種寫法:自閉合標簽,如:<bodyer/>(需要Vue腳手架支持,否則其后的組件不能被渲染)
  • 定義簡寫

    var heade=Vue.extend(options)
    //簡寫
    var heade=options;
    
    
    
1.3 關于VueComponent函式
  • 組件本質上是一個名為VueComponent建構式,而且不需要由我們定義,是Vue.extend生成的
  • 我們在使用組件時,Vue決議到會幫我們創建對應組件的實體物件,即執行new VueComponent(options);
  • 每次呼叫Vue.extend,回傳的都是一個全新的VueComponent!!!
  • 關于this指向
    • 組件配置中:data函式、methods中的函式、watch中的函式、computed中的函式,它們的this都指向VueComponent實體物件
    • new Vue()配置中:data函式、methods中的函式、watch中的函式、computed中的函式,它們的this都指向Vue實體物件
1.4 一個重要的內置關系
  • VueComponent.prototype.__proto__ === Vue.prototype
  • 目的:讓組件實體物件也可以訪問到Vue原型上的屬性、方法

2.單檔案組件

(四)腳手架(CLI)的使用

一、初始化腳手架

  • 腳手架是Vue官方提供的標準化開發工具(開發平臺)
  • 官方檔案
  • 安裝步驟
    • npm install -g @vue/cli 全域安裝@vue/cli (只需要安裝一次)
    • 在你要創建專案的目錄下,使用命令創建專案 vue create xxxx
    • 啟動專案 npm run serve
    • 備注:
      • 如果出現下載緩慢,請配置npm淘寶鏡像: npm config set registry https://registry.npm.taobao.org --global

        npm config set disturl https: //npm.taobao.org/dist --global

      • Vue腳手架隱藏了所有的webpack相關的配置,如想要查看具體的wekpack配置,請執行: vue inspect > output.js

二、關于不同版本Vue

  • vue.js與vue.runtime.xxx.js的區別:
    • vue.js是完整版的vue,包含了核心功能+模板決議器
    • vue.runtime.xxx.js是運行版的vue,只包含了核心功能,沒有模板決議器,
  • 因為vue.runtime.xxx.js沒有模板決議器,所以不能使用template配置項,需要使用render函式將收到的createELement函式去指定具體內容,

三、vue.config.js組態檔

  • 使用output.js可以查看到腳手架默認配置,
  • 使用vue.config.js可以對腳手架進行個性化定制,詳見:腳手架配置
//單檔案組件示例
<template>
    <div>
        <School></School>
        <Student></Student>
    </div>
</template>

<script>
import School from './components/Test1.vue';
import Student from './components/Test2.vue';

export default {
    name:'App',
    components:{
        School,
        Student
    }
}
</script>

<style>

</style>

四、ref屬性

  • 用來給元素或者子組件注冊參考資訊(相當于id)

  • 應用在html標簽上獲取真實的DOM元素,應用在組件標簽上是組件的實體物件(vc)

  • 使用方式

    <template>
        <div>
            <h1 ref="h1">你好</h1>
            <School ref="sch"></School>
            <button ref="but" @click="console">輸出refs</button>
            <Student></Student>
        </div>
    </template>
    
    <script>
    import School from './components/Test1.vue';
    import Student from './components/Test2.vue';
    
    export default {
        name:'App',
        components:{
            School,
            Student
        },
        methods: {
            console(){
                console.log(this.$refs);
            }
        },
    }
    </script>
    

五、配置項props

功能:讓組件接收外部傳過來的資料

備注:props是只讀的,Vue底層會監視你對props的修改,如果進行了修改,就會發出警告

export default {
    name:'Student',
    data(){
        return {
            mas:'你好,我是:'
        }
    },
    // 第一種方式:(只是簡單接收)
    // props:['name','gender','age'],
    // 第二種方式:(限制資料型別)
    // props:{
    //     name:String,
    //     gender:String,
    //     age:Number
    // }
    // 第三種方式:(詳細配置)
    props:{
        name:{
            type:String,  //型別
            required:true  //必要性
        },
        gender:{
            type:String,
            default:'男'   //默認值
        },
        age:{
            type:Number, 
            required:true
        }
    }
}

六、混合(混入)

功能:把某些組件共用的配置提取出來,成為一個混合物件

使用方式

//定義并暴露混合
export const mixin={
    data(){
        return {
            message:'你好啊!!'
        }
    },
    methods: {
        nihao(){
            alert("Hello!");
        }
    },
    mounted(){
        console.log("掛載了組件");
    },
}

//使用混合
//區域使用
import {mixin} from './mixin';
mixins:[mixin]

//全域使用(在main.js中引入注冊混合)
import {mixin} from './mixin';
Vue.mixin(mixin);

七、插件

功能:增強Vue

本質:包含install方法的一個物件,install的第一個引數是Vue,第二個以后的引數是插件使用所需要的資料

//定義插件
export default {
    install(Vue){
        Vue.prototype.test=()=>{
            alert('你好!');
        }
    }
}

//引入及使用(在main.js中)
import plugin from './plugins';
Vue.use(plugin);

八、scoped樣式

作用:讓樣式只在區域(當前組件生效)其他地方不生效,這樣來避免組件間樣式沖突

<style scopes></style>

九、web Storage

  • 存盤內容大小一般支持5MB左右(不同的瀏覽器可能不一樣)
  • 瀏覽端通過Window.sessionStorage和Window.localStorage屬性來實作本地存盤機制,
  • 相關API:
    • setItem('key','value');該方法接收一個鍵和值作為引數,會把鍵值對添加到存盤中,如果鍵名存在,則直接更新對應的值
    • getItem('key');該方法根據鍵獲取存盤中的值,如果沒有,回傳null
    • removeItem('key');該方法根據鍵洗掉存盤中的相應的鍵值對
    • clear();清空存盤的資訊
  • SessionStorage(會話存盤)存盤的內容會隨著瀏覽器關閉而消失
  • LocalStorage(本地存盤)存盤的內容,需要手動清除才會消失

十、組件自定義事件

  • 一種組件間通信方式,子組件===>父組件

  • 系結與觸發事件

    //父組件中
    <!-- 為子組件系結自定義事件,實作子給父傳遞資料(v-on/@)-->
    <School @test="getName"></School>  <!-- 普通事件系結的修飾符仍然可用,如once等 -->
    <!-- 為子組件系結自定義事件,實作子給父傳遞資料(ref 更加靈活) -->
    <School ref="school"></School>
    
    //父組件中
    methods: {
        getName(name){
            console.log(name+'拿到了');
        }
    },
    mounted(){
        setTimeout(()=>{
            this.$refs.school.$on('test',this.getName);  //使用$once方法,事件只觸發一次
            //注意:通過該方法系結事件時,回呼建議配置在methods中或者使用箭頭函式,否則回呼中(this.getName中)的this指向的是觸發事件的子組件
        },3000)
    }
    
    //子組件中觸發事件
    this.$emit('test',this.name);  
    
  • 解除事件系結

    //在子組件中
    this.$off('test');  //解除事件test系結
    this.$off(['test1','test2']);  //解除事件test1,test2的系結
    this.$off();  //解除所有事件系結
    
  • 組件系結原生DOM事件,需要使用native修飾符

十一、全域事件總線(GlobalEventBus)(重點)

  • 一種組件間通信的方式,任意組件間通信(基于組件自定義事件)

  • 安裝全域事件總線:(實際上就是造一個中轉的組件實體物件,該VC可以被所有其他組件訪問到)

    //在main.js的root組件中
    beforeCreate(){
        Vue.prototype.$bus=this  //$bus就是當前應用的vm,也就作為上述要造的vc
    }
    
  • 使用事件總線

    • 接收資料的組件:給$bus系結自定義事件,事件的回呼在自身

      methods:{
      	test(data){}  //回呼函式
      }
      mounted(){
      	this.$bus.$on('事件名',this.test);  //系結事件
      }
      
    • 發送資料的組件

      this.$bus.$emit('事件名',data);  //觸發事件
      
  • 最好在beforeDestroy鉤子中,用$off去解綁當前組件所用到的事件,

十二、訊息訂閱與發布(pubsub)

  • 一種組件間的通信方式,適用于任意組件間通信,

  • 使用

    • 安裝第三方庫:(這里用的是pubsub-js,也可以用其他的)npm i pubsub-js

    • 引入:import pubsub from 'pubsub-js'

    • 接收資料的組件中訂閱訊息,在自身撰寫回呼函式

      methods(){
          test(data){}
      }
      mounted(){
          this.pubid=pubsub.subscribe('訊息名',this.test);   //訂閱訊息
      }
      
    • 提供資料的組件發送訊息

      pubsub.publish('訊息名',data);
      
    • 最好在beforeDestroy鉤子中,用pubsub.unsubscribe(this.pubid)去取消訊息訂閱

十三、$nextTick

  • this.$nextTick(回呼函式)
  • 作用:在下一次DOM更新結束后執行其回呼函式,
  • 什么時候用,當改變資料后,要基于更行后的DOM進行某些操作的時候,要在nextTick所指定的回呼中執行,

十四、Vue封裝的過度與影片

  • 在插入、更新或者移除DOM元素時,會在合適的時候給元素添加樣式類名

  • v-enter == v-enter-active ==> v-enter-to v-leave == v-leave-active ==> v-leave-to

  • 使用方法

    • 準備好樣式:

      • v-enter:進入的起點
      • v-enter-active:進入的程序中
      • v-enter-to:進入的終點
      • v-leave:離開的起點
      • v-leave-active:離開的程序中
      • v-leave-to:離開的終點
    • 使用<transition>包裹要過度的元素,并配置name屬性:

      <transition name="test">  <!-- 指定了name屬性,需要將類名對應為相應的(例如test-enter) -->
          	<h1 v-show="isShow">你好啊!</h1>
      </transition>
      
    • 備注:如果有多個元素需要影片效果,則需要使用:transition-group,且每個元素都要指定key

    實體一:

    <button @click="change">顯示/隱藏</button>
    <transition name="test" appear>
        <div v-show="isShow" class="a">
            <h1>{{mes}}</h1>
        </div>
    </transition>
    
    <button @click="change">顯示/隱藏</button>
    .test-enter-active{
        animation: test 1s;
    }
    
    .test-leave-active{
        animation: test 1s reverse;
    }
    @keyframes test{
        from{
            transform: translateX(-100%);
        }
        to{
            transform: translateX(0);
        }
    }
    

    實體二:

    <transition name="test1" appear>
        <div v-show="isShow" class="a">
            <h1>{{mes}}</h1>
        </div>
    </transition>
    
    <button @click="change">顯示/隱藏</button>
    .test1-enter, .test1-leave-to{
        transform: translateX(-100%);
    }
    
    .test1-leave, .test1-enter-to{
        transform: translateX(0);
    }
    
    .test1-leave-active, .test1-enter-active{
        transition: 1s linear;
    }
    

    實體三:

    <button @click="change">顯示/隱藏</button>
    <transition-group name="test2" appear>
        <div v-show="isShow" class="a" key="1">
            <h1>{{mes}}</h1>
        </div>
        <div v-show="!isShow" class="a" key="2">
            <h1>{{mes}}</h1>
        </div>
    </transition-group>
    
    .test2-enter, .test2-leave-to{
        transform: translateX(-100%);
    }
    
    .test2-leave, .test2-enter-to{
        transform: translateX(0);
    }
    
    .test2-leave-active, .test2-enter-active{
        transition: 1s linear;
    }
    
  • 影片庫推薦:animate.css

    • 安裝 npm i animate.css
    • 引入 import 'animate.css';
    • 官方檔案 animate.css
    <button @click="change">顯示/隱藏</button>
    <transition 
                appear
                name="animate__animated animate__bounce"
                enter-active-class="animate__rubberBand"
                leave-active-class="animate__backOutDown"
                >
        <div v-show="isShow" class="a">
            <h1>{{mes}}</h1>
        </div>
    </transition>
    
  
  ```javascript
  import 'animate.css';
//記得配置這個methods
  change(){
      this.isShow=!this.isShow;
  }

十五、插槽

  • 作用:讓父組件可以向子組件中指定位置插入HTML結構,也是一種組件間通信方式 父組件===>子組件

  • 使用

    • 默認插槽

      //父組件
      <template>
          <List title="汽車">
              <img src="" alt="">
          </List>
          <List title="食物">
              <ul>
                  <li v-for="(f,i) in foods" :key="i">{{f}}</li>
              </ul>
          </List>
          <List title="游戲">
              <!-- <ul>
                  <li v-for="(g,i) in games" :key="i">{{g}}</li>
              </ul> -->
          </List>
      </template>
      
      <script>
      import List from "./components/Test1.vue";
      export default {
        name: "App",
        components: { List },
        data() {
          return {
            foods: ["海底撈", "燒烤"],
            cars: ["勞斯萊斯", "蘭博基尼"],
            games: ["推箱子", "連連看"],
          };
        },
      };
      </script>
      <style>
      .lists,
      .a {
        display: flex;
        justify-content: space-around;
      }
      img {
        width: 100%;
      }
      </style>
      
      //子組件
      <template>
          <div class="list">
              <h1>{{title}} 串列</h1>
              <slot>沒有內容了,,,</slot>
          </div>
      </template>
      
    • 具名插槽

      //父組件
      <template>
          <div class="lists">
              <List title="汽車">
                  <a slot="test" href="#">更多</a>
              </List>
              <List title="食物">
                  <div slot="test" class="a">
                      <a href="#">中餐</a>
                      <a href="#">西餐</a>
                  </div>
              </List>
              <List title="游戲">
                  <!-- 在用template標簽時可以這樣用,也可以slot="test" -->
                  <template v-slot:test>   
                      <div class="a">
                          <a href="#">單機</a>
                          <a href="#">聯機</a>
                      </div>
                      <h2>快來游玩吧!</h2>
                  </template>
              </List>
          </div>
      </template>
      
      //子組件
      <template>
          <div class="list">
              <h1>{{title}} 串列</h1>
              <slot name="test">沒有內容了111,,,</slot>
          </div>
      </template>
      
    • 作用域插槽

      • 資料在子組件中,但是根據資料生成什么樣的結構由父組件決定
      //父組件
      <template>
          <div class="lists">
              <List title="手機">
                  <template slot="test2" scope="{phones}">
                      <ul>
                          <li v-for="(p,i) in phones" :key="i">{{p}}</li>
                      </ul>
                  </template>
              </List>
              <List title="手機">
                  <!-- vue2.6后新的寫法 -->
                  <template v-slot:test2="{phones}">
                      <ol>
                          <li v-for="(p,i) in phones" :key="i">{{p}}</li>
                      </ol>
                  </template>
              </List>
          </div>
      </template>
      
      //子組件
      <template>
          <div class="list">
              <h1>{{title}} 串列</h1>
              <slot name="test2" :phones="phones">沒有內容222</slot>
          </div>
      </template>
      <script>
      export default {
          name:'List',
          data(){
              return {
                  phones:['小米','華為']
              }
          },
          props:['title']
      }
      </script>
      
      <style scoped>
          .list{
              background-color: skyblue;
              width: 200px;
              height: 300px;
          }
          h1{
              text-align: center;
          }
          li{
              background-color: orange;
              font-size: 18px;
              margin-bottom: 8px;
          }
      </style>
      

(五)Vue使用Ajax

一、axios:功能強大的網路請求庫

安裝 :npm npm上axios地址,網上找都行,到處都是

1.axios基本使用

<div id="app">
    <button @click="get">get</button>
    <br>
    <button @click="post">post</button>
</div>
var app=new Vue({
    el:'#app',
    methods:{
        get:function(){
            axios.get("http://127.0.0.1:3000/get?num=4")  //自己寫的測驗介面,下同
                .then(
                function(res){
                    console.log(res);
                },function(err){
                    console.log(err);
                }
            )
        },
        post:function(){
            axios.post("http://127.0.0.1:3000/post",{num:5})
                .then(
                function(res){
                    console.log(res);
                },function(err){
                    console.log(err);
                }
            )
        }
    }
})

二、Vue腳手架配置服務器代理

  • 方法一

    // 開啟代理服務器(方式一)
    devServer: {
        proxy: 'http://localhost:5000'
    },
    
    students(){
        axios.get("http://localhost:8081/students").then(
            (res)=>{
                console.log(res.data);
            },
            (err)=>{
                console.log(err.massage);
            }
        )
    }
    
    • 優點:配置簡單,請求資源時直接發送給本機服務器(8081)即可,
    • 缺點:不能配置多個代理,不能靈活選擇是否讓代理轉發請求
    • 作業方式:當請求時,優先訪問本機服務器,如果本機服務器沒有資源,才會轉發請求到對應服務器
  • 方法二

    // 開啟代理服務器(方式二)
    devServer: {
        proxy: {
            '/s': {  //當請求前綴為/s時代理服務器轉發請求到target
                target: 'http://localhost:5000',
                pathRewrite:{'^/s':''},  //代理服務器轉發請求時,將前綴/s去掉
                ws: true,  //用于支持websocket
                changeOrigin: true  //用于控制請求頭中的Host值(true: localhost:5000 false :localhost:8081)
            },
            '/c': {  //當請求前綴為/s時代理服務器轉發請求到target
                target: 'http://localhost:5001',
                pathRewrite:{'^/c':''},  //代理服務器轉發請求時,將前綴/s去掉
                ws: true,  //用于支持websocket
                changeOrigin: true  //用于控制請求頭中的Host值(true: localhost:5000 false :localhost:8081)
            }
        }
    }
    
    students(){
        axios.get("http://localhost:8081/s/students").then(
            (res)=>{
                console.log(res.data);
            },
            (err)=>{
                console.log(err.massage);
            }
        )
    },
    cars(){
        axios.get("http://localhost:8081/c/cars").then(
            (res)=>{
                console.log(res.data);
            },
            (err)=>{
                console.log(err.massage);
            }
        )
    }
    
    • 優點:可以配置多個代理,且靈活控制
    • 配置繁瑣,請求時需要加前綴

三、vue-resource插件(了解)

  • 安裝 npm i vue-resource
  • 使用
    • 引入 import vueResource from 'vue-resource'
    • 使用 Vue.use(vueResource);
    • 使用 this.$http.get(...)

(六)Vuex(重點)

一、Vuex簡介

  • 概念:專門在Vue中實作集中式狀態(資料)管理的一個Vue插件,對vue應用中多個組件的共享狀態進行集中式的管理(讀寫),也是組件間通信方式之一,適用于任意組件間通信

  • Github地址:vuex

  • 原理:

vuex原理圖

二、Vuex搭建

  • 安裝:npm i vuex

  • 創建檔案:src/store/index.js

    // 引入Vue
    import Vue from 'vue'
    // 引入Vuex
    import Vuex from 'vuex'
    // 應用Vuex插件
    Vue.use(Vuex);
    
    // 創建并暴露store
    export default new Vuex.Store({
        actions:{},
        mutations:{},
        state:{}
    })
    
  • 在main.js中配置store

    // 引入store
    import store from './store'
    
    import App from './App.vue'
    
    Vue.config.productionTip = false
    
    Vue.use(vuex);
    
    new Vue({
      render: h => h(App),
      store
    }).$mount('#app')
    

三、基本使用

  • 初始化資料state、配置actions,mutations

    actions:{
        //回應組件中的動作
        fun(context,value){
            //context:背景關系,相當于一個minstore,在里面有所有這里可能需要用到的資料和方法
            	//context.dispatch('action中的方法名',value) 可以對資料做多步中間處理
            	//context.state.test可以直接訪問到state中的資料,這里不要直接去修改資料,可以讀取資料做條件判斷等,
            		//如果直接修改資料,vue開發者工具無法捕捉到
            	//context.commit('mutations中的方法名',data) 提交操作
        }
        //業務邏輯全部寫在這里
    },
    mutations:{
        //執行操作
        //這里的方法名約定全大寫,方便與actions中的方法進行區分
        FUN(state,value){
            //state 就是state,這里就對資料進行基本操作(不關心業務邏輯,只關心基本增刪改查操作)
        }
    },
    state:{
        //資料
        test:0
    }
    
  • 組件中讀取資料,發起操作

    //讀取資料
    $store.state.test
    //發起操作
    $store.dispatch('action中的方法名',data)
    //如果不需要action做中間處理,則直接提交操作
    $store.commit('mutations中的方法名',data)
    

1. getters配置項

  • 概念:當state中的資料需要經過加工后再共享使用的時候,可以用getters加工

  • 用法:

    getters:{
        bigTest(state){
            return state.test*10;
        }
    }
    //用法形如組件中的computed計算屬性,但是getters可以在組件間復用
    

2.四個map方法

引入import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'

2.1 mapState
  • 用于幫助我們映射state中的資料為computed計算屬性

    computed:{
        //物件寫法
        ...mapState({a:'test1',b:'test2',c:'test3'})
        //陣列寫法(不能重新命名,生成的計算屬性名與state物件中的屬性名一致,傳遞的引數也得與state物件中的屬性名一致)
        ...mapState(['test1','test2','test3'])
    }
    
2.2 mapGetters
  • 用于幫助我們映射getters中的資料為computed計算屬性

    computed:{
        //物件寫法
        ...mapGetters({a:'test1',b:'test2',c:'test3'})
        //陣列寫法(不能重新命名,生成的計算屬性名與Getters物件中的屬性名一致,傳遞的引數也得與Getters物件中的屬性名一致)
        ...mapGetters(['test1','test2','test3'])
    }
    
2.3 mapActions
  • 用于幫助我們生成與actions對話的方法

    methods:{
        //物件寫法
        ...mapActions({a:'test1',b:'test2',c:'test3'})
        //生成的函式
        //a(value){
        //    $store.dispatch('test1',value);
        //}
        //陣列寫法(不能重新命名,生成的函式名與actions物件中的方法名一致,傳遞的引數也得與actions物件中的方法名一致)
        ...mapActions(['test1','test2','test3'])  
    }
    
2.4 mapMutations
  • 用于幫助我們生成與mutations對話的方法

    methods:{
        //物件寫法
        ...mapMutations({a:'TEST1',b:'TEST2'})
        //生成的函式
        //a(value){
        //    $store.commit('TEST1',value);
        //}
        //陣列寫法(不能重新命名,生成的函式名與mutations物件中的方法名一致,傳遞的引數也得與mutations物件中的方法名一致)
        ...mapMutations(['TEST1','TEST2'])  
    }
    

3.模塊化+命名空間

  • 目的:讓代碼更好的維護,讓多種資料分類更加明確

  • 使用方法

    • 創建并暴露模塊

      //在model1.js中
      export default model1={
          //開啟命名空間
          namespaced:true,
          state:{},
          actions:{},
          mutations:{},
          getters:{}
      }
      
      //在model2.js中
      export default model2={
          //開啟命名空間
          namespaced:true,
          state:{},
          actions:{},
          mutations:{},
          getters:{}
      }
      
    • 在store模塊中引入并使用其他模塊

      //在index.js中
      // 引入Vue
      import Vue from 'vue'
      // 引入Vuex
      import Vuex from 'vuex'
      //引入其他模塊
      import model1 from './model1'
      import model2 from './model2'
      // 應用Vuex插件
      Vue.use(Vuex);
      
      // 創建并暴露store
      export default new Vuex.Store({
          modules:{
              model1,
              model2
          }
      })
      
    • 讀取state中資料的方法(在讀取時要以某一種形式指明資料所在的模塊)

      //直接讀取
      this.$store.state.model1.test1
      //借助mapState讀取
      ...mapState('model1',['test1','test2'])
      
    • 讀取getters中資料的方法

      //直接讀取
      this.$store.getters['model2/test1']
      //借助mapGetters
      ...mapGetters('model2',['test1','test2'])
      
    • 呼叫dispatch與Actions對話的方法

      //直接對話
      this.$store.dispatch('model1/test1',data)
      //借助mapActions
      ...mapActions('model1',['test1','test2'])
      
    • 呼叫commit與Mutations對話的方法

      //直接對話
      this.$store.commit('model2/test1',data)
      //借助mapMutations
      ...mapMutations('model2',['TEST1','TEST2'])
      

(七)路由 vue-router(重點)

一、vue-router簡介

vue-router是vue的一個插件庫,專門用來實作SPA(單頁面)應用

1.SPA簡介

  • 單頁面Web應用(Single page web application,SPA)
  • 整個應用只有一個完整的頁面
  • 點擊頁面中的導航鏈接不會重繪頁面,只會做頁面的區域更新
  • 資料通過Ajax請求獲取

2.路由

  • 什么是路由
    • 一個路由就是一組映射關系(key-value)
    • key是路徑,value可能是function或component
  • 路由分類
    • 后端路由
      • 理解:value是function,用于處理客戶端提交的請求
      • 作業程序:服務器收到一個請求時,根據請求路徑找到匹配的函式來處理請求,回傳回應資料
    • 前端路由
      • 理解:value是component,用于展示頁面內容
      • 作業程序:當瀏覽器的路徑改變的時候,對應的組件就會顯示

二、基本使用

  • 安裝vue-router npm i vue-router

  • 引入 import VueRouter from 'vue-router'

  • 應用插件 Vue.use(VueRouter);

  • 創建并暴露一個router

    //在src/router/index.js下
    //引入vue-router
    import VueRouter from 'vue-router'
    //引入相關組件
    import Component1 from '../component/Component1'
    import Component2 from '../component/Component2'
    
    //創建并暴露router
    export default router= new VueRouter({
        routes:[
            {
                path:'/component1',
                component:Component1
            },
            {
                path:'/component2',
                component:Component2
            }
        ]
    })
    
  • 實作切換

    <router-link active-class="active" to="/component1">Component1</router-link>
    <!-- active-class指定被選中時的樣式,to指定跳轉路徑 -->
    <!-- router-link 最終呈現出來是一個a標簽 -->
    
  • 指定顯示位置

    <router-view></router-view>
    
  • 注意!

    • 在開發中,路由組件通常放在src/pages下,一般的組件通常放在src/components下
    • 切換路徑進而切換顯示的組件時,默認是在銷毀、掛載組件
    • 每個組件都有自己的$route屬性,里面存盤著自己的路由資訊
    • 整個應用只有一個router,通過每個路由組件的$router屬性訪問

三、多級路由

  • 配置路由規則,在一級路由里使用children進行配置

    export default router= new VueRouter({
        routes:[
            {
                path:'/component1',
                component:Component1,
                //配置子級路由,可以無限套娃
                children:[
                    {
                        path:'child1',  //children中的路徑不需要寫/
                        component:Child1
                    },
                    {
                        path:'child2',
                        component:Child2
                    }
                ]
            }
        ]
    })
    
  • 跳轉(to中的路徑需要寫完整)

    <router-link to="/component1/child1">Child1</router-link>  
    

四、路由傳參

1. query引數

  • 傳遞引數

    <!-- 字串寫法 -->
    <router-link :to="`/component1/child1/test1?a=${data.a}&b=${data.b}`">Test1</router-link>
    <!-- 物件寫法 -->
    <router-link 
    	:to="{
    		path:'/component1/child1/test1',
            query:{
            	a:data.a,
             	b:data.b
            }
    	}"
    >Test1</router-link>
    
  • 接收引數

    this.$route.query.a
    

2.路由命名(name配置項)

  • 使用

    export default router= new VueRouter({
        routes:[
            ...
                {
                    name:'c1',  //配置名字
                    path:'xxxx',
                    component:xxxxx
                },
    	]
    })
    
  • 簡化跳轉

    <!-- 主要是在子級路由跳轉時,即路徑較長,或者需要傳遞引數,使用物件寫法 -->
    <router-link 
    	:to="{
    		name:'c1',
            query:{
            	...
            }
    	}"
    >Test1</router-link>
    

3.params引數

  • 在配置中宣告params引數

    name:'c1'
    path:'xxxx/:a/:b'  //使用占位符宣告params引數
    
  • 傳遞引數

    <!-- 字串寫法 -->
    <router-link :to="`/xxxx/${data.a}/${data.b}`">Test1</router-link>
    <!-- 物件寫法 -->
    <router-link 
    	:to="{
    		name:'c1',   //這里必須用name,不能用path!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            query:{
            	a:data.a,
             	b:data.b
            }
    	}"
    >Test1</router-link>
    
  • 讀取引數

    this.$route.params.a
    

4.路由的props配置

作用,讓路由組件更方便接收到引數

{
    ...
    //第一種寫法:props值為物件,該物件中所有的key-value的組合最侄訓通過props傳給對應組件
    //props:{a:100,b:'hello'}
    //這種寫法不能動態賦值
    
    //第二種寫法:props值為true,路由收到的所有**params**引數通過props傳給對應組件
    //props:true
    //這種方法有局限性,只能處理params引數
    
    //第三種寫法:props值為函式,函式回傳一個物件,函式的第一個引數是$route,物件中所有的key-value的組合最侄訓通過props傳給對應組件
    props($route){
        return {
            a:$router.query.xxx
            b:$router.params.xxx
        }
    }
}

五、<router-link>的replace屬性

  • 作用:控制路由跳轉時操作瀏覽器歷史記錄的模式
  • 瀏覽器的歷史記錄有兩種寫入模式:分別是pushreplace,push是追加記錄(壓堆疊),replace是替換,默認是push
  • 開啟replace模式:<router-link replace>.....</router-link>

六、編程式路由導航

  • 作用:不需要再借助<router-link>,路由跳轉更加靈活

  • 具體方法

    //$router的兩個API
    this.$router.push({  //push模式跳轉
        name:'xxx',
        query:{
            ...
        }
    })
    //配置與to的物件寫法一樣
        
    this.$router.replace({  //replace模式跳轉
        name:'xxx',
        params:{
            ...
        }
    })
    
    //歷史記錄操作方法,$router的三個API
    this.$router.back() //后退一步
    this.$router.forward() //前進一步
    this.$router.go()  //傳遞引數,正數前進,負數后退具體的步數
    

七、快取路由組件

  • 作用:讓不展示的路由組件保持掛載,不被銷毀

  • 使用

    <keep-alive include="xxx">
    	<router-view></router-view>
    </keep-alive>
    <!-- 
    	keep-alive標簽中的內容將會被快取
    	include是一個配置項,里面值為**組件名**,其中包含的組件才會被快取,如果不配置include,則keep-alive中的組件都會被快取
    	include中需要包含多個組件時 :include="['xxx1','xxx2']"
    -->
    

八、activated與deactivated生命周期鉤子

  • 作用:路由組件獨有,用于捕獲路由組件的激活狀態
  • activated 路由組件被激活時觸發
  • deactivated 路由組件失活時觸發

九、路由守衛

1.全域守衛

//在暴露router之前,使用router相應API設定

//全域前置守衛:初始化時執行、每次路由切換前執行(控制訪問權限等)
router.beforeEach((to,from,next)=>{
    //to是即將跳轉的路由的相關資訊
    //from是跳轉前的路由相關資訊
    //next是一個函式,呼叫該函式即跳轉路由
})

//全域后置守衛:初始化時執行、每次路由切換后執行(控制頁簽名稱document.title變化等)
router.afterEach((to,from)=>{
    //to是即將跳轉的路由的相關資訊
    //from是跳轉前的路由相關資訊
})

//補充:路由配置中提供程式員存放其他資訊(標識資訊等)的配置項meta

2.獨享守衛

  • 某一個路由特有的
//配置在路由配置中
routes:[
    ...
    {
        ...
        beforeEnter(to,from,next){
        	...
        	//這里的三個引數與全域前置守衛一致
    	}
    }
]

3.組件內守衛

  • 組件獨享的守衛

    //在組件配置中
    //進入守衛:通過路由規則,進入該組件時被呼叫
    beforeRouteEnter(to,from,next){}
    //離開守衛:通過路由規則,離開該組件時被呼叫
    beforeRouteLeave(to,from,next){}
    //這里的三個引數與全域前置守衛一致
    

十、路由器作業模式

  • 對與一個路徑來說,hash值就是#及其后面的內容
  • hash值不會包含在HTTP請求中,即has值不會帶給服務器
  • hash模式
    • 優點
      • 兼容性較好
    • 缺點
      • 如果以后將地址通過第三方手機app分享,如果app校驗嚴格,則地址會標記為不合法
      • 地址中帶著/#/,不美觀
  • history模式
    • 優點
      • 地址干凈美觀
    • 缺點
      • 兼容性略差
      • 應用部署上線時需要后端人員支持,解決重繪頁面服務器404問題(本質上是因為重繪時瀏覽器將路徑全部發送給了服務器,請求服務器導致)
  • 補充:Nodejs解決重繪頁面服務器404問題方法(借助中間件)
    • 比如:connect-history-api-fallback npm上的connect-history-api-fallback
      • 安裝:npm i connect-history-api-fallback
      • 引入:const history = require('connect-history-api-fallback');
      • 使用:app.use(history()); (注意要在配置靜態資源前使用)

(八)Vue的常用UI組件庫

一、移動端常用UI組件庫

1.Vant

2.Cube UI

3.Mint UI

二、PC端常用UI組件庫

1.Element UI

2.IView UI

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

標籤:其他

上一篇:關于 JS 閉包看這一篇就夠了

下一篇:JavaScript(二)——資料型別,函式,陣列,字串

標籤雲
其他(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