03-修飾符-監聽屬性-傳送Ajax請求-生命週期鉤子

小满三岁啦發表於2024-04-28

事件修飾符

事件修飾符 作用
.stop 只處理自己的事件,父控制元件冒泡的事件不處理(阻止事件冒泡),一般用在子元素類上
.self 只處理自己的事件,子控制元件冒泡的事件不處理,一般用在父元素上
.prevent 阻止a連線的跳轉
.once 事件只會觸發一次(適用於抽獎頁面)

使用修飾符時,順序很重要;相應的程式碼會以同樣的順序產生

  • v-on:click.prevent.self 會阻止所有的點選
  • v-on:click.self.prevent 只會阻止對元素自身的點選

冒泡的概念

什麼是冒泡呢?以下面這個例子,比如有一個蕃茄色父盒子,裡面包裹了一個白色子盒子,分別繫結點選事件將輸出不同內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        .outer {
            width: 300px;
            height: 300px;
            padding: 10px;
            border: 2px solid black;
            margin: auto;
            background-color: tomato;
        }

        .inner {
            width: 150px;
            height: 50px;
            margin: auto;
            text-align: center;
            line-height: 50px;
            background-color: snow;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="outer" @click="outerEvent">
            <div class="inner" @click="innerEvent">不要點我啊 >_<</div>
        </div>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        methods: {
            outerEvent(){
                console.log("父親");
            },
            innerEvent(){
                console.log("兒子");
            }
        },
    })
</script>
</html>

效果如下,可以發現,當點選子盒子時,不僅子盒子事件被觸發,連同父盒子的事件也被觸發了。而只點父盒子時,只有父盒子事件觸發。這就是冒泡,事件會向上級DOM元素傳遞,由內而外,依次觸發。

img

stop (停止冒泡) 一般新增到子元素使用

當使用 .stop 事件修飾符時就能很簡單的阻止冒泡了,用法如下,直接給子盒子的點選事件後加上.stop即可:

<div class="outer" @click="outerEvent">
    <div class="inner" @click.stop="innerEvent">不要點我啊 >_<</div>
</div>

img

self (點選自己才會執行) 一般加到父元素

<div class="outer" @click.self="outerEvent">
    <div class="inner" @click="innerEvent">不要點我啊 >_<</div>
</div>

img

prevent (阻止默然行為)

阻止預設事件觸發。預設事件指對DOM的操作會引起自動執行的動作,比如點選a標籤超連結的時候會進行預設進行頁面的跳轉等等。

  • a連線的自動跳轉。
  • 表單的自動提交等。
<!-- 正常HTML程式碼 -->
<p><a href="#" @click.prevent="handleA">點我選桌布</a></p>

<script>
    // vue
    let vm = new Vue({
        el: "#app",
        methods: {
            handleA(){
                console.log("處理完成,允許訪問。");
                location.href = "https://snake.timeline.ink/home"
            }
        },
    })
</script>

img

事件只執行一次 .once

抽獎頁面大機率都是使用了這個

<div class="outer" @click.self="outerEvent">
    <div class="inner" @click.once="innerEvent">不要點我啊 >_<</div>
</div>

img

用capture後,是從上到下的。

按鍵修飾符

keyup

vue2寫法:keyup.具體的鍵位

vue3寫法:keyup.鍵位對應的數字 推薦

在Vue.js中,keyup是一個按鍵修飾符,它可以用來監聽鍵盤的keyup事件。當您在模板中使用@keyup時,您可以指定一個鍵盤按鍵,以便在使用者釋放該按鍵時觸發相應的事件處理函式。例如,您可以這樣使用:

<input @keyup.enter="submitForm">

Keycode對照表(鍵碼對照表):https://segmentfault.com/a/1190000005828048

<!-- vue2中 -->
<input type="text" @keyup.enter="showMsg" v-model="text"> --- <span>{{text}}</span>

<!-- vue2中 -->
<input type="text" @keyup.13="showMsg" v-model="text"> --- <span>{{text}}</span>

