【Vue.js 2.6】Vue.js的初體驗

Vue (讀音 /vjuː/,類似於 view)是一套用於構建用戶界面的漸進式框架,它是由尤雨溪開發的。Vue與其它大型框架(AngularReact )不同的是,Vue被設計為可以自底向上逐層應用。Vue的核心庫只關注視圖層,不僅易於上手,還便於與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue也完全能夠為複雜的單頁應用提供驅動。至於為什麼會去選擇VUE呢?其一是它很輕量,其二是因為我的英文很弱啊。

Vue.js的初體驗

資料連動 (v-model)

  • Vue.js是Reactive的,資料跟畫面綁定後,我們只要關心資料的變化,下面就是一個很簡單的例子。
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <script src='https://unpkg.com/vue'></script>
    <title>VUE.js</title>
</head>
<body>

<div id='app'>
    <h2>{{ value }}</h2>
    <input type="text" v-model='value'>
</div>

<script>
    const app = new Vue({
        el: '#app',
        data: {
            value: '我很愛VUE,VUE也愛我。'
        }
    })
</script>
</body>
</html>

迴圈 (v-for)

  • 個人以為程式最大的功能的就是做大量「重複」的事,所以迴圈的功能當然是一定要有的
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <script src='https://unpkg.com/vue'></script>
    <title>VUE.js</title>
</head>
<body>

<div id='app'>
    <ul>
        <li v-for='product in products'>
            {{ product }}
        </li>
    </ul>

</div>

<script>
const app = new Vue({
    el: '#app',
    data: {
        products: [
        'MacBook Pro 16吋 DDR4 1024GB',
        'Switch + 動物森友會',
        'PS5 + FF7 Remark',
        ]
    }
})
</script>
</body>
</html>

從Web取得資料 (API)

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

<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <script src='https://unpkg.com/vue'></script>
    <title>VUE.js</title>
</head>

<body>

    <div id='app'>
        <ul>
            <li v-for='agency in agencies'>
                {{ agency.o_tlc_agency_name }}
            </li>
        </ul>

    </div>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                agencies: [],
            },
            created () {
                fetch('https://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=24c9f8fe-88db-4a6e-895c-498fbc94df94&limit=3')
                    .then(response =>  { return response.json() })
                    .then(json => { this.agencies = json.result.results })
            }
        })
    </script>
</body>

</html>

可重複用組件 (Component)

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

<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <script src='https://unpkg.com/vue'></script>
    <title>VUE.js</title>
</head>

<body>

    <div id='app'>
        <prompt-component></prompt-component>
        <prompt-component></prompt-component>
        <prompt-component></prompt-component>
    </div>

    <script>
        Vue.component('prompt-component', {
            template: '<div><p>{{ message }}</p><button @click="sayHi">Say Hi!</button></div>',
            data: function () { return { message: 'Hello World!' }},
            methods: { sayHi: function () { alert('Hi') }}
        })
    </script>

<script>
    const app = new Vue({
        el: '#app',
    })
</script>
</body>

</html>

Vue.js的生命週期

生命週期流程圖

  • 這個就不用多做說明了吧,看圖說故事,大家可以試試就知道了。這裡比較要注意的是,如果要呼叫Vue裡面的function,要加上「$字號」,所以在變數命名的時候要注意一下。

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

<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <script src='https://unpkg.com/vue'></script>
    <title>VUE.js</title>
    <style>
        body {
            font-size: 1.5em
        }

        #app {
            margin-bottom: 1em
        }
    </style>
</head>

<body>
    <div id="app">
        <h1>{{ count }}</h1>
        <button @click="updateEvent">Update</button>
    </div>

    <button id="del">Del</button>

    <script>
        var app = new Vue({
            el: '#app',
            data: { count: 0, },
            methods: {
                updateEvent: function () { this.count += 1 },
            },
            beforeCreate: function () {
                console.log('元件實體剛被建立,屬性計算之前')
                console.log('beforeCreate - this.count: ', this.count)
                console.log('beforeCreate - this.$el: ', this.$el)
            },
            created: function () {
                console.log('元件實體已建立,屬性已綁定,但 DOM 還沒生成')
                console.log('created - this.count: ', this.count)
                console.log('created - this.$el: ', this.$el)
            },
            beforeMount: function () {
                console.log('模板 (template) 編譯或掛載至 HTML 之前')
                console.log('beforeMount - this.$el: ', this.$el)
            },
            mounted: function () {
                console.log('模板 (template) 編譯或掛載至 HTML 之後')
                console.log('mounted - this.$el: ', this.$el)
            },
            beforeUpdate: function () {
                console.log('元件被更新之前')
                console.log('beforeUpdate: ', this.$el.querySelector('h1').innerText, this.count)
            },
            updated: function () {
                console.log('元件被更新之後')
                console.log('updated: ', this.$el.querySelector('h1').innerText, this.count)
            },
            beforeDestroy: function () {
                console.log('移除 vue instance 之前');
                console.log('beforeDestroy');
            },
            destroyed: function () {
                console.log('移除 vue instance 之後')
                console.log('destroyed')
            },
        });

        document.getElementById('del').addEventListener('click', function () {
            app.$destroy()
        })

    </script>
</body>

</html>

beforeCreate() - init()?

  • 顧名思義就是「在建立之前 - new之前」,在這裡「變數跟DOM」都是「拿不到的」,所以呢在這裡基本上就是告訴你開始建立實體。

created() - viewDidLoad()?

  • 在這個階段就可以「拿到數值」了,但是「DOM還未生成」,不過想想這樣設計也對,DOM一出來就可以馬上把值放進去了,在這裡很適合用來「初始化數值」。

beforeMount() - viewWillAppear()?

  • 在這個時候DOM就跑出來了,但是…值還沒有被換掉,要改變長相就趕快。

mounted() - viewDidAppear()?

  • 這時候值就放入DOM之中了,可以看見{{count}}被換掉了。

beforeUpdate() - willSet()?

  • 看文字就可以知道,就是在「更新之前」的階段,數值已經計算好了,但是還沒有放到DOM中,在這裡可以「裝飾」一下數值。

updated() - didSet()?

  • 這裡就是把數值放到DOM中了。

beforeDestroy()

  • 這個就是要消失之前可以,趕快把要記錄的數值記一記。

destroyed() - deinit()?

  • 正式消失,不過正常不會手動去執行它啦。

後記

  • 果然是隔行如隔山啊,寫起來超沒效率的,不過比起以前一個一個慢慢Key的原生寫法好太多了,加油。