1. 程式人生 > >vue初始化、資料處理、元件傳參、路由傳參、全域性定義CSS與JS、元件生命週期

vue初始化、資料處理、元件傳參、路由傳參、全域性定義CSS與JS、元件生命週期

目錄

  • 專案初始化
  • 元件資料區域性化處理
    • 子元件
    • 父元件
    • 路由邏輯跳轉
      • 案例
  • 元件傳參
    • 父傳子
      • 子元件
      • 父元件
    • 子傳父
      • 子元件
      • 父元件
  • 元件的生命週期鉤子
  • 路由傳參
    • 第一種
      • 配置:router/index.js
      • 傳遞:GoodsBox.vue
      • 接收:GoodsDetail.py
    • 第二種
      • 配置:router/index.js
      • 傳遞:GoodsBox.vue
      • 接收:GoodsDetail.py
  • 全域性配置自定義css與js
    • global.css
    • settings.js
    • main.js
  • 小結

專案初始化

1.跟元件: App.vue

<template>
  <div id="app">
    <router-view />
  </div>
</template>

2.路由配置:router--index.js

只保留home主頁,刪除about頁,刪除views中About元件

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },

];

3.元件:views和components資料夾

1)刪除除Home.vue以外的所有元件

2)初始化Home.vue

<template>
  <div class="home">
    <h1>主頁</h1>
  </div>
</template>

3)刪除logo和HollWorld.vue

4)在assets中新建css、img、js三個資料夾

如果要修改頁面標籤圖示
    替換public資料夾下的favicon.ico圖片檔案

元件資料區域性化處理

"""
1)不管頁面元件還是小元件,都可能會被多次複用
2)複用元件的原因,其實就是複用元件的 頁面結構、頁面樣式、頁面邏輯
3)但是頁面上的資料需要區分(被複用的兩個元件資料多少是有區別的),所以元件的資料要做區域性化處理
4)藉助函式可以產生區域性作用域的特點,為每一次複用元件產生一個獨立的作用域
語法:
data () {
    return {
        // 資料們
    }
}
"""

子元件

<template>
    <div class="beat" @click="count += 1">
        {{ count }}下
    </div>
</template>

<script>
    export default {
        name: "Beat",
        // 不管是頁面元件還是小元件,都可能被複用,頁面結構與樣式都可以採用一套,但是資料一定要相互獨立
        data () {
            return {
                count: 0
            }
        }
    }
</script>

<style scoped>
    .beat {
        width: 100px;
        height: 100px;
        background-color: orange;
        text-align: center;
        line-height: 100px;
        border-radius: 50%;
    }
</style>

父元件

<template>
    <div class="home">
        <Beat/>
        <Beat/>
    </div>
</template>
<script>
    import Beat from '@/components/Beat'
    export default {
        components: {
            Beat,
        }
    }
</script>

路由邏輯跳轉

"""
1)很多時候,我們需要通過普通按鈕的邏輯,或是直接在某些邏輯中完成頁面的跳轉
2)可以通過在邏輯中用 this.$router.push() 來完成前往目標頁,兩種語法如下
    this.$router.push('路徑')
    this.$router.push({name: '路由名'})
3)在做移動端專案時,沒有像瀏覽器那樣的前進後臺鍵,頁可以用 this.$router.go() 來完成前進後退,語法如下
    前進後退:this.$router.go(正負整數),正式代表前進,負數代表後臺,數值就是步長
"""

案例

<template>
    <div class="home">
        <Nav/>
        <h1>主頁</h1>
        <button @click="goPage('/first')">前往第一頁</button>
        |
        <button @click="goPage('/second')">前往第二頁</button>
        |
        <button @click="goBack(-1)">後退一頁</button>
        |
        <button @click="goBack(-2)">後退二頁</button>
        |
        <button @click="goBack(1)">前進一頁</button>
    </div>
</template>

<script>
    import Nav from '@/components/Nav'

    export default {
        methods: {
            goPage(path) {
                // 可以通過 this.$router 完成邏輯跳轉
                this.$router.push();
            },
            goBack(num) {
                // 一般在移動端專案上運用
                this.$router.go(num);  
            }
        },
        components: {
            Nav,
        }
    }
</script>

元件傳參

父傳子

"""
一、元件傳參 - 父傳子
1)在子元件內部通過props設定元件的自定義屬性
    props: ['abc', 'goods']
2)在父元件渲染子元件是對自定義屬性賦值即可
    <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods"/>
"""

子元件

<template>
    <div class="goods-box">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
</template>

