vue元件化

_XinXinM_發表於2021-01-04

1、元件基礎
在這裡插入圖片描述
元件是可以複用的vue例項,帶有一個名字,我們可以在一個通過new vue建立的vue根例項中把這個元件作為自定義元素來使用。
元件化的作用是把應用程式中一些比較獨立的功能模組或者單元把他抽取出來,把它封裝成元件。像工程零件,搭積木的積木。能在開發後續程式的過程中維護、複用得到進一步的提升。
2.元件註冊、使用及資料傳遞
vue.component(name,options)可用於註冊元件。

<!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="vue.js"></script>
    <style>
        .active{
            background-color: #ddd;
        }
    </style>
</head>
<body>
    <!-- 宿主檔案 -->
    <!-- {{ mustache }}是一個動態的值 左右就用雙括號{{}}-->
    <!-- 插值文字 -->
    <!-- v-once執行一次性插值 之後值變了動態值不變 -->
    <div id= "app">
        <h2 :title="title">
            {{ title }}    
        </h2>
        <!-- 使用者輸入 -->
        <!-- 鍵盤按下事件v-on:keydown -->
        <p><input type="text" v-model = "course" v-on:keydown.enter = "addCourse">{{course}}</p>
        <button @click = "addCourse">新增</button>
        
        <!-- 列表渲染 --> 
        <!-- 被選中點選一個動態的類 沒有被選中類被移除掉-->
        <!-- transparent 沒有顏色透明色 -->
        <!-- 列表元件 -->
        <course-list :courses = "courses"></course-list>
        <!-- <div 
        v-for="c in courses" 
        :key="c"
        :style = "{backgroundColor: selectedCourse === c ? '#' : 'transparent'}"
        @click = "selectedCourse = c"> 
          {{ c }}
      </div> -->
    <script>
        // 課程列表元件
        // 元件命名建議取成羊肉串命名法,如果使用駝峰的方式將來在使用的時候很容易產生混淆
        // 因為最終在列表元件那裡使用的時候一般情況下是不區分大小寫的
        // 所以即使用了駝峰命名在下面也無法使用因為無法識別
        // 而且元件名在內部進行註冊的時候會對命名進行轉換,這樣會造成對使用過程造成混淆
        // 推薦元件在命名的時候就進行羊肉串命名法
        Vue.component('course-list',{
            data(){
                return{
                    selectedCourse:'',
                }
            },
            // props是一個屬性,接受老爹傳過來的一些屬性
            // 定義方式有兩種:一種是物件,一種是陣列
            // 如果屬性是這樣定義['courses'] ,那麼就是希望老爹傳過來的屬性名就叫courses
            // 將來在列表元件裡就可以通過this.courses來訪問傳進來的引數了
            // ['courses']這種方式對引數的校驗沒有好處,一般情況下用得更多的是物件形式
            // 會用key的方式去命名,然後用type對其型別進行約束
            props:{
                courses:{
                    type:Array,
                // 預設值為空陣列,這樣子對courses就會有提前的約束 
                    default:[]
                }
            },
            template:`
                <!-- 條件渲染 -->
                <!-- v-if 和 v-for最好不要放在一個標籤上他們有優先順序的不同會爭搶 -->
                <p v-if = "courses.length == 0 ">沒有任何課程資訊</p>
                <div class="course-list" v-else>
                    <div 
                        v-for="c in courses" 
                        :key="c"
                        :class = "{active: selectedCourse === c}"
                        @click = "selectedCourse = c"> 
                        {{ c }}
                    </div>
                </div>
                `
        })
        // 模擬非同步資料呼叫
        function getCourses(){
            return new Promise(resolve =>{
                setTimeout(() => {
                    resolve(['定風波','web高階'])
                })
            })
        }
        // 1.建立vue例項
        // 儲存vue例項
        const app = new Vue({
            // 交代宿主是誰
            el:"#app",
            data: {
                title: '課程:',
                course:"",
                
                // courses:[],
                courses:["黃帝內經","仲景心法","鍼灸","傷寒","金匱"],
                totalCount:0,
            },
            methods: {
                addCourse() {
                    // 1.新增course到陣列
                    this.courses.push(this.course)
                    // 2.清空course
                    this.course = ""

                }
            },
            // 非同步用async await
            // 建立鉤子 
            async created(){
                // created執行時刻,元件例項已建立,由於未掛載dom不存在
                const courses = await getCourses()
                this.courses = courses
            },
            // mounted獲取業務資料
            // mounted時間點更靠後,除了建立之後還做了掛載,獲取業務資料
            // 掛載的實際操作是將前面所有的渲染函 數執行之後將虛擬DOM轉換為真實DOM
            // 也就是在mounted中可以訪問到DOM元素了
            // 其實vue例項被建立,掛載,渲染函式執行虛擬DOM轉換為真實DOM都是很快的
            // 非同步資料獲取選擇mounted和created本質上沒有什麼差別
            // 不用以為看到created介面會比較早 沒有這個區別
            // 因為我們訪問資料所花銷的時間遠遠大於初始化掛載的時間,沒有什麼實質上的區別
            // mounted(){},
            
            // computed是值變化了返回值
            computed: {
                
                total() {
                    // 計算屬性是有快取性的,如果值沒有發生變化,則頁面不會重新渲染
                    return this.courses.length+'門'
                }
            },
            // watch 做某個值得監控,如果發生變化了則會執行這個函式做我想做的事情
            // watch是值變化了執行這個函式
            // 監控courses這個值的變化
            // watch如果不加特別宣告表示值變化之後才會執行,它一開始是不會執行的

            // 預設情況下watch初始化時不執行想要watch立即執行 immediate為true。立即執行一次
            // watch: {
            //     courses(newValue, oldValue) {
            //         this.totalCount = newValue.length +"門"
            //     }
            // },


            // 為了一開始就能執行要選帶選項的watch vwatcher-options
            watch: {
                data: {
                    immediate: true,//立即執行 一次
                    // deep是當監控的資料是很複雜的資料的時候才使用如果是很淺就不需要用到deep
                    // deep: true,
                    handler(newValue, oldValue) {
                        
                    }
                }
            },
        })
        
    </script>
</body>
</html>

在這裡插入圖片描述

相關文章