從零開始學 Web 之 Vue.js(六)Vue的元件
大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......
- github:https://github.com/Daotin/Web
- 微信公眾號:Web前端之巔
- 部落格園:http://www.cnblogs.com/lvonve/
- CSDN:https://blog.csdn.net/lvonve/
在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧!
一、Vue元件
什麼是元件: 元件的出現,就是為了拆分 Vue 例項的程式碼量的,能夠讓我們以不同的元件,來劃分不同的功能模組,將來我們需要什麼樣的功能,就可以去呼叫對應的元件即可;
元件化和模組化的不同:
- 模組化: 是從程式碼邏輯的角度進行劃分的;方便程式碼分層開發,保證每個功能模組的職能單一;
- 元件化: 是從UI介面的角度進行劃分的;前端的元件化,方便UI元件的重用;
二、定義元件
1、定義全域性元件
定義全域性元件有三種方式:
1、使用 Vue.extend
配合 Vue.component
方法:
// 1.使用 Vue.extend 來建立全域性的Vue元件
var login = Vue.extend({
// 通過 template 屬性,指定了元件要展示的HTML結構
template: '<h1>登入</h1>'
});
// 2.使用 Vue.component('元件的名稱', 建立出來的元件模板物件)
Vue.component('login', login);
// 3.使用元件
<div id="app">
<!-- 如果要使用元件,直接,把元件的名稱,以 HTML 標籤的形式,引入到頁面中即可 -->
<login></login>
</div>
注意:
使用 Vue.component 定義全域性元件的時候,元件名稱使用了 駝峰命名(如myLogin),則在引用元件的時候,需要把 大寫的駝峰改為小寫的字母,同時在兩個單詞之前,使用 - 連結(
<my-login></my-login>
);如果不使用駝峰,則直接拿名稱來使用即可;
當然,上面兩步可以合成一個步驟完成:
Vue.component('login', Vue.extend({
template: '<h1>登入</h1>'
}));
2、直接使用 Vue.component 方法:
Vue.component('login', {
template: '<div><h3>註冊</h3><span>123</span></div>'
});
注意:不論是哪種方式建立出來的元件,元件的 template 屬性指向的模板內容,必須有且只能有唯一的一個根元素,否則會報錯。
3、將模板字串,定義到 template 標籤中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<!-- 3. 使用元件 -->
<mycom></mycom>
</div>
<!-- 2.在 被控制的 #box 外面,使用 template 元素,定義元件的HTML模板結構 -->
<template id="tmp1">
<!-- 還是需要遵從template 模板內容,必須有且只能有唯一的一個根元素 -->
<div>
<h3>登入</h3>
<p>p標籤</p>
</div>
</template>
<script>
// 1.定義元件
Vue.component('mycom', {
template: '#tmp1'
});
var vm = new Vue({
el: "#box",
data: {},
methods: {}
});
</script>
</body>
</html>
注意:
1、
template: '#tmp1'
是定義模板標籤的 id ,# 別忘寫了。2、被控制的 #box 外面,使用 template 標籤;
3、 template 標籤裡面,還是遵從只能有唯一的一個根元素的原則。
2、定義私有元件
定義私有元件,就是再VM例項中定義元件。
如下,box中可以使用,box2不可以使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<mycom></mycom>
</div>
<div id="box2">
<mycom></mycom>
</div>
<template id="temp">
<h3>自定義私有屬性</h3>
</template>
<script>
var vm = new Vue({
el: "#box",
data: {},
methods: {},
// 定義私有元件
components: {
mycom: {
template: '#temp'
}
}
});
var vm2 = new Vue({
el: "#box2",
data: {},
methods: {}
});
</script>
</body>
</html>
3、元件的data和methods屬性
元件中也可以有自己的data和methods屬性,可以傳入template中使用。
特點:
- data屬性為一個匿名函式,其返回值為一個物件。
- data 函式返回值為一個物件(最好是新開闢的物件,否則如果多次引用元件,不是新開闢的物件給的話,物件是同一份,而我們需要每一個元件有自己的物件),物件中可以放入資料。
- 元件中 的data和methods,使用方式,和例項中的 data 和methods使用方式完全一樣
<div id="box2">
<login></login>
</div>
<template id="temp2">
<div>
<input type="button" value="按鈕" @click="myclick">
<h3>自定義私有屬性</h3>
<p> {{msg}} </p>
</div>
</template>
<script>
Vue.component('login', {
template: '#temp2',
data: function () {
return {
msg: '這是元件中的data'
}
},
methods: {
myclick() {
console.log("點選按鈕");
}
}
});
</script>
三、元件切換
我們在登入註冊一個網站的時候,經常看到兩個按鈕,一個登入,一個註冊,如果你沒有賬號的話,需要先註冊才能登入。我們在點選登入和註冊的時候,網頁會相應的切換,登入頁面就是登陸元件,註冊頁面就是註冊元件,那麼點選登入和註冊,如何實現元件的切換呢?
1、方式一
使用flag
識別符號結合v-if
和v-else
切換元件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<!-- 給a註冊點選事件,切換flag狀態 -->
<a href="javascript:;" @click.prevent="flag=true">登入</a>
<a href="javascript:;" @click.prevent="flag=false">註冊</a>
<!-- 使用v-if v-else切換元件 -->
<login v-if="flag">
</login>
<register v-else="flag">
</register>
</div>
<script>
Vue.component('login', {
template: '<h3>登入元件</h3>'
});
Vue.component('register', {
template: '<h3>註冊元件</h3>'
});
var vm = new Vue({
el: "#box",
data: {
flag: true
},
methods: {}
});
</script>
</body>
</html>
缺陷:由於flag的值只有true和false,所以只能用於兩個元件間 的切換,當大於兩個元件的切換就不行了。
2、方式二
使用 component元素的:is
屬性來切換不同的子元件
使用 <component :is="componentId"></component>
來指定要切換的元件。
componentId:為需要顯示的元件名稱,為一個字串,可以使用變數指定。
componentId: 'login'
// 預設顯示登入元件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<!-- 給a註冊點選事件,切換flag狀態 -->
<a href="javascript:;" @click.prevent="componentId='login'">登入</a>
<a href="javascript:;" @click.prevent="componentId='register'">註冊</a>
<component :is="componentId"></component>
</div>
<script>
Vue.component('login', {
template: '<h3>登入元件</h3>'
});
Vue.component('register', {
template: '<h3>註冊元件</h3>'
});
var vm = new Vue({
el: "#box",
data: {
componentId: 'login' // 預設顯示登入
},
methods: {}
});
</script>
</body>
</html>
為元件切換新增過渡:
很簡單,只需要用 transition 將 component 包裹起來即可。
<transition>
<component :is="componentId"></component>
</transition>
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
<link rel="stylesheet" href="./lib/animate.css">
<style>
.loginDiv {
width: 200px;
height: 200px;
background-color: red;
}
.registerDiv {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box">
<!-- 給a註冊點選事件,切換flag狀態 -->
<a href="javascript:;" @click.prevent="componentId='login'">登入</a>
<a href="javascript:;" @click.prevent="componentId='register'">註冊</a>
<transition mode="out-in" enter-active-class="animated bounceInRight" leave-active-class="animated bounceOutRight">
<component :is="componentId"></component>
</transition>
</div>
<template id="login">
<div class="loginDiv">
</div>
</template>
<template id="register">
<div class="registerDiv">
</div>
</template>
<script>
Vue.component('login', {
template: '#login'
});
Vue.component('register', {
template: '#register'
});
var vm = new Vue({
el: "#box",
data: {
componentId: 'login'
},
methods: {}
});
</script>
</body>
</html>
mode="out-in"
:可以設定切換元件的模式為先退出再進入。
四、元件傳值
1、父元件向子元件傳值
我們先通過一個例子看看子元件可不可以直接訪問父元件的資料:
<body>
<div id="box">
<mycom></mycom>
</div>
<template id="temp">
<h3>子元件 --- {{msg}}</h3>
</template>
<script>
var vm = new Vue({
el: "#box",
data: {
msg: '父元件的msg'
},
methods: {},
components: {
mycom: {
template: '#temp'
}
}
});
</script>
</body>
由於 components 定義的是私有元件,我們直接在子元件中呼叫父元件的msg會報錯。
那麼,怎麼讓子元件使用父元件的資料呢?
父元件可以在引用子元件的時候, 通過 屬性繫結(v-bind:) 的形式, 把需要傳遞給子元件的資料,以屬性繫結的形式,傳遞到子元件內部,供子元件使用 。
<body>
<div id="box">
<mycom v-bind:parentmsg="msg"></mycom>
</div>
<template id="temp">
<h3>子元件 --- 父元件:{{parentmsg}}</h3>
</template>
<script>
var vm = new Vue({
el: "#box",
data: {
msg: '父元件的msg'
},
methods: {},
components: {
mycom: {
template: "#temp",
// 對傳遞給子元件的資料進行宣告,子元件才能使用
props: ['parentmsg']
}
}
});
</script>
</body>
注意:父元件繫結的屬性名稱不能有大寫字母,否則不會顯示,並且在命令列會有提示:
元件data資料和props資料的區別:
- data資料是子元件私有的,可讀可寫;
- props資料是父元件傳遞給子元件的,只能讀,不能寫。
案例:發表評論功能
父元件為評論列表,子元件為ID,評論者,內容和按鈕的集合,在輸入ID,評論者等內容,然後點選新增的時候,需要首先獲取子元件的list列表,然後再新增新的列表項到列表中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<mycom :plist="list"></mycom>
<ul>
<li v-for="item in list" :key="item.id">
ID:{{item.id}} --- 內容:{{item.content}} --- 評論人:{{item.user}}
</li>
</ul>
</div>
<template id="tmp1">
<div>
<label>
ID:
<input type="text" v-model="id">
</label>
<br>
<label>
評論者:
<input type="text" v-model="user">
</label>
<br>
<label>
內容:
<textarea v-model="content"></textarea>
</label>
<br>
<!-- 把父元件的資料作為子元件的函式引數傳入 -->
<input type="button" value="新增評論" @click="addContent(plist)">
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data: {
list: [{
id: Date.now(),
user: 'user1',
content: 'what'
}, {
id: Date.now(),
user: 'user2',
content: 'are'
}]
},
methods: {},
components: {
mycom: {
template: '#tmp1',
data: function () {
return {
id: '',
user: '',
content: '',
}
},
methods: {
addContent(plist) {
plist.unshift({
id: this.id,
user: this.user,
content: this.content
});
}
},
props: ['plist']
}
}
});
</script>
</body>
</html>
把新增ID,評論人,內容作為子元件,把列表作為父元件,然後把新增的資料放到父元件列表上,由於要獲取到父元件列表的資料,所以必然涉及到父元件向子元件傳值的過程。這裡還通過子元件方法引數來儲存父元件的資料到子元件的資料中。
2、父元件向子元件傳方法
既然父元件可以向子元件傳遞資料,那麼也可以向子元件傳遞方法。
<body>
<div id="box">
<mycom v-bind:parentmsg="msg" @parentfunc="show"></mycom>
</div>
<template id="temp">
<div>
<input type="button" value="呼叫父元件方法" @click="sonClick">
<h3>子元件 --- 父元件:{{parentmsg}}</h3>
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data: {
msg: '父元件的msg'
},
methods: {
show(data1, data2) {
console.log("這是父元件的show方法" + data1 + data2);
}
},
components: {
mycom: {
template: "#temp",
// 對傳遞給子元件的資料進行宣告,子元件才能使用
props: ['parentmsg'],
methods: {
sonClick() {
// 呼叫父元件的show方法
this.$emit("parentfunc", 111, 222);
}
}
}
}
});
</script>
</body>
1、
@parentfunc="show"
繫結父元件的show方法。2、
<input type="button" value="呼叫父元件方法" @click="sonClick">
點選按鈕呼叫父元件的show方法3、在 子元件的 sonClick 方法中使用
this.$emit("parentfunc");
來呼叫父元件的show方法4、父元件的show方法也可以傳參,在呼叫的時候,實參從 this.$emit 的第二個引數開始傳入。
5、如果 this.$emit 的第二個引數傳的是子元件的data資料,那麼父元件的方法就可以獲得子元件的資料,這也是把子元件的資料傳遞給父元件的方式。
3、使用 ref 獲取DOM和元件的引用
我們知道Vue不推薦直接獲取DOM元素,那麼在Vue裡面怎麼獲取DOM及元件元素呢?
我們呢可以在元素上使用 ref
屬性來獲取元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="box">
<input type="button" value="獲取元素" @click="getrefs" ref="mybtn">
<h3 ref="myh3">這是H3</h3>
<mycom ref="mycom"></mycom>
</div>
<template id="tmp1">
</template>
<script>
// 定義元件
Vue.component('mycom', {
template: '#tmp1',
data: function () {
return {
msg: '子元件的msg',
pmsg: ''
}
},
methods: {
show(data) {
console.log('呼叫子元件的show');
this.pmsg = data;
console.log(this.pmsg);
},
}
});
var vm = new Vue({
el: "#box",
data: {
parentmsg: '父元件的msg'
},
methods: {
getrefs() {
console.log(this.$refs.myh3);
console.log(this.$refs.mycom.msg);
this.$refs.mycom.show(this.parentmsg);
}
}
});
</script>
</body>
</html>
總結:
1、ref 屬性不僅可以獲取DOM元素,也可以獲取元件(無論全域性還是私有元件)元素。
2、獲取到元件元素後,就可以獲取元件元素的data資料和methods方法。
3、獲取到元件中的方法後,可以傳入VM的data資料,就可以把VM的data資料傳入元件中。
相關文章
- 從零開始學 Web 之 Vue.js(三)Vue例項的生命週期WebVue.js
- 從零開始學Electron筆記(六)筆記
- 從零開始學golang之TCPGolangTCP
- 從零開始學安全(六)●黑客常用的Dos命令黑客
- 從零開始學習 React 高階元件React元件
- Vue.js 學習筆記之六:構建更復雜的元件Vue.js筆記元件
- 從零開始學五筆(六):捺區字根
- 從零開始徒手擼一個vue的toast彈窗元件VueAST元件
- 一個「學渣」從零開始的Web前端自學之路Web前端
- 從零開始學Web之jQuery(一)jQuery的概念,頁面載入事件WebjQuery事件
- 深入Vue.js從原始碼開始(一)Vue.js原始碼
- VUE2.0從零開始 學習路線Vue
- 從零開始學 Web 之 JavaScript 高階(一)原型,貪吃蛇案WebJavaScript原型
- Re從零開始的UI庫編寫生活之表格元件UI元件
- 從零開始學PythonPython
- 從零開始學Python—第六課:迴圈結構Python
- VUE從零開始環境搭建Vue
- 從零開始學習C++之遞推C++
- 從零開始學 Python 之基礎語法Python
- 從零開始學YC-Framework之鑑權Framework
- 從零開始的堆疊卡片控制元件控制元件
- 從零開始React專案架構(六)React架構
- Vue.js 學習筆記之四:Vue 元件基礎Vue.js筆記元件
- 從零開始學 Spring BootSpring Boot
- 從零開始學正則
- 從零開始學習laravelLaravel
- 從零開始學習KafkaKafka
- 【ROS】從零開始學ROSROS
- vue.js元件開發Vue.js元件
- Re從零開始的UI庫編寫生活之進度條元件UI元件
- 如何從0開始搭建 Vue 元件庫Vue元件
- 從零實現Vue的元件庫(六)- Hover-Tip 實現Vue元件
- 從零開始學WEB前端——網頁的骨架——HTML理論講解Web前端網頁HTML
- VUE從零開始系列(上手),呆萌小白上手VUEVue
- VUE從零開始系列(axios),呆萌小白上手VUEVueiOS
- flutter之從零開始搭建(一)之 BottomNavigationBarFlutterNavigation
- 從零開始學React:二檔 React生命週期以及元件開發React元件
- 從零開始做Vue前端架構(9)Vue前端架構