如果要獲取具體的按鍵 可以透過下面的方式

<body>
    <div id="app">
        <input type="text" @keyup="showMsg" v-model="text"> --- <span>{{text}}</span>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            text: ""
        },
        methods: {
            showMsg(e){
                console.log(`你剛剛按下了  ${e.key}  `);
            }
        },
    })
</script>

img

表單控制

在Vue.js中,:valuev-model之間的關係是這樣的::value用於向v-model繫結的資料傳遞值。當使用:value時,它決定了輸入元素(比如input或checkbox)的值,而這個值會影響到v-model繫結的資料。換句話說,:value提供了輸入元素的值,而v-model則負責將這個值與資料進行雙向繫結。

input屬性 v-model繫結 完整案例 說明
checkbox 單選:布林值remember:true, 多選:陣列 hobby:[] 需要指定value <label>欺負小滿<input type="checkbox" v-model="hobby" value="qfxm"></label> 單選:data裡面設定布林值,多選,設定陣列。
radio 字串 gender: "" 需要指定value <label>女<input type="radio" v-model="gender" value="girl"></label> data裡面設定字串
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        span {
            color: tomato;
        }
    </style>
</head>

<body>
    <div id="app">
        <h3>checkbox單選就是true和false</h3>
        <label>使用者名稱:<input type="text" v-model="username"></label><br>
        <label>密碼:<input type="password" v-model="password"></label><br>
        <label>記住密碼:<input type="checkbox" v-model="remember"></label><br>
        <p>使用者資訊:username: <span>{{username}}</span> password: <span>{{password}}</span> 記住密碼: <span>{{remember}}</span>
        </p>
        <hr>

        <h3>checkbox多選就是選value,v-model是陣列</h3>
        愛好:
        <label>逃課<input type="checkbox" v-model="hobby" value="tk"></label>
        <label>搶人頭<input type="checkbox" v-model="hobby" value="qrt"></label>
        <label>欺負小滿<input type="checkbox" v-model="hobby" value="qfxm"></label>
        <p>愛好:<span>{{hobby}}</span></p>
        <hr>

        <h3>raido單選也是value,v-model是字串</h3>
        性別:
        <label for="">男<input type="radio" v-model="gender" value="boy"></label>
        <label for="">女<input type="radio" v-model="gender" value="girl"></label>
        <p>性別:<span>{{gender}}</span></p>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            username: '',
            password: '',
            remember: false,
            hobby: [],
            gender: ""
        },
    })
</script>

</html>

img

購物車案例

需要留意的幾個問題:

  1. 全選/全不選和下面的核取方塊並不是一起的,所以需要單獨起一個函式去控制。

  2. 一般情況下true和false事件第一事件想到的就應該是change事件。

  3. 只要下面核取方塊不是全部選中,那麼全選核取方塊應該是非選中狀態。

    判斷長度,只要下面商品選中的長度之和等於列表長度,那麼全選設定為true,否則設定為false

  4. 在JavaScript中,字串是可以和數字進行乘法操作的,但是不建議,還是建議嚴謹一些,使用number型別。

  5. 傳遞的時候,傳遞物件才可以同步去修改,傳遞數字不可以,就相當於python中的可變資料型別。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        table {
            border: 1px solid black;
            border-collapse: collapse;
        }

        tr, th, td {
            border: 1px solid black;
            padding: 10px;
        }

        .to-center {
            text-align: center;
            align-items: center;
        }

    </style>
</head>

