1. 程式人生 > 其它 >VueJS 基礎部分-元件化(2)

VueJS 基礎部分-元件化(2)

技術標籤:前端Vuejsvuevue.js

第一章 元件化

1.1 認識元件化

元件化就是將一個頁面拆分成一個個小的功能模組,每個功能模組完成屬於自己這部分獨立的功能,使得整個頁面的管理和維護變得非常容易

1.2 元件的基本使用過程

<div id="app">
    <!-- 3. 使用元件 -->
    <my-cpn></my-cpn>
    <my-cpn></my-cpn>
    <my-cpn></my-cpn>
</div>

<script
src="../js/vue.js">
</script> <script> // 1. 建立元件構造物件 const cpnC = Vue.extend({ template: ` <div> <h2>標題</h2> <p>內容:哈哈哈哈~~~~~</p> </div>`, }) // 2. 註冊元件 // Vue.component(`元件的標籤名`,cpnC) Vue.component
(`my-cpn`, cpnC) const app = new Vue({ el: '#app', })
</script>

1.3 全域性元件和區域性元件

全域性元件

// 註冊元件(全域性元件, 可以在多個Vue的例項下面使用)
Vue.component(`my-cpn`, cpnC)

區域性元件

const app2 = new Vue({
    el: '#app2',
    /* 1. 區域性元件 */
    components: {
        cpn: cpnC,
    },
})

1.4 父元件和子元件

const
childC = Vue.extend({ // 子元件 template: ` <div> <h2>I am son component</h2> <p>i has any money</p> </div> `, }) const parentC = Vue.extend({ // 父元件 template: ` <div> <h2>I am father component</h2> <p>I have many son</p> <child></child> </div> `, components: { /* 建立子元件 */ child: childC, }, }) const app = new Vue({ el: '#app', components: { parent: parentC, }, })

1.5 元件註冊的語法糖

// 全域性元件
Vue.component(`my-cpn`, {
    template: `
        <div>
          <h2>全域性元件</h2>
          <p>內容:哈哈哈哈~~~~~</p>
        </div>
      `,
})

// 區域性元件
const app = new Vue({
    el: '#app',
    data: {
        message: 'hello',
    },
    components: {
        cpn1: {
            template: `
            <div>
              <h2>區域性元件</h2>
              <p>內容:哈哈哈哈~~~~~</p>
            </div>
          `,
        },
    },
})

1.6 模板的分離寫法

  1. script(不常用)
<!-- 1. script標籤,型別必須是 text/x-template -->
<script type="text/x-template" id="cpn">
    <div>
      <h2>{{title}}</h2>
      <p>{{message}}</p>
    </div>
</script>

<script src="../js/vue.js"></script>
<script>
    Vue.component(`cpn`, {
        template: `#cpn`,
        data() {
            return {
                title: '全域性元件',
                message: '內容:我是全域性元件 哈哈哈哈~~~~~',
            }
        },
    })
    const app = new Vue({
        el: '#app',
        components: {
            cpn1: {
                template: `#cpn`,
            },
        },
    })
</script>
  1. template(如果內部的標籤大於 1 ,則需要有一個根 div 來包含內容)
<template id="cpn1">
    <div>
        <h2>區域性元件</h2>
        <p>內容:哈哈哈哈~~~~~</p>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn1: {
                template: `#cpn1`,
            },
        },
    })
</script>

1.7 資料的存放

  1. 子元件不能訪問父元件
  2. 子元件有自己的 data,而且必須是一個函式
Vue.component(`cpn`, {
      template: `#cpn1`,
      data() {
        return {
          counter: 0
        }
      }
  1. 為什麼是一個函式?

    目的:讓每一個控制元件獨立的存在,不發生多個繫結在一起

1.8 父子元件的通訊

父傳子 : props

/* v-bind 目前不支援駝峰,或者寫成 c-movies */
const cpn = {
    template: '#cpn',
    /* 1. 陣列形式 */
    // props: ['c-movies', 'c-message'],
    props: {
        /* 2. 型別限制 */
        // c-movies: Array,
        // c-message: String

        /* 3. 提供一些預設值(以及必傳值) */
        c-message: {
            type: String,
            default: '沒有資訊', // 沒有傳值時則顯示預設值
        },
        c-movies: {
            type: Array,
            default() {
                return ['沒有發現']
            },
            required: true, // 表示必須傳該陣列 否則報錯
        },
    },
    data() {
        return {}
    },
}

子傳父 : $emit

<!-- 父元件模板 -->
<div id="app">
    <!-- 父元件監聽子元件傳送的請求 -->
    <cpn @itemclick="cpnClick"></cpn>
</div>

<!-- 子元件模板 -->
<template id="cpn">
    <div>
        <button v-for="item in categories" @click="btnClick(item)">
            {{item.name}}
        </button>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    /* 子元件 */
    const cpn = {
      template: '#cpn',
      data() {
        return {
          categories: [
            {id: 'a1', name: '熱門推薦'},
            {id: 'a2', name: '手機數碼'},
            {id: 'a3', name: '家用家電'},
          ]
        }
      },
      methods: {
        btnClick(item) {
          // 發射事件: 自定義事件
          /* itemclick 表示事件的名稱 */
          this.$emit('itemclick', item){
            console.log();
          }
        }
      }
    }

    /* 父元件 */
    const app = new Vue({
      el: '#app',
      components: {
        cpn
      },
      methods: {
        cpnClick(item) {
          console.log(item);
        }
      }
    })
</script>

第二章 元件化開發

2.1 父子元件的訪問

  1. 父元件 訪問 子元件
  • $children (不常用)
<div id="app">
    <cpn></cpn>
    <button @click="btnClick">按鈕</button>
</div>

<template id="cpn">
    <div>我是子元件</div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        methods: {
            btnClick() {
                console.log(this.$children)
                this.$children[0].name
                for (let c of this.$children) {
                    console.log(c.name)
                }
            },
        },
        components: {
            cpn: {
                template: '#cpn',
                data() {
                    return {
                        name: '我是子元件的name',
                    }
                },
            },
        },
    })
