vuejs 單文件組件.vue 文件的使用
vuejs 自定義了一種.vue文件,可以把html, css, js 寫到一個(gè)文件中,從而實(shí)現(xiàn)了對(duì)一個(gè)組件的封裝, 一個(gè).vue 文件就是一個(gè)單獨(dú)的組件。由于.vue文件是自定義的,瀏覽器不認(rèn)識(shí),所以需要對(duì)該文件進(jìn)行解析。 在webpack構(gòu)建中,需要安裝vue-loader 對(duì).vue文件進(jìn)行解析。在 sumlime 編輯器中,我們 書寫.vue 文件,可以安裝vue syntax highlight 插件,增加對(duì)文件的支持。
用vue-cli 新建一個(gè)vue項(xiàng)目,看一下.vue文件長(zhǎng)什么樣? 在新建項(xiàng)目的過(guò)程中,命令行中會(huì)詢問(wèn)你幾個(gè)問(wèn)題,當(dāng)詢問(wèn)是否安裝vue-router 時(shí),這里先選擇否。項(xiàng)目完成后,我們看到src 目錄下有一個(gè)componet 目錄,里面有一個(gè) Hello.vue 文件,內(nèi)容如下,這里對(duì)template 里面的內(nèi)容做了一些刪減
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
可以看到,在 .vue 文件中, template 中都是html 代碼,它定義了在頁(yè)面中顯示的內(nèi)容,由于里面還有變量,也可以說(shuō)定義了一個(gè)模版;script中都是js 代碼,它定義這個(gè)組件中所需要的數(shù)據(jù)和及其操作,style 里面是css 樣式,定義這個(gè)組件的樣式,scoped 表明這里寫的css 樣式只適用于該組件,可以限定樣式的作用域。
script 標(biāo)簽中 export defalut 后面的對(duì)象的理解。
在不使用.vue 單文件時(shí),我們是通過(guò) Vue 構(gòu)造函數(shù)創(chuàng)建一個(gè) Vue 根實(shí)例來(lái)啟動(dòng)vuejs 項(xiàng)目,Vue 構(gòu)造函數(shù)接受一個(gè)對(duì)象,這個(gè)對(duì)象有一些配置屬性 el, data, component, template 等,從而對(duì)整個(gè)應(yīng)用提供支持。
new Vue({
el: '#app',
data: {
msg: "hello Vue"
}
})
在.vue文件中,export default 后面的對(duì)象 就相當(dāng)于 new Vue() 構(gòu)造函數(shù)中的接受的對(duì)象,它們都是定義組件所需要的數(shù)據(jù)(data), 以及操作數(shù) 據(jù)的方法等, 更為全面的一個(gè) export default 對(duì)象,有methods, data, computed, 這時(shí)可以看到, 這個(gè)對(duì)象和new Vue() 構(gòu)造函數(shù)中接受的對(duì)象是一模一樣的。但要注意data 的書寫方式不同。在 .vue 組件, data 必須是一個(gè)函數(shù),它return(返回一個(gè)對(duì)象),這個(gè)返回的對(duì)象的數(shù)據(jù),供組件實(shí)現(xiàn)。
把項(xiàng)目中自帶的hello.vue 內(nèi)容清空,我們自己寫一個(gè)組件來(lái)體驗(yàn)一下這種相同。
<template>
<div class="hello">
<input type="txet" placeholder="請(qǐng)輸入文字" v-model="msg" @keypress.enter="enter">
<p>{{upper}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'hello'
}
},
methods:{
enter () {
alert(this.msg);
}
},
computed: {
upper () {
return this.msg.toUpperCase();
}
}
}
</script>
<style scoped>
input {
width: 200px;
height: 20px;
}
p {
color: red;
}
</style>
頁(yè)面中有一個(gè)input輸入框,當(dāng)進(jìn)行輸入的時(shí)候,輸入框下面的內(nèi)容會(huì)進(jìn)行同步顯示,只不過(guò)它是大寫,當(dāng)輸入完成后,按enter鍵就會(huì)彈出我們輸入的內(nèi)容。獲取用戶輸入的內(nèi)容,我們用的是v-model 指令,這個(gè)指令將用戶輸入的內(nèi)容綁定到變量上,并且它響應(yīng)式的,我們的變量值會(huì)隨著用戶輸入的變化而變化,也就是說(shuō)我們始終獲取的都是用戶最新的輸入。下面大寫的顯示,用的是computed屬性,彈窗則是給綁定了一個(gè)keypress事件,通過(guò)描述,你會(huì)發(fā)現(xiàn),它簡(jiǎn)直就是一個(gè)vue實(shí)例,實(shí)際上它就是個(gè)vue實(shí)例。每一個(gè)vue組件都是一個(gè)vue實(shí)例,更容易明白 export default 后面的對(duì)象了。
父子組件之間的通信
每一個(gè).vue 文件就是一個(gè) 組件,組件和組件相互組合,就成了一個(gè)應(yīng)用,這就涉及到的組件和組件之間的通信,最常用的就是父子之間的通信。在vue 中, 在一個(gè)組件中通過(guò) import 引入另一個(gè)組件,這個(gè)組件就是父組件,被引入的組件就是子組件。
在我們這個(gè)vue-cli 項(xiàng)目中,src 文件夾下有一個(gè)App.vue 文件,它的script標(biāo)簽中,import Hello from './components/Hello',那么 App.vue 就是父組件,components 文件夾下的Hello.vue 就是子組件。父組件通過(guò)props 向子組件傳遞數(shù)據(jù),子組件通過(guò)自定義事件向父組件傳遞數(shù)據(jù)。
父組件向子組件傳值, 它主要是通過(guò)元素的屬性進(jìn)行的. 在App.vue 的template中,有一個(gè) <hello></hello>, 這就是我們引入的子組件. 給其添加屬性如 mes-father="message from father"; 父組件將數(shù)據(jù)傳遞進(jìn)去,子組件需要接收才能使用. 怎樣接收呢?
在Hello.vue 中, export default 后面的對(duì)象中,添加一個(gè)字段props, 它是一個(gè)數(shù)組, 專門用來(lái)接收父組件傳遞過(guò)來(lái)的數(shù)據(jù). props: ["mesFather"], 這里定義了mesFather 字符串, 和父組件中定義的元素的屬性一一對(duì)應(yīng). 但是我們?cè)诟附M件,就是在 <hello /> 元素中定義的屬性是mes-father, 沒(méi)有一一對(duì)應(yīng)啊? 這主要是因?yàn)?,在html 元素中大小寫是不敏感的。 如果我們寫成<hello mesFather="message from father"></hello>, 里面的mesFather 就會(huì)轉(zhuǎn)化成mesfather, 相當(dāng)于我們向子組件傳遞了一個(gè)mesfather數(shù)據(jù), 如果在js 文件中,我們定義 props: ["mesFather"],我們是接受不到數(shù)據(jù)的,因?yàn)閖s 是區(qū)分大小寫的, 只能寫成props: ["mesfather"]. 但是在js 文件中,像這種兩個(gè)單詞拼成的數(shù)據(jù),我們習(xí)慣用駝峰命名法,所以vue 做了一個(gè)轉(zhuǎn)化,如果在組件中屬性是 - 表示,它 自動(dòng)會(huì)轉(zhuǎn)化成駝峰式。 傳進(jìn)來(lái)的數(shù)據(jù)是mes-father, 轉(zhuǎn)化成mesFather, 我們?cè)趈s 里面寫mesFather, 一一對(duì)應(yīng),子組件可以接受到組件。 props 屬性是和data, methods 屬性并列的,屬同一級(jí)別。 props 屬性里面定義的變量,在 子組件中的template 中可以直接使用。
App.vue 的template 更改如下:
<template> <div id="app"> <img src="./assets/logo.png"> <hello mes-father="message from father"></hello> </div> </template>
Hello.vue組件,這里還是把項(xiàng)目中自帶的Hello.vue 清空,自己寫,變成如下內(nèi)容
<template>
<div class="hello">
<p>{{mesFather}}</p>
</div>
</template>
<script>
export default {
props:['mesFather']
}
</script>
這時(shí),在頁(yè)面中看到 message from father 字樣,父元素向子元素傳遞數(shù)據(jù)成功。
子組件向父組件傳遞數(shù)據(jù),需要用到自定義事件。 例如,我們?cè)贖ello.vue ,寫入一個(gè)input, 接收用戶輸入,我們想把用戶輸入的數(shù)據(jù)傳給父組件。這時(shí),input 需要先綁定一個(gè)keypress 事件,獲取用戶的輸入,同時(shí)還要發(fā)射自定義事件,如valueUp, 父組件只要監(jiān)聽這個(gè)自定義事件,就可以知道子組件要向他傳遞數(shù)據(jù)了。子組件在發(fā)射自定義事件時(shí),還可以攜帶參數(shù),父組件在監(jiān)聽該事件時(shí),還可以接受參數(shù),參數(shù),就是要傳遞的數(shù)據(jù)。
在 Hello.vue template中,添加一個(gè)input輸入框,給它一個(gè)v-model 獲取用戶的輸入,再添加keypress的事件,用于發(fā)射事件,傳輸數(shù)據(jù)。script 中添加data,定義變量來(lái)獲取用戶的輸入,添加methods 來(lái)處理keypress事件的處理函數(shù)enter, 整個(gè)Hello.vue 文件如下
<template>
<div class="hello">
<!-- 添加一個(gè)input輸入框 添加keypress事件-->
<input type="text" v-model="inputValue" @keypress.enter="enter">
<p>{{mesFather}}</p>
</div>
</template>
<script>
export default {
props:['mesFather'],
// 添加data, 用戶輸入綁定到inputValue變量,從而獲取用戶輸入
data: function () {
return {
inputValue: ''
}
},
methods: {
enter () {
this.$emit("valueUp", this.inputValue)
//子組件發(fā)射自定義事件valueUp, 并攜帶要傳遞給父組件的值,
// 如果要傳遞給父組件很多值,這些值要作為參數(shù)依次列出 如 this.$emit('valueUp', this.inputValue, this.mesFather);
}
}
}
</script>
在App.vue 中, template中hello 組件綁定一個(gè)自定義事件,@valueUp =“receive”, 用于監(jiān)聽子組件發(fā)射的事件,再寫一個(gè) p 元素,用于展示子組件傳遞過(guò)來(lái)的數(shù)據(jù),<p>子組件傳遞過(guò)來(lái)的數(shù)據(jù) {{ childMes }}</p>
相應(yīng)地,在scrpit中,data 中,定義一個(gè)變量childMes, 并在 methods 中,定義一個(gè)事件處理函數(shù)reciever。整個(gè)App.vue修改如下:
<template>
<div id="app">
<img src="./assets/logo.png">
<!-- 添加自定義事件valueUp -->
<hello mes-father="message from father" @valueUp="recieve"></hello>
<!-- p元素,用于展示子組件傳遞過(guò)來(lái)的數(shù)據(jù) -->
<p>子組件傳遞過(guò)來(lái)的數(shù)據(jù) {{childMes}}</p>
</div>
</template>
<script>
import Hello from './components/Hello'
export default {
name: 'app',
components: {
Hello
},
// 添加data
data: function () {
return {
childMes:''
}
},
// 添加methods,自定義事件valueUp的事件處理函數(shù)recieve
methods: {
recieve: function(mes) { // recieve 事件需要設(shè)置參數(shù),這些參數(shù)就是子組件傳遞過(guò)來(lái)的數(shù)據(jù),因此,參數(shù)的個(gè)數(shù),也要和子元素傳遞過(guò)來(lái)的一致。
this.childMes = mes;
}
}
}
</script>
這時(shí)在input中輸入內(nèi)容,然后按enter鍵,就以看到子組件傳遞過(guò)來(lái)的數(shù)據(jù),子組件向父組件傳遞數(shù)據(jù)成功。
當(dāng)在input輸入框中輸入數(shù)據(jù),并按enter鍵時(shí),它會(huì)觸發(fā)keypress.enter事件,從而調(diào)用事件處理函數(shù)enter, 在enter 中, 我們發(fā)射了一個(gè)事件valueUp, 并攜帶了一個(gè)參數(shù),由于在<hello @valueUp=”recieve”></hello> 組件中, 我們綁定valueUp 事件,所以父組件在時(shí)刻監(jiān)聽valueUp 事件, 當(dāng)子組件發(fā)射value 事件時(shí),父組件立刻捕獲到,并立即調(diào)用它的回調(diào)函數(shù)receive, 在receive 中,我們獲取到子組件傳遞過(guò)來(lái)的數(shù)據(jù),并賦值了data 中的變量childMes, 由于data 數(shù)據(jù)發(fā)生變化,從而觸發(fā)dom更新,頁(yè)面中就顯示子組件傳遞過(guò)來(lái)的內(nèi)容。
其實(shí)在子組件中, props 最好的寫法是props 驗(yàn)證,我們?cè)谧咏M件Hello.vue中寫 props:['mesFather'], 只是表達(dá)出,它接受一個(gè)參數(shù)mesFather, 如果寫成props 驗(yàn)證,不僅能表達(dá)出它需要什么參數(shù),還能表達(dá)參數(shù)類型,并且如有錯(cuò)誤,vue 會(huì)做出警告?,F(xiàn)在把props 改成props 驗(yàn)證的寫法, Hello.vue 中的js中的props修改如下:
props: {
'mesFather': {
type: String,
default: 'from father',
required:true
}
}
如果是組件與組件之間的通信非常復(fù)雜,不光是父子組件,還有兄弟組件,那就需要用到狀態(tài)管理,vuex
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue.js 使用axios實(shí)現(xiàn)下載功能的示例
下面小編就為大家分享一篇vue.js 使用axios實(shí)現(xiàn)下載功能的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看2018-03-03
vue + socket.io實(shí)現(xiàn)一個(gè)簡(jiǎn)易聊天室示例代碼
本篇文章主要介紹了vue + socket.io實(shí)現(xiàn)一個(gè)簡(jiǎn)易聊天室示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-03-03
Vue路由組件的緩存keep-alive和include屬性的具體使用
:瀏覽器頁(yè)面在進(jìn)行切換時(shí),原有的路由組件會(huì)被銷毀,通過(guò)緩存可以保存被切換的路由組件,本文主要介紹了Vue路由組件的緩存keep-alive和include屬性的具體使用,感興趣的可以了解一下2023-11-11
詳解Vue調(diào)用手機(jī)相機(jī)和相冊(cè)以及上傳
這篇文章主要介紹了Vue調(diào)用手機(jī)相機(jī)及上傳,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
mui-player自定義底部導(dǎo)航在vue項(xiàng)目中顯示不出來(lái)的解決
這篇文章主要介紹了mui-player自定義底部導(dǎo)航在vue項(xiàng)目中顯示不出來(lái)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Vue.js中使用iView日期選擇器并設(shè)置開始時(shí)間結(jié)束時(shí)間校驗(yàn)功能
本文通過(guò)實(shí)例代碼給大家介紹了Vue.js中使用iView日期選擇器并設(shè)置開始時(shí)間結(jié)束時(shí)間校驗(yàn)功能,需要的朋友可以參考下2018-08-08
vue-cli腳手架初始化項(xiàng)目各個(gè)文件夾用途
這篇文章主要介紹了vue-cli腳手架初始化項(xiàng)目各個(gè)文件夾用途,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01