<body>
    <div id="app">
        <table>
            <caption>峽谷商品清單</caption>
            <tr>
                <th>id</th>
                <th>名稱</th>
                <th>數量</th>
                <th>價格</th>
                <!-- 
                    全選 全不選,需要繫結一個change事件,v-model需要設定成一個布林值,因為這是單個核取方塊 
                    核心點:這個核取方塊和下面的核取方塊並不是一起的,所以是需要單獨去控制
                -->
                <th>全選/全不選 <input type="checkbox" @change="changeEvent" v-model="checkAll"></th>
            </tr>
            <tr v-for="item in good_list">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td><button @click="minus(item)">-</button> {{item.count}} <button @click="item.count++">+</button></td>
                <td>{{item.price}}</td>
                <td class="to-center"><input type="checkbox" @change="changeOnce"  v-model="checkGoods" :value="item"></td>
            </tr>
        </table>
        <p>全選:<span style="color:red">{{checkAll}}</span></p>
        <p>商品的總價格為:<span :style="{color: 'red'}">{{totalPrice}}</span> 元</p>
        <!-- {{checkGoods}} -->
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            good_list: [
                { id: 1001, name: '紅buff', price: 273, count: 25 },
                { id: 1002, name: '藍buff', price: 237, count: 23 },
                { id: 1003, name: '人頭', price: 5999, count: 2 },
                { id: 1004, name: '摸魚手環', price: 1002, count: 3 },
                { id: 1005, name: '野怪', price: 249, count: 11 },
                { id: 1005, name: '河蟹', price: 308, count: 45 },
            ],
            // 迴圈出來的物件放進去陣列裡面
            checkGoods: [],
            // 全選的核取方塊
            checkAll: false,
        },
        methods: {
            // 控制商品數量的減少 小於0 alert
            minus: function(item){
                if (item.count > 1){
                    return item.count--
                }else{
                    alert("不能再減啦!")
                }
            },
            // 全選/不選商品
            changeEvent(){
                if (this.checkAll){
                    this.checkGoods = this.good_list
                }else{
                    this.checkGoods = []
                }
            },
            // 修復全選全部選的bug
            // 只要全部商品的總長度,等於列表的長度,那麼全選就設定成true,除開這種情況都是false
            changeOnce(){
                if (this.checkGoods.length === this.good_list.length){
                    this.checkAll = true
                }else{
                    this.checkAll =  false
                }
            }
        },
        computed: {
            // 返回選擇商品的價格
            totalPrice: function(){
                let total = 0
                for (let good of this.checkGoods) {
                    total += good.price * good.count
                }
                return total
            },
            
        }

    })
</script>

</html>

img

v-model進階用法(也是修飾符)

修飾符 說明
v-model.trim 同JavaScript語法,它用於自動過濾使用者輸入的首尾空格。
v-model.lazy 將輸入事件從預設的 input 事件改為 change 事件。即輸入框的值不會實時更新到資料,而是在失去焦點或按下Enter鍵時才會更新到繫結的資料中。
v-model.number 如果是按數字開頭,保留全部數字,放棄英文字元。如果是英文開頭,都保留。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        span {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <div id="app">
        <h3>常規寫法(未使用lazy)</h3>
        <input type="text" v-model="t0"> -- <span>{{t0}}</span>

        <h3>演示v-mode.lazy</h3>
        <input type="text" v-model.lazy="t1"> -- <span>{{t1}}</span>

        <h3>演示v-mode.trim</h3>
        <input type="text" v-model.trim="t2"> -- <span>{{t2}}</span>

        <h3>演示v-mode.number</h3>
        <input type="text" v-model.number="t3"> -- <span>{{t3}}</span>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            t0: "",
            t1: "",
            t2: "",
            t3: ""
        }
    })
</script>
</html>

img

vue與Ajax

# 1 後端---》提供介面--》json形式--》給前端--》前端拿到再做處理
	-後端介面
    -ajax 傳送請求
    
# 2 vue中使用ajax
	-1 jquery的ajax
    -2 js原生的fetch
    	-XMLHTTPRequest--》需要做瀏覽器相容
        -fetch方案
    -3 第三方axios(最多)
    
    
# 3 寫個後端介面--》django----》flask簡單


# 4 前後端互動---》跨越問題---》後端處理
	-Access-Control-Allow-Origin

因為後續用的最多的是fetch和axios,所以只列出這兩種。