</script>
  • $refs
<div id="app">
    <cpn ref="aaa"></cpn>
    <button @click="btnClick">按鈕</button>
</div>

<template id="cpn">
    <div>我是子元件</div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        methods: {
            btnClick() {
                console.log(this.$refs.aaa.name)
            },
        },
        components: {
            cpn: {
                template: '#cpn',
                data() {
                    return {
                        name: '我是子元件的name',
                    }
                },
            },
        },
    })
</script>
  1. 子元件 訪問 父元件 (不常用)
  • $parent <訪問父元件>
<div id="app">
    <cpn></cpn>
</div>

<template id="cpn">
    <div>
        <h3>我是子元件</h3>
        <button @click="btnClick">按鈕</button>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: '#cpn',
                methods: {
                    btnClick() {
                        // 訪問父元件
                        console.log(this.$parent)
                    },
                },
            },
        },
    })
</script>
  • $root <訪問根元件>
<div id="app">
    <cpn></cpn>
</div>

<template id="cpn">
    <div>
        <h3>我是子元件</h3>
        <button @click="btnClick">按鈕</button>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: '#cpn',
                methods: {
                    btnClick() {
                        // 訪問根元件 $root
                        console.log(this.$root)
                    },
                },
            },
        },
    })
</script>

2.2 插槽(slot)的使用

  • 基本使用
<div id="app">
    <!-- 1. 未設定插槽的標籤 -->
    <cpn></cpn>

    <!-- 2. 設定一個插槽的值 -->
    <cpn><i>我是i標籤</i></cpn>

    <!-- 3. 設定多個插槽的值 -->
    <cpn>
        <div>我是div標籤</div>
        <a>我是a標籤</a>
    </cpn>
</div>

<template id="cpn">
    <div>
        <h3>我是h3標籤</h3>
        <p>我是p標籤</p>
        <!-- slot 中設定預設標籤, 如果沒有替換的標籤, 顯示預設的標籤 -->
        <slot>
            <button>我是btn按鈕</button>
        </slot>
    </div>
</template>
  • 具名插槽
<div id="app">
    <!-- 定位替換 確定好插槽的名字 -->
    <cpn>
        <span slot="center">我是新的span標籤</span>
    </cpn>
</div>

<template id="cpn">
    <div>
        <!-- 寫入每個插槽的名字 -->
        <slot name="left"><span>左邊</span></slot>
        <slot name="center"><span>中間</span></slot>
        <slot name="right"><span>右邊</span></slot>
    </div>
</template>
  • 編譯的作用域
<div id="app">
    <!-- 1. 直接顯示 -->
    <cpn></cpn>

    <cpn>
        <!-- 2. 轉換顯示方式 -->
        <template slot-scope="slot">
            <p v-for="item in slot.data">{{item}} -</p>
            <p>{{slot.data.join(' - ')}}</p>
            <p>{{slot.data.join(' * ')}}</p>
        </template>
    </cpn>
</div>

<template id="cpn">
    <div>
        <slot :data="pLanguages">
            <ul>
                <li v-for="item in pLanguages">{{item}}</li>
            </ul>
        </slot>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: '#cpn',
                data() {
                    return {
                        pLanguages: [
                            'JavaScript',
                            'Python',
                            'C++',
                            'C#',
                            'Swift',
                        ],
                    }
                },
            },
        },
    })
</script>
  • 作用域插槽

第三章 前端模組化

3.1 為什麼使用模組化

  • 簡單寫 js 程式碼帶來的問題
  • 閉包引起程式碼不可複用
  • 自己實現了簡單的模組化
  • AMD/CMD/CommonJS

3.2 ES6 中模組化的使用

  • export (匯出)
// 1. CommonJS 模組化 匯出
module.export = {
    add,
    mul,
}

// 2. ES6 模組化 匯出
export const name = 'Tom'
export const age = 18
export const height = 1.88
  • import (匯入)
/* 1. CommonJs 模組化 匯入 */
const { add, mul } = require('./js/mathUtils.js')

/* 2. ES6 模組化匯入 */
import * as info from './js/info.js'

// 例外
/* 3. 依賴 檔案 匯入 */
require('./css/normal.css')