<script>
    export default {
        name: "GoodsBox",
        // 在元件內部通過props定義元件的自定義屬性
        props: ['abc', 'goods'],
    }
</script>

<style scoped>
    .goods-box {
        width: 260px;
        height: 300px;
        border: 1px solid black;
        border-radius: 5px;
        margin: 20px;
        float: left;
        overflow: hidden;
        text-align: center;
    }
    img {
        width: 260px;
        height: 260px;
    }
</style>

父元件

<template>
    <div class="goods">
        <div class="main">
            <!-- 在使用子元件是對自定義屬性賦值即可 -->
            <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods" />
        </div>
    </div>
</template>
<script>
    import GoodsBox from "../components/GoodsBox";

    let goods_list = [
        {
            img: require('@/assets/img/001.jpg'),
            title: '小貓',
        },
        {
            img: require('@/assets/img/002.jpg'),
            title: '小貓兒',
        },
        {
            img: require('@/assets/img/003.jpg'),
            title: '小狗',
        },
        {
            img: require('@/assets/img/004.jpg'),
            title: '小狗兒',
        },
    ];

    export default {
        name: "Goods",
        data () {
            return {
                goods_list,
            }
        },
        components: {
            GoodsBox,
        },
    }
</script>

子傳父

"""
二、元件傳參 - 子傳父
前提:子元件是被父元件渲染的,所以子元件渲染要晚於父元件
1)子元件一定要滿足一個條件,才能對父元件進行傳參(某個時間節點 === 某個被啟用的方法)
    eg:i)子元件剛剛載入成功,給父元件傳參 ii)子元件某一個按鈕被點選的時刻,給父元件傳參 iii)子元件要被銷燬了,給父元件傳參

2)在子元件滿足條件啟用子元件的方法中,對父元件發生一個通知,並將資料攜帶處理(自定義元件事件)
    <div class="goods-box" @click="boxClick"></div>
    methods: {
        boxClick () { this.$emit('receiveData', this.goods.title, '第二個資料', '第三個資料') }
    }

3)在父元件渲染子元件時,為自定義事件繫結方法
    <GoodsBox @receiveData="recFn"/>

4)在父元件實現繫結方法時,就可以拿到子元件傳參的內容(接收到了通知並在父元件中相應)
    recFn(title, data2, data3) {
        console.log('接收到了' + title);
    }

元件標籤不能繫結系統定義的事件,沒有意義,子元件的事件都是在自己內部完成
"""

子元件

<template>
    <div class="goods-box" @click="boxClick">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
</template>

<script>
    export default {
        props: ['abc', 'goods'],
        methods: {
            boxClick () {
                // 通知父級 - 自定義元件的事件
                this.$emit('receiveData', this.goods.title)
            }
        }
    }
</script>

父元件

<template>
    <div class="goods">
        <div class="main">
            <!-- 實現自定義事件,接收子元件通知的引數 -->
            <GoodsBox v-for="goods in goods_list" @receiveData="recFn"/>
        </div>
    </div>
</template>
<script>
    import GoodsBox from "../components/GoodsBox";
    export default {
        name: "Goods",
        data () {
            return {
                goodsTitle: '哪個',
            }
        },
        methods: {
            recFn(title) {
                console.log('接收到了' + title);
                this.goodsTitle = title;
            }
        },
        components: {
            GoodsBox,
        },
    }
</script>

元件的生命週期鉤子

"""
一、元件的生命週期:一個元件從建立到銷燬的整個過程
二、生命週期鉤子:在一個元件生命週期中,會有很多特殊的時間節點,且往往會在特定的時間節點完成一定的邏輯,特殊的事件節點可以繫結鉤子
注:鉤子 - 提前為某個事件繫結方法,當滿足這個事件啟用條件時,方法就會被呼叫 | 滿足特點條件被回撥的繫結方法就稱之為鉤子
"""
<template>
    <div class="goods">
        <Nav />
    </div>
</template>
<script>
    import Nav from "../components/Nav";
    export default {
        name: "Goods",
        components: {
            Nav,
        },
        beforeCreate() {
            console.log('該元件要被載入了')
        },
        created() {
            console.log('該元件要被載入成功了')
        },
        updated() {
            console.log('資料更新了')
        },
        destroyed() {
            console.log('該元件銷燬了')
        }
    }
</script>

路由傳參

