1. 程式人生 > 實用技巧 >專案初始化、元件資料區域性化處理、子元件、父元件、路由邏輯跳轉、元件傳參、元件的生命週期鉤子、路由傳、全域性配置自定義css與js、

專案初始化、元件資料區域性化處理、子元件、父元件、路由邏輯跳轉、元件傳參、元件的生命週期鉤子、路由傳、全域性配置自定義css與js、

```python
"""
1)路由:邏輯跳轉、路由傳參
2)專案元件的資料區域性化處理:data: {} => data: function(){ return {} } => data(){ return{} }
3)元件的宣告週期
4)元件間通訊
5)各種第三方外掛:vuex、axios、element-ui、(jq+bs)
"""
```

### 專案初始化

```python
"""
1)根元件:App.vue
<template>
<div id="app">
<router-view />
</div>
</template>

2)路由配置:router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
];

3)元件:views和components資料夾
i)刪除除Home.vue以為的所有元件
ii)初始化Home.vue
<template>
<div class="home">
</div>
</template>

4)分類管理資源:assets資料夾
建立img、css、js子資料夾,刪除原來的資源

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



### 元件資料區域性化處理

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

##### 子元件

```vue
<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;

text-align: center;
line-height: 100px;
border-radius: 50%;
}
</style>

```

##### 父元件

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



### 路由邏輯跳轉

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

##### 案例

```vue
<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>
```



### 元件傳參

#### 父傳子

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

##### 子元件

```vue
<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>
```

##### 父元件

```vue
<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>

```



#### 子傳父

```python
"""
二、元件傳參 - 子傳父
前提:子元件是被父元件渲染的,所以子元件渲染要晚於父元件
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);
}

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

##### 子元件

```vue
<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>
```

##### 父元件

```vue
<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>

```



### 元件的生命週期鉤子

```python
"""
一、元件的生命週期:一個元件從建立到銷燬的整個過程
二、生命週期鉤子:在一個元件生命週期中,會有很多特殊的時間節點,且往往會在特定的時間節點完成一定的邏輯,特殊的事件節點可以繫結鉤子
注:鉤子 - 提前為某個事件繫結方法,當滿足這個事件啟用條件時,方法就會被呼叫 | 滿足特點條件被回撥的繫結方法就稱之為鉤子
"""
```

```vue
<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>

```



### 路由傳參

```python
"""
路由傳參:
一、通過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

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

##### 傳遞:GoodsBox.vue

```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

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



#### 第二種

##### 配置:router/index.js

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

##### 傳遞:GoodsBox.vue

```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

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



### 全家配置自定義css與js

##### global.css

```css
html, body {
margin: 0;
}

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

ul {
margin: 0;
padding: 0;
}
```

##### settings.js

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

##### main.js

```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檔案的{}資料
```



## 小結

```python
"""
專案:
環境;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 - 控制路由資料
"""
```