Vue5--自定义组件/父子组件/组件多级传递/插槽
自定义全局组件在<template id="模板id">中定义模板在Vue.component中注册模板(“模板名”, {template: “#模板id”});在html中通过<模板名></模板名>使用模板在这里插入代码片...
自定义全局组件
- 在
<template id="模板id">
中定义模板 - 在Vue.component中注册模板(“模板名”, {
template: “#模板id”
}); - 在html中通过
<模板名></模板名>
使用模板
<body>
<div id="app">
<tem></tem>
</div>
<template id="temp">
<div>
<p>这是一个模板</p>
<p>这真的是一个模板</p>
</div>
</template>
<script>
Vue.component('tem',{
template:'#temp'
});
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
自定义局部组件
- 在
<template id="模板id">
中定义模板 - 在Vue实例的components中以{}注册组件,注册形式为
{ '模板名':{ template:'#模板id'}}
- 在该Vue实例绑定的标签中以 模板名 的形式使用组件
<body>
<div id="app">
<tem></tem>
</div>
<template id="temp">
<div>
<p>这是一个模板</p>
<p>这真的是一个模板</p>
</div>
</template>
<script>
let vue = new Vue({
el:'#app',
data:{
},
components:{
'tem':{
template:'#temp'
}
}
});
</script>
</body>
自定义组件中的data和methods
- 自定义组件中的函数定义在methods中
- 自定义组件中的data定义在函数的返回值中
<body>
<div id="app">
<tem></tem>
</div>
<template id="temp">
<div>
<p>{{msg}}</p>
<button v-on:click="func">按钮</button>
</div>
</template>
<script>
Vue.component('tem',{
template:'#temp',
data:function(){
return{
msg:'这真的是一个模板'
}
},
methods:{
func(){
console.log('我是一个自定义模板')
}
}
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
使用keep-alive实现动态组件(组件是否显示)
在component中,根据is的值决定哪个组件被渲染
keep-alive能保存被隐藏的组件在隐藏之前的状态
所以通过 keep-alive 和 component 配合使用,能实现组件动态显示,并保存组件在隐藏之前的状态
<body>
<div id="app">
<button @click="toggle">切换</button>
<keep-alive>
<component v-bind:is="name"></component>
</keep-alive>
</div>
<template id="temp1">
<p>{{msg}}</p>
</template>
<template id="temp2">
<p>{{msg2}}</p>
</template>
<script>
Vue.component('tem',{
template:'#temp1',
data:function(){
return{
msg:'这真的是一个模板'
}
},
methods:{
func(){
console.log('我是一个自定义模板')
}
}
});
Vue.component('tem2',{
template: '#temp2',
data:function(){
return{
msg2:'我真的是一个模板吗'
}
}
});
let vue = new Vue({
el:'#app',
data:{
name:'tem'
},
methods:{
toggle(){
this.name = this.name === 'tem'? 'tem2':'tem'
}
}
});
</script>
</body>
组件中使用过渡动画
如果是单个组件就使用transition
如果是多个组件就使用transition-group
在默认情况下,进入动画和离开动画同时执行,如果要指定动画的执行顺序,在transition中指定mode
父子组件
通过在自定义组件中再定义其子组件的形式定义父子组件
<body>
<div id="app">
<dadtemp></dadtemp>
</div>
<template id="dad">
<div>
<p>这是爸爸</p>
<sontemp></sontemp>
</div>
</template>
<template id="son">
<p>这是儿子</p>
</template>
<script>
let vue = new Vue({
el:'#app',
data:{
},
components:{
"dadtemp":{
template:'#dad',
components:{
'sontemp':{
template:'#son'
}
}
}
}
});
</script>
</body>
父子组件之间的数据传递
如果子组件想访问父组件中的数据,必须由父组件传递,子组件接收
在父组件中通过v-bind传递数据,传递格式 v-bind:自定义接收名称 = “要传递数据”
在子组件中通过props接收数据,接收格式 props: [“自定义接收名称”]
<body>
<div id="app">
<dadtemp></dadtemp>
</div>
<template id="dad">
<div>
<p>这是爸爸</p>
<sontemp v-bind:dadname="name" v-bind:dadsex="sex"></sontemp>
</div>
</template>
<template id="son">
<div>
<p>这是儿子---{{dadname}}==={{dadsex}}</p>
</div>
</template>
<script>
let vue = new Vue({
el:'#app',
data:{
},
components:{
"dadtemp":{
template:'#dad',
data:function(){
return{
name:'这是爸爸的名字',
sex:'这是爸爸的性别'
}
},
components:{
'sontemp':{
template:'#son',
props:["dadname","dadsex"]
}
}
}
}
});
</script>
</body>
父子组件之间的方法传递
想要在子组件中调用父组件中的方法:
在父组件中通过v-on传递方法:传递格式 v-on:自定义接收名称 = “要传递方法”
在子组件中自定义一个方法:在自定义方法中通过 this.$emit(‘自定义接收名称’)触发传递过来的方法
<body>
<div id="app">
<dadtemp></dadtemp>
</div>
<template id="dad">
<div>
<button @click="func">爸爸的按钮</button>
<sontemp @dadfunc="func"></sontemp>
</div>
</template>
<template id="son">
<div>
<button @click="sonfunc">儿子的按钮</button>
</div>
</template>
<script>
let vue = new Vue({
el:'#app',
data:{
},
components:{
"dadtemp":{
template:'#dad',
methods:{
func(){
console.log('这是爸爸的方法')
}
},
components:{
'sontemp':{
template:'#son',
methods:{
sonfunc(){
this.$emit('dadfunc')
}
}
}
}
}
}
});
</script>
</body>
子组件调用父组件方法时传递参数
this.$emit(需要调用的函数名称,传递的参数…)
<body>
<div id="app">
<dadtemp></dadtemp>
</div>
<template id="dad">
<div>
<button @click="func('baba')">爸爸的按钮</button>
<sontemp @dadfunc="func"></sontemp>
</div>
</template>
<template id="son">
<div>
<button @click="sonfunc">儿子的按钮</button>
</div>
</template>
<script>
let vue = new Vue({
el:'#app',
data:{
},
components:{
"dadtemp":{
template:'#dad',
methods:{
func(data){
console.log(data)
}
},
components:{
'sontemp':{
template:'#son',
methods:{
sonfunc(){
this.$emit('dadfunc','er')
}
}
}
}
}
}
});
</script>
</body>
组件命名
- 注册组件的时候使用了"驼峰命名", 那么在使用时需要转换成"短横线分隔命名"
例如: 注册时: myFather -> 使用时: my-father - 在传递参数的时候如果想使用"驼峰名称", 那么就必须写"短横线分隔命名"
例如: 传递时: parent-name=“name” -> 接收时: props: [“parentName”] - 在传递方法的时候不能使用"驼峰命名", 只能用"短横线分隔命名"
@parent-say=“say” -> this.$emit(“parent-say”);
<div id="app">
<my-father></my-father>
</div>
<template id="father">
<div>
<p>{{name}}</p>
<button @click="say">我是按钮</button>
<son :parent-name="name" @parent-say="say"></son>
</div>
</template>
<template id="son">
<div>
<p>{{parentName}}</p>
<button @click="sonFn">我是按钮</button>
</div>
</template>
<script>
// 父组件
Vue.component("myFather", {
template: "#father",
data: function(){
return {
name: "lnj"
}
},
methods: {
say(){
console.log("www.it666.com");
}
},
// 子组件
components: {
"son": {
template: "#son",
props: ["parentName"],
methods: {
sonFn(){
this.$emit("parent-say");
}
}
}
}
});
// 这里就是MVVM中的View Model
let vue = new Vue({
el: '#app'
});
</script>
组件多级传递
在Vue中如果儿子想使用爷爷的数据, 必须一层一层往下传递
在Vue中如果儿子想使用爷爷的方法, 必须一层一层往下传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--导入vue.js文件-->
<script src="js/vue.js"></script>
<style>
*{
margin:0;
padding:0;
}
</style>
</head>
<body>
<div id="app">
<yeyetemp></yeyetemp>
</div>
<template id="yeye">
<div>
<button @click="yeyefunc">爷爷的按钮</button>
<p>{{msg}}</p>
<dadtemp v-bind:yeyemsg="msg" @yefunc="yeyefunc"></dadtemp>
</div>
</template>
<template id="dad">
<div>
<button @click="bafunc">爸爸的按钮</button>
<p>{{yeyemsg}}</p>
<sontemp v-bind:dadmsg="yeyemsg" @babafunc="bafunc"></sontemp>
</div>
</template>
<template id="son">
<div>
<button @click="erfunc">儿子的按钮</button>
<p>{{dadmsg}}</p>
</div>
</template>
<script>
Vue.component('yeyetemp',
{
template:'#yeye',
data:function () {
return{
msg:'我是你爷爷'
}
},
methods:{
yeyefunc(){
console.log('我是你爷爷');
}
},
components:{
'dadtemp':{
template:'#dad',
props:['yeyemsg'],
methods:{
bafunc(){
this.$emit('yefunc')
}
},
components:{
'sontemp':{
template:'#son',
props: ['dadmsg'],
methods:{
erfunc(){
this.$emit('babafunc')
}
}
}
}
}
}
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
</html>
匿名插槽
默认情况下,在父组件中调用子组件中,如果向子组件的标签中添加内容,则这部分内容不会被渲染。
使用slot插槽,在子组件中挖一个坑,父组件有需求时再填,实现动态添加子组件中的内容。
slot没有name属性时,是匿名插槽。在子组件中有几个匿名插槽,在父组件中填充的数据就会被拷贝几份,所以一般只写一个匿名插槽。
<body>
<div id="app">
<temp>
<div>这是将template中slot标签中的默认内容替换的数据</div>
</temp>
</div>
<template id="tem">
<div>
<p>这是一个p</p>
<slot>
我是默认数据
</slot>
<p>这又是一个p</p>
</div>
</template>
<script>
Vue.component('temp',{
template:'#tem'
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
具名插槽
给slot添加name属性,就是具名插槽。在填充时,通过slot=‘插槽名’,将内容添加到该插槽中。没有给某具名插槽添加内容的,将会使用该插槽的默认内容。
<body>
<div id="app">
<temp>
<div slot="one">这是name=‘one'插槽的数据</div>
</temp>
</div>
<template id="tem">
<div>
<p>这是一个p</p>
<slot name="one">我是默认数据</slot>
<slot name="two">我是默认数据</slot>
<p>这又是一个p</p>
</div>
</template>
<script>
Vue.component('temp',{
template:'#tem'
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
v-slot
v-slot指令是Vue2.6中用于替代slot属性的一个指令
在Vue2.6之前, 我们通过slot属性告诉Vue当前内容填充到哪一个具名插槽
从Vue2.6开始, 我们通过v-slot指令告诉Vue当前内容填充到哪一个具名插槽
注意点: v-slot指令只能用在template标签上。可以使用#号替代v-slot
<body>
<div id="app">
<temp>
<template #one>
<p>one中的内容</p>
</template>
<template #two>
<p>two中的内容</p>
</template>
</temp>
</div>
<template id="tem">
<div>
<p>这是一个p</p>
<slot name="one">我是默认数据</slot>
<slot name="two">我是默认数据</slot>
<p>这又是一个p</p>
</div>
</template>
<script>
Vue.component('temp',{
template:'#tem'
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
作用域插槽
作用域插槽就是带数据的插槽, 就是让父组件在填充子组件插槽内容时也能使用子组件的数据—》子组件提供数据, 父组件决定如何渲染
- 在slot中通过
v-bind:数据名="数据"
方式暴露数据 - 在父组件中通过
<template slot-scope="作用域名称">
接收数据 - 在父组件的
<template></template>
中通过 作用域名称.数据名称 方式使用数据 - 匿名插槽可以使用
#default="作用域"
具名插槽可使用#插槽名="作用域"
<body>
<div id="app">
<temp>
<template #default="obj">
<li v-for="(name,index) in obj.names">{{name}}</li>
</template>
<template #one="obj2">
<li v-for="(data,index) in obj2.datas">{{data}}</li>
</template>
</temp>
</div>
<template id="tem">
<div>
<p>ppppp</p>
<slot :names="msg"></slot>
<slot :datas="msg" name="one"></slot>
</div>
</template>
<script>
Vue.component('temp',{
template:'#tem',
data:function () {
return{
msg:["zs", "ls", "ww", "zl"]
}
}
})
let vue = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
更多推荐
所有评论(0)