之前的部落格:https://www.cnblogs.com/ccsvip/p/18090680

網友的文章:https://developer.baidu.com/article/details/2766440

解決跨域

// 響應頭中新增,服務端設定 'Access-Control-Allow-Origin' = "*"

fetch傳送Ajax請求

在第一個 .then 中,應該返回 response.json(),以便將其傳遞給下一個 .then

此外,在第二個 .then 中,應該接收到 data 引數,而不是直接從 response 物件中獲取資料。

# 後端程式碼
from flask import Flask, jsonify, make_response


app = Flask(__name__)

@app.route("/")
def index():
    data = {"name": "小滿", "age": 3}
    response = make_response(jsonify(data))
    # 解決跨域用的
    response.headers['Access-Control-Allow-Origin'] = "*"    
    return response

if __name__ == "__main__":
    app.run(debug=True)
<script>
    // 複雜的寫法
    fetch("http://127.0.0.1:5000/")
        .then(function(response){
            return response.json()
        }).then(
            function(data){
                console.log(data);
            }
        ).catch(function(error){
            console.log(["Error", error]);
        })
</script>


<script>
    // 透過fetch傳送Ajax請求 簡單的寫法
    fetch("http://127.0.0.1:5000/")
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(error => console.log(['Error', error]))
</script>

image-20240426203231069

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="app">
        <button @click="loadData">獲取個人資訊</button>
        <p>姓名:{{name}}</p>
        <p>年齡:{{age}}</p>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: "",
            age: ""
        },
        methods: {
            loadData(){
                fetch("http://127.0.0.1:5000/")
                .then(response => response.json())
                .then((data)=>{
                    this.name = data.name
                    this.age = data.age
                })
                .catch(error => console.log(['Error', error]))
            }
        },
    })

</script>
</html>

axios傳送Ajax請求

<script>
    // 透過axios傳送請求
    axios.get("http://127.0.0.1:5000/")
        .then((response)=>{
        // 資料從 response.data 中獲取
        data = response.data
        console.log(data);
    })
        .catch(error => console.log(["Error", error]))
</script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
</head>
<body>
    <div id="app">
        <button @click="loadData">檢視個人資訊</button>
        <p>姓名:{{name}}</p>
        <p>年齡:{{age}}</p>
        <p>愛好:{{hobby}}</p>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: "",
            age: "",
            hobby: ""
        },
        methods: {
            loadData(){
                axios.get("http://127.0.0.1:5000/")
                .then((response)=>{
                    data = response.data
                    this.name = data.name
                    this.age = data.age
                    this.hobby = data.hobby
                })
                .catch(error => alert('發生了一些錯誤', error))
            }
        },

    })
</script>
</html>

透過axios傳送Ajax請求介面案例(獲取電影資料)

# 後端
import json
from flask import Flask, jsonify, make_response


app = Flask(__name__)

with open("./movies.json", "rt", encoding="utf-8") as file:
    data = json.load(file)

@app.route("/")
def index():
    response = make_response(jsonify(data))
    # 解決跨域問題
    response.headers['Access-Control-Allow-Origin'] = "*"    
    return response

if __name__ == "__main__":
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
    <style>
        ul {
            list-style: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="loadFilm">載入電影資料</button>
        <ul v-for="item in films">
            <li>名稱:{{item.name}}</li>
            <li>型別:{{item.category}}</li>
            <li>簡介:{{item.synopsis}}</li>
            <li>導演:{{item.director}}</li>
            <li>評分:{{item.grade}}</li>
            <li>地址:{{item.nation}}</li>
            <li><img :src="item.poster" width="100"></li>
            <hr>
        </ul>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            films: null
        },
        methods: {
            loadFilm(){
                let url = "http://127.0.0.1:5000/"
                axios.get(url).then((response)=>{
                    let dataObj = response.data.result
                    let filmArr = []
                    for (const item of dataObj) {
                        let filmData = {
                            name: item.name,
                            synopsis: item.synopsis,
                            director: item.director,
                            nation: item.nation,
                            poster:item.poster,
                            grade: item.grade,
                            category: item.category
                        }
                        filmArr.push(filmData)
                    }
                    this.films = filmArr
                })
            }
        },
        computed: {
            
        }
    })