"""
路由傳參:
一、通過url正則傳遞資料
i)設定
    路由: path: '/goods/detail/:pk'   |   '/goods/:pk/detail/:xyz'
    請求: '/goods/detail/任意字元'    |    '/goods/任意字元/detail/任意字元'
ii)如何傳
    <router-link :to="`/goods/detail/${pk}`"></router-link>
    this.$router.push(`/goods/detail/${pk}`)

iii)如何取
    this.$route物件是管理路由引數的,傳遞的引數會在this.$route.params字典中
    this.$route.params.pk

二、通過url引數傳遞資料
i)設定
    路由: path: '/goods/detail'
    請求: '/goods/detail?pk=資料'
ii)如何傳
    <router-link :to="`/goods/detail?pk=${pk}`"></router-link>
    <router-link :to="{name:'GoodsDetail', query:{pk: pk}}"></router-link>

    this.$router.push(`/goods/detail?pk=${pk}`)
    this.$router.push({name:'GoodsDetail', query:{pk: pk}})

iii)如何取
    this.$route物件是管理路由引數的,傳遞的引數會在this.$route.query字典中
    this.$route.query.pk
"""

第一種

配置:router/index.js

const routes = [
    {
        path: '/goods/detail/:pk',
        name: 'GoodsDetail',
        component: GoodsDetail
    },
]

傳遞:GoodsBox.vue

<router-link class="goods-box" :to="`/goods/detail/${goods.pk}`">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</router-link>

<!------------------- 或者 ------------------->

<div class="goods-box" @click="goDetail(goods.pk)">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</div>
<script>
    export default {
        name: "GoodsBox",
        methods: {
            goDetail (pk) {
                this.$router.push(`/goods/detail/${pk}`);
            }
        }
    }
</script>

接收:GoodsDetail.py

<script>
    export default {
        name: "GoodsDetail",
        data () {
            return {
                pk: '未知',
            }
        },
        // 通常都是在鉤子中獲取路由傳遞的引數
        created() {
            this.pk = this.$route.params.pk || this.$route.query.pk;
        }
    }
</script>

第二種

配置:router/index.js

const routes = [
    {
        path: '/goods/detail',
        name: 'GoodsDetail',
        component: GoodsDetail
    },
]

傳遞:GoodsBox.vue

<router-link class="goods-box" :to="`/goods/detail?pk=${goods.pk}`">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</router-link>

<!------------------- 或者 ------------------->

<div class="goods-box" @click="goDetail(goods.pk)">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</div>
<script>
    export default {
        name: "GoodsBox",
        methods: {
            goDetail (pk) {
                // this.$router.push(`/goods/detail?pk=${goods.pk}`);
                
                // 或者
                this.$router.push({
                    name: 'GoodsDetail',
                    query: {
                        pk,
                    }
                });
            }
        }
    }
</script>

接收:GoodsDetail.py

<script>
    export default {
        name: "GoodsDetail",
        data () {
            return {
                pk: '未知',
            }
        },
        // 通常都是在鉤子中獲取路由傳遞的引數
        created() {
            this.pk = this.$route.params.pk || this.$route.query.pk;
        }
    }
</script>

全域性配置自定義css與js

global.css

html, body {
    margin: 0;
}

a {
    color: black;
    text-decoration: none;
}

ul {
    margin: 0;
    padding: 0;
}

settings.js

export default {
    base_url: 'https://127.0.0.1:8000'
}

main.js

//1) 配置全域性css
import '@/assets/css/global.css'
// import global_css from '@/assets/css/global.css'  // 資源需要用變數儲存,方便以後使用
// require('@/assets/css/global.css')
// let global_css = require('@/assets/css/global.css')  // 資源需要用變數儲存,方便以後使用


// 2) 配置自定義js設定檔案
import settings from '@/assets/js/settings.js'
Vue.prototype.$settings = settings;
// 在任何一個元件中的邏輯,可以通過 this.$settings訪問settings.js檔案的{}資料

小結

"""
專案:
    環境;node -> npm -> cnpm -> vue/cli
    建立:vue create proj
    配置:配置npm啟動項
    專案目錄結構:依賴、環境、入口、核心程式碼們
    
元件:
    構成:template + script + style
    匯入:import 別名 from '路徑'
    父加子:1)匯入 2)註冊 3)使用
    元件資料:元件化處理 data(){ return {} }
    傳參:父傳子 - 自定義元件屬性  |  子傳父 - 自定義元件事件
    生命週期鉤子:created() { //完成後臺請求等 }

路由:
    根元件中的頁面佔位:<router-view />
    導航欄中的頁面跳轉:<router-link to=""></router-link>
    程式碼中的邏輯跳轉:this.$router.push() | this.$router.go()
    路由傳參:兩種方式
    兩個路由物件:
        this.$router - 控制路由跳轉
        this.$route - 控制路由資料
"""