要實(shí)現(xiàn)的功能:
點(diǎn)擊【顯示子組件】按扭,子組件顯示----已實(shí)現(xiàn)
點(diǎn)擊【關(guān)閉】,子組件關(guān)閉----未實(shí)現(xiàn);第一次點(diǎn)擊報(bào)underfind錯(cuò)誤?,并且子組件沒有隱藏
點(diǎn)擊【確認(rèn)】按鈕把input中的值傳到父組件的 {{text}} ------未實(shí)現(xiàn)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
</head>
<body>
<template id="aa">
<div>
<hr>
我是子組件2
<input type="text" v-model="text2">
<button @click="close()">關(guān)閉</button>
<button @click="affirm()">確認(rèn)</button>
</div>
</template>
<div id="box">
<p>
我是父組件:{{text}}
<button @click="showChild()">顯示子組件</button>
</p>
<child-page v-show="pageSwitch" :pageSwitch2="pageSwitch" :text2="text"></child-page>
</div>
<script>
new Vue({
el:"#box",
data:{
text:"hello",
pageSwitch:false
},
methods:{
showChild:function(){
this.pageSwitch=true;
}
},
components:{
"child-page":{
template:"#aa",
data:function(){
return{
childmsg:"子組件信息"
}
},
props:['pageSwitch2',"text2"],
methods:{
close:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
this.pageSwitch2=false;
},
affirm:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
}
}
}
}
})
</script>
</body>
</html>
其實(shí)樓上的方法都是舍近求遠(yuǎn)了,用$emit可以解決問題,
但是$emit的局限也很大,比如通過slot傳進(jìn)來的子組件就沒辦法使用$emit
高效而且能夠?qū)崿F(xiàn)解耦的做法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
</head>
<body>
<template id="aa">
<div>
<hr>
我是子組件2
<input type="text" v-model="text2">
<button @click="close()">關(guān)閉</button>
<button @click="affirm()">確認(rèn)</button>
</div>
</template>
<div id="box">
<p>
我是父組件:{{text}}
<button @click="showChild()">顯示子組件</button>
</p>
<child-page v-show="pageSwitch" :pageSwitch2="pageSwitch" :text2="text" :close="close" :affirm="affirm"></child-page>
</div>
<script>
new Vue({
el:"#box",
data:{
text:"hello",
pageSwitch:false
},
methods:{
showChild:function(){
this.pageSwitch=true;
},
close:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
this.pageSwitch2=false;
},
affirm:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
}
},
components:{
"child-page":{
template:"#aa",
data:function(){
return{
childmsg:"子組件信息"
}
},
props:['pageSwitch2',"text2","close","affirm"],
}
}
})
</script>
</body>
</html>
整體思路的就是把close和affirm(拼寫錯(cuò)誤,其實(shí)是confirm)兩個(gè)方法移動(dòng)到父組件,
然后在父組件的模板里把這兩個(gè)方法傳給子組件。
解釋:根據(jù)面向?qū)ο蟮摹伴_閉原則”,要想實(shí)現(xiàn)通過繼承子組件來修改內(nèi)部的邏輯,必然要對(duì)外暴露使用關(guān)心的接口
子組件向父組件通信,可使用$emit、vuex、或eventBus等,根據(jù)題主描述的問題,建議使用$emit方法。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
</head>
<body>
<template id="aa">
<div>
<hr>
我是子組件2
<input type="text" v-model="text2">
<button @click="close()">關(guān)閉</button>
<button @click="affirm()">確認(rèn)</button>
</div>
</template>
<div id="box">
<p>
我是父組件:{{text}}
<button @click="showChild()">顯示子組件</button>
</p>
<child-page v-show="pageSwitch" :pageSwitch2="pageSwitch" :text2="text"></child-page>
</div>
<script>
new Vue({
el:"#box",
data:{
text:"hello",
pageSwitch:false
},
methods:{
showChild:function(){
this.pageSwitch=true;
}
},
components:{
"child-page":{
template:"#aa",
data:function(){
return{
childmsg:"子組件信息"
}
},
props:['pageSwitch2',"text2"],
methods:{
close:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
this.$emit("pageSwitch2",false);
},
affirm:function(){
console.log(this.pageSwitch2);
console.log(this.text2);
}
}
}
}
})
</script>
</body>
</html>
ps:如題主方法,點(diǎn)擊父組件方法隱藏子組件,雖然可以實(shí)現(xiàn)隱藏子組件的功能,但實(shí)際上還是控制父組件中的數(shù)據(jù),并沒有實(shí)現(xiàn)父子組件的通信,建議題主可以多了解props和emit等常用方法。
感謝各位,效果已經(jīng)實(shí)現(xiàn)了
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
</head>
<body>
<template id="aa">
<div>
<hr>
我是子組件2
<input type="text" v-model="text2b">
<button @click="close()">關(guān)閉</button>
<button @click="affirm()">確認(rèn)</button>
</div>
</template>
<div id="box">
<p>
我是父組件:{{text}}
<button @click="showChild()">顯示子組件</button>
</p>
<child-page v-show="pageswitch" :pageswitch2="pageswitch" :text2="text" v-on:close2="close()" v-on:affirm2="affirm()" ref="childpage"></child-page>
</div>
<script>
new Vue({
el:"#box",
data:{
text:"hello",
pageswitch:false
},
methods:{
showChild:function(){
this.pageswitch=true;
},
close:function(){
this.pageswitch=false;
},
affirm:function(){
this.text=this.$refs.childpage.text2b; //父組件獲取子組件的值,使用this.$refs
}
},
components:{
"child-page":{
template:"#aa",
data:function(){
return{
childmsg:"子組件信息",
text2b:""
}
},
props:['pageswitch2',"text2"], //子組件獲取父組件的值,使用props
methods:{
close:function(){
this.$emit("close2"); //子組件事件觸發(fā)父組件的事件,使用 this.$emit
},
affirm:function(){
this.$emit("affirm2");
}
},
created:function(){
this.text2b=this.text2;
}
}
}
})
</script>
</body>
</html>
升級(jí)版代碼功能更多:
支持多個(gè)事件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
</head>
<style>
.reply{
font-size: 12px;
background: #d0d0d0;
width: 300px;
padding: 5px;
}
</style>
<body>
<template id="aa">
<div>
<hr>
<input type="text" v-model="reply2b" placeholder="請(qǐng)輸入評(píng)論內(nèi)容">
<button @click="close()">關(guān)閉</button>
<button @click="affirm()">確認(rèn)</button>
</div>
</template>
<div id="box">
<ul>
<li v-for="item in items" @click="showChild(item)">
{{item.title}}
<p class="reply" v-show="item.reply">{{item.reply}}</p>
</li>
</ul>
<child-page v-show="pageswitch" :pageswitch2="pageswitch" v-on:close2="close()" v-on:affirm2="affirm()" ref="childpage"></child-page>
</div>
<script>
new Vue({
el:"#box",
data:{
pageswitch:false,
items:[
{
"title":"標(biāo)題一",
"reply":"我是評(píng)論一"
},
{
"title":"標(biāo)題二",
"reply":""
}
],
item:""
},
methods:{
showChild:function(item){
this.pageswitch=true;
this.$refs.childpage.init(item); //父組件觸發(fā)子組件的事件this.$refs;
this.item=item;
},
close:function(){
this.pageswitch=false;
},
affirm:function(){
this.item.reply=this.$refs.childpage.reply2b; //父組件獲取子組件的值,使用this.$refs
}
},
components:{
"child-page":{
template:"#aa",
data:function(){
return{
childmsg:"子組件信息",
reply2b:""
}
},
props:['pageswitch2'], //子組件獲取父組件的值,使用props
methods:{
close:function(){
this.$emit("close2"); //子組件事件觸發(fā)父組件的方法,使用 this.$emit
},
affirm:function(){
this.$emit("affirm2");
},
init:function(item){
this.reply2b=item.reply;
}
}
}
}
})
</script>
</body>
</html>
用vuex吧,也就是單一事件中心管理組件通信
你報(bào)錯(cuò)的原因應(yīng)該是你通過子組件修改了父組件的數(shù)據(jù),這在vue2.0是不允許的(1.0可以),你要是想只是不報(bào)錯(cuò),可以使用 mounted中轉(zhuǎn),但解決不了實(shí)際問題。所以可以父組件每次傳一個(gè)對(duì)象給子組件, 對(duì)象之間引用
data:{
parentData:{
text:"hello",
pageSwitch:false
}
}
像上面這樣,父組件傳遞數(shù)據(jù)對(duì)象給子組件,子組件修改數(shù)據(jù)對(duì)象里的內(nèi)容。
<script>
//父組件
Vue.component('father', {
template: `
<div class="fatherBox">
<div class="message" v-html="fatherData"></div>
<button @click="changeChild">父組件按鈕</button>
<child
:show="forChild"
@childHandle="doChildCommand"
></child>
</div>
`,
data: function () {
return {
fatherData: '父組件數(shù)據(jù)',
forChild: '父組件傳給子組件的數(shù)據(jù)'
}
},
methods: {
changeChild: function () {
this.fatherData = '命令來源:<span>父組件</span>';
this.forChild = '父組件改變了傳給子組件的數(shù)據(jù)';
},
doChildCommand: function (a,b) {
this.fatherData = '命令來源:<span>子組件</span>';
this.forChild = '子組件請(qǐng)求父組件改變了這個(gè)值。附帶參數(shù) <span>a->'+ a +', b->' + b +'</span>';
}
}
})
//子組件
Vue.component('child', {
props: {
show: {
type: String,
default: '我是子組件'
}
},
template: `
<div class="childBox">
<div class="message" v-html="show"></div>
<button @click="changeFather">子組件按鈕</button>
</div>
`,
methods: {
changeFather: function () {
//通知父組件的一個(gè)函數(shù)
//第一個(gè)參數(shù)為與父組件約定好的函數(shù)
//后面的參數(shù)是遞數(shù)據(jù),可以為多個(gè)
this.$emit('childHandle','我是數(shù)據(jù)一','我也是數(shù)據(jù)')
}
}
})
new Vue({
template: '<father></father>',
el: '#app'
})
</script>
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。