</script>
</html>

img

排序問題

如果要排序,是前端傳送排序請求給後端,後端去完成排序請求,然後拿到資料渲染到頁面,而不是前端去完成排序。(雖然前端也可以)

監聽屬性

監聽住一個屬性,只要這個屬性發生變化,就執行函式.

這種自動更新是透過Vue.js的響應式系統實現的,它會追蹤每個屬性的變化,並在屬性值發生變化時,自動更新相關的檢視。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
    <style>
        .box {
            display: flex;
            justify-content: center;
        }

        .box-course {
            width: 200px;
            height: 50px;
            background-color: tomato;
            text-align: center;
            line-height: 50px;
            margin: 10px;
            border: 2px solid yellow;
            outline: 2px solid black;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="box">
            <!-- 我這裡使用的是滑鼠滑動事件 mousemove  你也可以使用click點選事件 -->
            <div @mousemove="courseType='Python'" class="box-course">Python</div>
            <div @mousemove="courseType='JavaScript'" class="box-course">JavaScript</div>
            <div @mousemove="courseType='Dart'" class="box-course">Dart</div>
        </div>

        <p>選中的課程是:<span :style="{color:'red'}">{{content}}</span></p>
    </div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            courseType: "",
            content: ""
        },
        watch: {
            // 可以放兩個引數,第一個是老引數,第二個是新引數
            // 列印的時候,新引數在前面
            courseType(oldvalue, newValue){
                this.content = this.courseType 
                console.log(oldvalue, newValue);
            }
        }
    })
</script>
</html>

img

元件的使用

# 元件就是:擴充套件 HTML 元素,封裝可重用的程式碼,目的是複用
    例如:有一個輪播圖,可以在很多頁面中使用,一個輪播有js,css,html
    元件把js,css,html放到一起,有邏輯,有樣式,有html
    
    
# 區域性元件和全域性元件
	-區域性元件:只能在當前頁面中使用
    -全域性元件:全域性都可以用
    
    
# 定義全域性元件

全域性元件 component

全域性元件是指在Vue應用程式中註冊的元件,可以在應用程式的任何地方使用。這意味著一旦註冊了全域性元件,它就可以在整個應用程式範圍內的任何Vue例項中使用,而不需要在每個例項中單獨註冊或匯入。這樣可以使元件在整個應用程式中變得可用,提高了元件的複用性和可維護性。

注意:元件也需要放在根元件管理的DOM中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
</head>
<body>
    <div id="app">
        
    <h2>元件首頁</h2>
    <hr>
    <!-- 這個Child 就是我們自己定義的全域性元件 -->    
    <Child></Child>
    <hr>
        
    </div>
</body>
<script>
    // 定義全域性元件 Vue.component
    // 給元件起一個名字 就是第一個引數
    Vue.component("Child",{
        // 第二個引數是一個物件
        // 物件裡面必須包含幾個東西 1. template 2.data  3. methods
        // template 放HTML內容,這裡只做一個簡單的演示,後續寫入到檔案的vue後直接引用就行了。  這裡的template和根元件的el是一個意思
        // 這個元件有自己的HTML內容
        template: `<div>
                        <button @click="handleClick">{{name}}</button>
                    </div>`,
                
        // data就是之前的data,只不過並不是是直接放一個物件,而是放一個函式,返回一個物件
        data(){
            return {
                name: "小滿"
            }
        },
        methods: {
            handleClick(){
                alert(this.name)
            }
        }

    })
    let vm = new Vue({
        el: "#app",

    })
</script>
</html>

生命週期鉤子

無論是自己定義的元件,還是vue例項,都會有這幾個生命週期鉤子。

