一、元件
1、什麼是元件
在Vue.js中,元件是構建使用者介面的可重用和獨立的模組。每個Vue元件都封裝了自己的模板、邏輯和樣式,使得程式碼可以更加模組化、可維護性更高。透過元件化,你可以將介面拆分成獨立的、可複用的部分,每個部分都有自己的功能和樣式,這樣可以更容易地管理複雜的介面,並且提高了程式碼的可讀性和可維護性。
通俗來說,元件就是把一個很大的介面拆分為多個小的介面, 每一個小的介面就是一個元件,將大介面拆分成小介面就是元件化。而元件化開發指的就是根據封裝的思想,把頁面上可重用的 UI 結構封裝為元件,從而方便專案的開發和維護。
2、元件的分類
- 按作用範圍分類
- 全域性元件:專案中所有地方都可以的元件稱為全域性元件
- 區域性元件(私有元件):僅有該元件才能使用的元件稱為區域性元件
- 按照用途來分
- 頁面元件
- 自定義元件
工程化開發之後:1個元件 就是1個xx.vue
。 在vue 中規定:元件的字尾名是 .vue。之前接觸到的 App.vue 檔案本質上就是一個 vue 的元件。
以CSDN為例,如果使用元件化開發的話:
3、元件的內容
在Vue中,一個元件可以包括以下內容:
-
模板(Template):定義了元件的結構和佈局,使用HTML和Vue的模板語法來描述介面的外觀。
-
指令碼(Script):包含了元件的邏輯,例如資料處理、事件處理、生命週期鉤子等。通常使用JavaScript或TypeScript編寫。
-
樣式(Style):定義了元件的樣式,可以使用CSS、Sass、Less等來編寫。
透過元件,你可以將頁面劃分成多個獨立的部分,每個部分都有自己的功能和樣式,並且可以在需要的地方進行重複使用。其中,每個元件中必須包含 template 模板結構,而 script 行為和 style 樣式是可選的組成部分。
(1)template
- 當前元件的DOM結構,需要定義到template標籤的內部
template:`
<div>
<h1>{{ message }}</h1>
<button @click="changeMessage">Change Message</button>
</div>
`
注意:
- template 是 vue 提供的容器標籤,只起到包裹性質的作用,它不會被渲染為真正的 DOM 元素,後面的 v-slot 會使用到這個標籤
- template 中只能包含唯一的根節點
(2)script
- 之後與元件相關的data資料、methods方法等,都需要定義到export default所匯出的物件中
data() {
return {
message: 'Hello, Vue!'
};
},
methods: {
changeMessage() {
this.message = 'Hello, World!';
}
}
注意:
.vue 元件中的 data 必須是函式
vue 規定:.vue 元件中的 data 必須是一個函式,不能直接指向一個資料物件。
因此在元件中定義 data 資料節點時,下面的方式是錯誤的,但是在根元件這樣寫是可以的
data:{ count:0 }
(3)style
- 還是按照css的語法來寫就好
<style>
h1 {
color: blue;
}
</style>
總的來說,Vue元件是Vue.js框架中用於構建使用者介面的獨立模組,它們可以被組合和巢狀,從而構建出複雜的介面。
二、元件使用
1、全域性元件
全域性元件是在Vue應用程式中全域性註冊的元件,可以在應用的任何地方使用。一旦註冊為全域性元件,它就可以在整個應用程式中的任何Vue例項的模板中使用。
(1)註冊全域性元件
在Vue中,你可以使用Vue.component
方法來註冊全域性元件。例如:
// 全域性註冊一個名為 'my-component' 的元件
Vue.component('my-component', {
// ... 元件的選項
})
(2)使用全域性元件
一旦註冊為全域性元件,你可以在任何Vue例項的模板中使用它:
<template>
<div>
<my-component></my-component>
</div>
</template>
(3)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>全域性元件的使用</h1>
<button @click="handleClick">點我</button>
<hr>
<xiao></xiao>
<hr>
<h1>我是全域性元件</h1>
<xiao></xiao>
</div>
</body>
<script>
// 1、定義全域性元件
Vue.component('xiao', {
template: `<div>
<h1>{{ name }}</h1>
<button @click="handleClick">點我換名字</button>
</div>`,
data() {
return {
name: 'xiao'
}
},
methods: {
handleClick() {
this.name = '彭于晏'
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
}
})
</script>
</html>
2、區域性元件
區域性元件是在Vue例項(或者其他元件)的元件選項中註冊的元件。它只能在註冊它的例項或者元件內部使用。
(1)註冊區域性元件
在Vue例項或者其他元件中,你可以透過components
選項來註冊區域性元件。例如:
<template>
<div>
<my-local-component></my-local-component>
</div>
</template>
<script>
// 透過ES6的import將自定義的元件引入進來
import MyLocalComponent from './MyLocalComponent.vue';
export default {
// 註冊元件
components: {
'my-local-component': MyLocalComponent
}
}
</script>
(2)使用區域性元件
一旦在例項或者元件中註冊了區域性元件,你可以在該例項或者元件的模板中使用它:
<template>
<div>
<my-local-component></my-local-component>
</div>
</template>
(3)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>區域性元件的使用</h1>
<button @click="handleClick">點我</button>
<hr>
<xiao></xiao>
</div>
</body>
<script>
var xiao = {
template: `
<div>
<h2>我是區域性元件</h2>
</div>
`,
data() {
return {}
},
methods: {}
}
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
},
components: {
xiao:xiao
}
})
</script>
</html>
3、全域性和區域性混合使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>區域性元件的使用</h1>
<button @click="handleClick">點我</button>
<hr>
<child></child>
</div>
</body>
<script>
var xiao = {
template: `
<div>
<h2>我是區域性元件</h2>
</div>
`,
data() {
return {}
},
methods: {}
}
// 全域性元件
Vue.component('child', {
template: `
<div>
<h1>我是全域性元件</h1>
<xiao></xiao>
<xiao></xiao>
<xiao></xiao>
</div>
`,
// 區域性元件
components: {
// 第一種方法
// xiao: {
// template: `
// <div>
// <h2>我是區域性元件</h2>
// </div>
// `,
// data() {
// return {}
// },
// methods: {}
// }
// 第二種方法
xiao
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
},
components: {
xiao
}
})
</script>
</html>
4、總結
- 全域性元件可以在整個應用程式中的任何地方使用,而區域性元件只能在註冊它的例項或者元件內部使用。
- 全域性元件適合用於在整個應用中頻繁使用的通用元件,而區域性元件適合用於特定頁面或者元件內部的元件。
- 全域性元件的註冊是透過
Vue.component
方法進行,而區域性元件的註冊是透過元件選項中的components
屬性進行。 - 注意:元件中的資料,事件在沒有額外引數的影響下都是獨立的
瞭解elementui:
- Element UI是一個基於Vue.js的元件庫,提供了豐富的UI元件,如按鈕、表格、彈窗等,可以幫助開發者快速構建美觀、功能完善的前端介面。
- 使用Element UI不僅可以減少開發工作量,而且它的元件都經過最佳化和測試,在效能和使用者體驗方面表現較好。
- 透過引入Element UI的全域性元件,開發者可以更加高效地開發出具有一致風格的介面。
三、元件間通訊
1、父子通訊之父傳子-自定義屬性
(1)父元件向子元件通訊的步驟
- 在父元件中定義變數
data: {
'url': './img/a.jpg'
}
- 把變數傳遞個子元件 ==> 自定義屬性:myurl
<Child1 :myurl="url"></Child1>
- 在子元件中,拿到屬性
props:['myurl']
- 以後在子元件中使用父元件的屬性
this.myurl
(2)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>元件間通訊之父傳子:自定義屬性</h1>
<h2>父元件中的名字{{myname}}</h2>
<div style="background-color: pink">
<child :name="myname" yy="xx"></child>
</div>
</div>
</body>
<script>
// 全域性元件
Vue.component('child', {
template: `
<div>
<h2>我是child元件</h2>
<h3>父元件傳遞給子元件的{{ name }}---{{ yy }}</h3>
</div>`,
data() {
return {}
},
props: ['name', 'yy']
})
var vm = new Vue({
el: '#app',
data: {
myname: '彭于晏'
},
})
</script>
</html>
執行結果:
2、父子通訊之子傳父---自定義事件
(1)子元件向父元件通訊的步驟
- 在父元件中定義變數,用來接收子元件傳入的變數
data: {
text:''
},
- 在父元件使用子元件時候,自定義事件 myevent,名字隨便取
<Child1 @myevent="handleMyEvent"></Child1>
- 在父元件中定義函式,跟自定義事件繫結
handleMyEvent(childText){
this.text=childText
}
- 在子元件中 ==> 觸發自定義事件執行
this.$emit('自定義事件名字',this.mytext)
(2)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>元件間通訊之子傳父:自定義事件</h1>
<h2>我是父元件</h2>
子元件傳給父元件的值===> {{p_name}}
<hr>
<div style="background-color:pink">
<child @myevent="handleEvent"></child>
</div>
</div>
</body>
<script>
// 全域性元件
Vue.component('child', {
template: `
<div>
<h2>我是child元件</h2>
<input type="text" v-model="name">--> {{name}}
<button @click="handleSend">傳給父</button>
</div>`,
data() {
return {
name:''
}
},
methods:{
handleSend(){
this.$emit('myevent',this.name)
}
}
})
var vm = new Vue({
el: '#app',
data: {
p_name:''
},
methods: {
handleEvent(name){
// name 是子元件中呼叫this.$emit('myevent',this.name)傳過來的
this.p_name = name
}
},
})
</script>
</html>
執行結果:
3、ref屬性(父子通訊)
- ref 是個屬性, 如果在普通的DOM元素上,引用指向的就是該DOM元素;
- 如果在子元件上,引用的指向就是子元件例項,然後父元件就可以透過 ref 主動獲取子元件的屬性或者呼叫子元件的方法
(1)放在普通標籤上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h2>ref屬性放在普通標籤上</h2>
<input type="text" v-model="name" ref="myinput">
<img src="./img/2.jpg" alt="" ref="myimg">
<button @click="handleClick">點我執行程式碼</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
handleClick() {
console.log(this.$refs)
// 根據ref指定的名字,取出原生dom物件,然後就可以操作dom物件了
var i = this.$refs['myinput']
console.log(i)
i.value = "你好"
// 改圖片
var i = this.$refs['myimg']
i.src = './img/3.jpg'
}
}
})
</script>
</html>
(2)放在元件上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<div style="background-color: antiquewhite">
<h2>ref屬性放在元件上</h2>
<child ref="mychild"></child>
</div>
</div>
</body>
<script>
// 定義全域性元件
Vue.component('child', {
template: `
<div>
<img :src="url" alt="">
<button @click="handleClick('子元件傳入的')">點我彈窗</button>
</div>
`,
data() {
return {
url: './img/1.jpg'
}
},
methods: {
handleClick(name) {
alert(name)
}
},
})
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
handleClick() {
// 操作元件物件
var i = this.$refs['mychild']
console.log(i.url)
// 改圖片
i.url = './img/4.jpg'
// 改執行方法
i.handleClick('xiao')
// 子傳父
this.name = i.url
}
}
})
</script>
</html>
四、動態元件
1、概念
動態元件就是允許你根據當前的資料來動態地切換顯示不同的元件。
-
Vue內部提供的元件component元件作用是:實現動態的渲染元件,按需顯示元件。
-
component 標籤是 vue 內建的,作用:元件的佔位符
-
其中is 屬性的值,表示要渲染的元件的名字
-
is 屬性的值,應該是元件在 components 節點下的註冊名稱
2、完整示例
- 比如我們這裡有三個元件,需求:在app根元件中點選不同按鈕可以按需顯示元件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue.js"></script>
<style>
.item {
width: 150px;
height: 50px;
background-color: pink;
font-size: 25px;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
}
.top {
display: flex;
justify-content: center;
}
</style>
</head>
<body>
<div id="app">
<h1>動態元件</h1>
<div class="top">
<div class="item" @click="current='goods'">
<span>商品</span>
</div>
<div class="item" @click="current='order'">
<span>訂單</span>
</div>
<div class="item" @click="current='user'">
<span>使用者</span>
</div>
</div>
<div>
<!-- 不使用動態元件-->
<!-- <goods v-if="current=='goods'"></goods>-->
<!-- <order v-else-if="current=='order'"></order>-->
<!-- <user v-else></user>-->
<!-- 使用動態元件-->
<component :is="current"></component>
</div>
</div>
</body>
<script>
// 1 定義出 商品,訂單,使用者 三個元件
Vue.component('goods', {
template: `<div>
<h3>商品頁面</h3>
商品列表
<br>
商品列表
</div>`,
})
Vue.component('order', {
template: `<div>
<h3>訂單頁面</h3>
訂單內容
</div>`,
})
Vue.component('user', {
template: `<div>
<h3>使用者頁面</h3>
使用者資訊
</div>`,
})
var vm = new Vue({
el: '#app',
data: {
current: 'goods'
},
})
</script>
</html>
3、內部元件keep-alive元件的使用
-
keep-alive 會把內部的元件進行快取,而不是銷燬元件;
-
在使用 keep-alive 的時候,可以透過 include 指定哪些元件需要被快取;
-
或者,透過 exclude 屬性指定哪些元件不需要被快取;但是:不要同時使用 include 和 exclude 這兩個屬性
<keep-alive exclude="goods">
<component :is="current"></component>
</keep-alive>
五、插槽
1、介紹
slot的官方定義是用於元件內容分發,簡單通俗的解釋就是在元件化開發中,雖然元件是一樣的,但是在不同的使用場景,元件的某一部分需要有不同的內容顯示。slot就好比元件開發時定義的一個引數,如果不傳入值就當預設值使用,如果傳入了新值,在元件呼叫時就會替換定義時的slot預設值。
一般情況下,編寫完1個元件之後,元件的內容都是寫死的,需要加資料 只能去元件中修改,擴充套件性很差。然後就出現了插槽這個概念,只需在元件中新增<slot></slot>
,就可以在body的元件標籤中新增內容。
2、匿名插槽
- 匿名插槽插入不同的內容類似for迴圈一樣,使用插槽一次就要全部再來一遍,例如下面使用了兩個不同內容但是匿名插槽一樣,所以會有兩次完整的元件形成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>插槽使用</h1>
<div>
<Home style="background-color:greenyellow">
<div>
<img src="./img/1.jpg" alt="">
</div>
</Home>
</div>
<hr>
<div>
<Home style="background-color:orange">
<div>
<img src="./img/2.jpg" alt="">
</div>
</Home>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
who: 'Home'
},
components: {
Home: {
template: `<div>
<h3>我是首頁</h3>
<slot></slot>
<h3>結束了</h3>
</div>`
},
}
})
</script>
</html>
2、具名插槽
- 在使用相同的具名插槽的時候,並沒有再次形成完整的元件內容,而是將插槽裡面的內容直接放到元件中對應插槽的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>插槽使用</h1>
<div>
<Home style="background-color:greenyellow">
<div slot="middle">
<img src="./img/1.jpg" alt="">
</div>
<div slot="middle">
<img src="./img/1.jpg" alt="">
</div>
<div slot="bottom">
<a href="">點我看mm</a>
</div>
</Home>
</div>
<hr>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
who: 'Home'
},
components: {
Home: {
template: `<div>
<h3>我是首頁</h3>
<slot name="middle"></slot>
<h3>結束了</h3>
<slot name="bottom"></slot>
</div>`
},
}
})
</script>
</html>