Vue深入-8【元件註冊、父子元件通訊】
阿新 • • 發佈:2020-12-13
(1).註冊元件的兩種方式
1.全域性註冊元件
<script>
Vue.component('my-cmp',{
template:'<div>我的全域性註冊元件</div>'
})
</script>
2.區域性註冊元件
let myLocalCmp={ template:'<div>我的區域性註冊元件</div>' } new Vue({ el:'#app', components:{ myLocalCmp } })
3.元件解析
<template>
<div>Test</div>
</template>
<script>
import App from './App';
console.log(App)
</script>
(2).jsx配合render註冊元件中的html
1.render
Vue.component('my-cmp',{ render(h){ renturn( <h1>hello</h1> ) } })
這裡必須要寫到元件中經過babel編譯(下方就用cli了),且要禁用規則或者呼叫一下h才不會報錯
<script>
export default{
render(h){
console.log(h);
return(
<h1>App</h1>
)
}
}
</script
(3).render的h函式註冊元件中的html
h函式中有三個引數,第一個為標籤名,第二個為類名/id等,第三個為巢狀
1.第三個引數
<script>
export default{
render(h){
return h('h1',{},['Test1','Test2'])
}
}
</script>
<script>
export default{
render(h){
return h('h1',{},[
h('span',{},'這是一個span')
])
}
}
</script>
<scipt>
export default{
data(){
return{
items:['span1','span2']
}
},
render(h){
return h('h1',{},this.items.map((item)=>{
return h('span',{},item)
}))
}
}
</script>
2.第二個引數
<script>
export default{
render(h){
return h('h1',{
//類名
class:{
test:true,
'another-class':true
},
//樣式
style:{
color:'red',
fontSize:'100px'
},
//id
attrs:{
id:'test'
},
//事件響應
on:{
click:this.xx
}
})
}
}
</script>
(4).父子元件通訊
1.引入標籤傳值通訊
<template>
<div>
<h1>父親</h1>
<Child :message="message"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return{
message:'Hello Parent'
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
</div>
</template>
<script>
export default{
props:['message']
}
</script>
2.$emit通訊
<template>
<div>
<h1>父親</h1>
<Child :message="message" @changeMessage="message=$event"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return{
message:'Hello Parent'
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
<button @click="handleClick">按鈕</button>
</div>
</template>
<script>
export default{
props:['message'],
methods:{
handleClick(){
this.$emit('changeMessage','Bye')
}
}
}
</script>
3.直接將函式傳遞下去
<template>
<div>
<h1>父親</h1>
<Child :message="message" :changeMessageFn="changeMessage"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return{
message:'Hello Parent'
}
},
methods:{
changeMessage(value){
this.message = value
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
<button @click="changeMessageFn('回撥函式')">按鈕</button>
</div>
</template>
<script>
export default{
props:['message','changeMessageFn'],
methods:{
handleClick(){
this.$emit('changeMessage','Bye')
}
}
}
</script>
<script>
export default{
data(){
return {
message:'data裡的message'
}
},
props:['message','changeMessageFn'],
methods:{
handleClick(){
this.$emit('changeMessage','Bye')
}
}
}
</script>
4.$children訪問兒子data
<template>
<div>
<h1>父親</h1>
<p>{{message}}</p>
<button @click="changeChildNumber">按鈕</button>
<Child/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return{
message:'Hello Parent'
}
},
methods:{
changeChildNumber(){
this.$children[0].number = 50
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<p>{{number}}</p>
</div>
</template>
<script>
export default{
data(){
return{
nmber:30
}
}
}
</script>
5.通過$parent來訪問父例項
<template>
<div>
<h1>孩子</h1>
<p>{{parentMessage}}</p>
</div>
</template>
<script>
export defalut{
data(){
return {
number:10
}
},
computed:{
parentMessage(){
return this.$parent.message
}
}
}
</script>
this.$parent.$options.name
$parent $children是沒什麼用的,通常用於元件庫去查詢到父元件的名稱
所有inject都可以獲取到provide宣告的值,無論是什麼層級的元件
<template>
<div>
<h1>父親</h1>
<Child/>
</div>
</template>
<script>
import Child from './Child';
export default{
provide:{
message:'Hello Parent'
},
components:{
Child
}
}
</script>
<template>
<div>
<h1>孩子</h1>
{{message}}
<GrandChild/>
</div>
</template>
<script>
import GrandChild from './GrandChild'
export default{
inject:['message'],
components:{
GrandChild
}
}
</script>
<template>
<div>
<h1>孫子</h1>
{{message}}
</div>
</template>
<script>
export default{
inject:['message']
}
</script>
7.$attrs $listeners
1.$attrs 和v-bind
$attrs可以不接收父親的data,儲存在attrs中傳遞給孫子
<template>
<div>
<h1>父親</h1>
<p>姓名:{{name}}</p>
<p>年齡:{{age}}</p>
<Child :name="name" :age="age"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return {
name:'zza',
age:20
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<GrandChild v-bind="$attrs"/> //這裡的v-bind就是簡化了引數的傳遞
</div>
</template>
<script>
import GrandChild from './GrandChild';
export default{
components:{
GrandChild
}
}
</script>
<template>
<div>
<h1>孫子</h1>
{{name}}
{{age}}
</div>
</template>
<script>
export default{
props:['name','age']
}
</script>
<template>
<div>
<h1>父親</h1>
<p>姓名:{{name}}</p>
<p>年齡:{{age}}</p>
<Child :name="name" :age="age" @test="changeName"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
data(){
return {
name:'zza',
age:20
}
},
methods:{
changeName(){
this.name='小夏'
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<button @click="$listeners.test">按鈕</button>
</div>
</template>
<template>
<div>
<h1>父親</h1>
<button @click="changeAge">按鈕</button>
<Child ref="childComp"/>
</div>
</template>
<script>
import Child from './Child';
export default{
components:{
Child
},
methods:{
changeAge(){
console.log('before',this.$refs.childComp.age)//20
this.$refs.childComp.changeAge();
console.log('before',this.$refs.childComp.age)//50
}
}
}
</script>
<template>
<div>
<h1>孩子</h1>
<button>按鈕</button>
</div>
</template>
<script>
export default{
data(){
return {
age:20
}
},
methods:{
changeAge(){
this.age=50
}
}
}
</script>
<template>
<div>
<div ref="mydiv"></div>
</div>
</template>
<script>
mounted(){
console.log(this.$refs.myDiv)
this.$refs.myDiv.innerHtml="Hello"
}
</script