函式 呼叫時間 其他說明
beforeCreate vue例項初始化之前呼叫
created vue例項初始化之後呼叫 這裡常用於跟後端互動,因為元件已經渲染完成了,因為這個時候變數已經有了,就傳送Ajax請求載入資料,然後給變數後續處理。
beforeMount 掛載到DOM樹之前呼叫
mounted 掛載到DOM樹之後呼叫
beforeUpdate 資料更新之前呼叫
updated 資料更新之後呼叫
beforeDestroy vue例項銷燬之前呼叫 這個用的也比較多,比如元件建立後建立一個定時器,元件銷燬之前清除定時器。
destroyed vue例項銷燬之後呼叫

生命週期鉤子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
</head>
<body>
    <!-- <div id="app">
        <h2>元件的使用</h2>
        <button @click="handleShow">顯示/隱藏元件</button>
        <hr>
        <child v-if="isShow"></child>
        <hr>
    </div> -->

    <div id="app">
        <h2>元件的使用</h2>
        <button @click="handleShow">顯示/隱藏元件</button>
        <hr>
        <child v-if="isShow"></child>
        <hr>
    </div>
    
</body>
<script>
    let baseAssembly = {
        template: `<div>
                        <button @click="clickEvent">{{title}}</button>
                    </div>`,
        data(){
            return {
                title: "點我",
                name: '小滿'
            }
        },
        methods: {
            clickEvent(){
                this.title = "看到大喬了嗎?"
                alert("小滿三歲啦!")
            }
        },
        // 載入之前
        beforeCreate() {
            console.log('beforeCreate');  // beforeCreate
            console.log(this.name);  // undefined  因為是建立之前,所以還拿不到資料
            console.log(this.$el)  // undefined  注意取模板需要透過 $el去取
        },
        // 
        created() {
            console.log('created');  // created
            console.log(this.name);  // 小滿
            console.log(this.$el)  // undefined  
        },

        // 掛載之前
        beforeMount() {
            console.log('beforeMount');  // beforeMount
            console.log(this.name);  // 小滿
            console.log(this.$el)  // 有資料了,就是body中自己定義的DOM   
        },

        mounted() {
            console.log('mounted');  // mounted
            console.log(this.name);  // 小滿
            console.log(this.$el)  // 有資料了,就是body中自己定義的DOM   
        },

        // 資料發生變化才會執行
        beforeUpdate() {
            console.log("beforeUpdate");
        },

        // 
        updated() {
            console.log("updated");
        },

        // 刪除之前
        beforeDestroy() {
            console.log("beforeDestroy");
        },

        // 刪除之後
        destroyed() {
            console.log("destroyed");
            console.log("元件已被銷燬");
        },
    }

    // 呼叫全域性元件,實際是變數的傳參
    Vue.component("child", baseAssembly)

    let vm = new Vue({
        el: "#app",
        data: {
            isShow: true
        },
        methods: {
            handleShow: function(){
                this.isShow = !this.isShow
            }
        }
    })
</script>
</html>

img

生命週期鉤子案例(啟動計時器,銷燬計時器)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
</head>

<body>
    <div id="app">
        <button @click="handleClick">銷燬元件</button>
        <child v-if="isShow"></child>
    </div>
</body>
<script>
    let baseAssembly = {
        template: `<div>
                        <p>{{title}}</p>
                    </div>`,
        data() {
            return {
                timer: null,
                title: "一切都是最好的安排"
            }
        },
        created() {
            this.timer = setInterval(function () {
                console.log("小滿最棒啦!");
            }, 1000)
        },
        beforeDestroy() {
            clearInterval(this.timer)
            this.timer = null

            console.log("計時器已被銷燬!");
        },
    }

    Vue.component("child", baseAssembly)

    // 根元件
    let vm = new Vue({
        el: "#app",
        data: {
            isShow: true
        },
        methods: {
            handleClick(){
                this.isShow = !this.isShow
                
            }
        },


    })
</script>

</html>

img

相關文章