您的位置:首页 >> Vue >> 《和小米一起学Vue.js》— 组件基础

《和小米一起学Vue.js》— 组件基础

[ 孤狼 | 2022-07-30 00:52:19 | Vue | 1081°C | 0条评论 ]

组件是可复用的 Vue 实例,且带有一个名字。因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。


组件基础

组件构造器 vue.extend()

组件构造器内需要一个template属性来存放组件模板

const zj=vue.extends({
template:'<div>你好,我是组件内容</div>'
})


组件注册 vue.component

Vue.component('组件名称',组件构造器)
Vue.component('nzj',zj)


组件使用

组件的使用通过组件名称为标签来调用

<nzj></nzj>


直接注册组件

在新版本vue中,可以直接注册组件

Vue.component('nzj2',{
template:'<div>你好,我是直接注册组件内容</div>'
})


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 创建组件</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<nzj></nzj>
<nzj></nzj>
<nzj2></nzj2>
</div>
<script>
const zj=Vue.extend({
template:'<div>你好,我是组件内容</div>'
})
Vue.component('nzj',zj)

Vue.component('nzj2',{
template:'<div>你好,我是直接注册组件内容</div>'
})


let ndata={
};
const app=new Vue({
el:"#app",
data:ndata
});
</script>
</body>
</html>




全局组件和局部组件

在vue实例之外注册的组件,为全局组件,可以在多个vue实例内使用,在vue实例内注册的组件为局部组件,只能在当前vue实例内使用。局部组件注册使用 components 属性。

const jb={
template:'<div>你好,我是局部组件内容</div>'
}
components:{
nzj:zj,
nzj2:{template:'<div>你好,我是直接注册组件内容</div>'},
nzj3:jb
}

上面3种方式均可注册局部组件(子组件)


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 局部组件</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<nzj></nzj>
<nzj></nzj>
<nzj2></nzj2>
</div>
<script>
const zj=Vue.extend({
template:'<div>你好,我是组件内容</div>'
})
const jb={
template:'<div>你好,我是局部组件内容</div>'
}
const app=new Vue({
el:"#app",
components:{
nzj:zj,
nzj2:{template:'<div>你好,我是直接注册组件内容</div>'},
nzj3:jb
}
});
</script>
</body>
</html>




父组件和子组件

在一个组件内的 components 属性下注册另一个组件,就会形成父子组件。

TIP:全局组件独立存在,没有父组件。  

Vue.component('zj1',{
template:'<div>我是组件1-<zj2></zj2></div>',
components:{
zj2:{template:'<div>我是子组件</div>'}
}
})


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 父子组件</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<zj1></zj1>
</div>
<script>
Vue.component('zj1',{
template:'<div>我是组件1-<zj2></zj2></div>',
components:{
zj2:{template:'<div>我是子组件</div>'}
}
})

const app=new Vue({
el:"#app",
data:{}
});
</script>
</body>
</html>




模板分离

1. 使用 script type="text/x-template" 来创建模板,然后在组件 template 里置顶模板ID来达到分离模板的目的

<script type="text/x-template" id="mb1">
<div>这里是mb1的内容</div>
</script>
Vue.component('zj1',{
template:'#mb1'
})


2. 使用 template 标签来创建模板

<template id="mb2">
<div>这里是template标签的mb2内容</div>
</template>
Vue.component('zj2',{
template:'#mb2'
})


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 模板分离</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<zj1></zj1>
<zj2></zj2>
</div>
<script type="text/x-template" id="mb1">
<div>这里是mb1的内容</div>
</script>
<template id="mb2">
<div>这里是template标签的mb2内容</div>
</template>

<script>
Vue.component('zj1',{
template:'#mb1'
})
Vue.component('zj2',{
template:'#mb2'
})

const app=new Vue({
el:"#app",
data:{}
});
</script>
</body>
</html>




组件数据存放

组件中数据存放在自己的 data 函数里,组件的 data 不能是对象,只能以函数方式出现。

案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 组件数据存放</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<zj1></zj1>
</div>
<template id="mb1">
<div>{{name}}</div>
</template>

<script>
Vue.component('zj1',{
template:'#mb1',
data(){
return{
name:'你好'
}
}
})

const app=new Vue({
el:"#app",
data:{}
});
</script>
</body>
</html>




父子组件通信

在我们开发组件时,它的一些功能可能要求我们和父级组件进行沟通。

一:父传子  

<div id="app">
<zj1 :zname="name"></zj1>
</div>
<template id="mb1">
<div>{{zname}}</div>
</template>
const zj={
template:'#mb1',
props:['zname']
}

const app=new Vue({
el:"#app",
data:{
name:'张三'
},
components:{
zj1:zj
}
});

上面父组件vue内的数据name 被子组件内的zname绑定并输出。



props的使用方式

父组件向子组件传递数据,在其子组件中,我们可以通过给子组件添加一个 props 属性来支持这个功能。在调用是使用 v-bind 的方式绑定父组件的数据。  

1.数组方式

props:['zname']

2.对象方式

指定变量类型,如果传入参数类型不符,会有报错

props:{zname:String}
props:{zname:[String,Number]}

参数为对象,设置默认值和必选选项

props:{zname:{type:String,default:'默认值',required:true}}
props:{zname:{type:array,default(){return ['默认值']}}}

 required true 时,必须传值,否则报错

 type 类型为 array object 时,默认值必须是个函数返回。否则报错


props 中定义的变量名,尽量使用小写,如果使用驼峰命名,由于 v-bind 不支持,就必须要转换为 “-” 连接的名称。否则不识别。

props:['zName']
<div :z-name="name">{{zName}}</div>

上面代码中 props 里的 zName 驼峰命名法,在v-bind中只能使用 “z-name” 的方式绑定。


二:子组件向父组件传数据(自定义事件)

子组件可以通过调用内建的 $emit 方法并传入事件名及数据。

//zm(){
// this.$emit('事件名','子组件数据');
//}
zm(){
this.$emit('fms','子组件数据');
}

并在模板中绑定该函数

<template id="mb1">
<button @click="zm">{{zname}}</button>
</template>

最后在调用标签上将事件名绑定到父组件的函数名上即可

<zj1 :zname="name" @fms="fm"></zj1>


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 父子组件通信</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<zj1 :zname="name" @fms="fm"></zj1>
</div>


<template id="mb1">
<button @click="zm">{{zname}}</button>
</template>

<script>
const zj={
template:'#mb1',
props:['zname'],
methods:{
zm(){
this.$emit('fms','子组件数据');
}
}
}

const app=new Vue({
el:"#app",
data:{
name:'张三'
},
components:{
zj1:zj
},
methods:{
fm(value){
console.log(value);
}
}
});
</script>
</body>
</html>





访问子组件实例或子元素

尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 这个属性为子组件赋予一个 ID 引用。

TIP:$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs。  

<div id="app">
<div>
<zj ref="zj1"></zj>
<button @click="dy">打印</button>
</div>
</div>
<script>
const app=new Vue({
el:"#app",
data:{},
components:{
zj:{
template:'#zj',
data(){
return {
zj_name:'zjname',
}
}
}
},
methods:{
dy(){
console.log(this.$refs.zj1.zj_name);
}
}
});
</script>


$children 

可以直接通过下标调用当前实例的子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。一般推荐使用ref方式来调用。

<div id="app">
<div>
<zj></zj>
<zj></zj>
<button @click="dy2">打印第2个zj组件的名称</button>
</div>
</div>
<script>
const app=new Vue({
el:"#app",
data:{},
components:{
zj:{
template:'#zj',
data(){
return {
zj_name:'zjname',
}
}
}
},
methods:{
dy2(){
console.log(this.$children[1].zj_name);
}
}
});
</script>


案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 子组件访问</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<div>
<zj></zj>
<zj></zj>
<zj ref="zj1"></zj>
<button @click="dy">打印ref指定的子组件名称</button>
<button @click="dy2">打印第2个zj组件的名称</button>
</div>
</div>
<template id="zj">
<div>
我是子组件-{{zj_name}}
</div>
</template>
<script>
const app=new Vue({
el:"#app",
data:{},
components:{
zj:{
template:'#zj',
data(){
return {
zj_name:'zjname',
}
}
}
},
methods:{
dy(){
console.log(this.$refs.zj1.zj_name);
},
dy2(){
console.log(this.$children[1].zj_name);
}
}
});
</script>

</body>
</html>





访问父组件元素

子实例可以用 this.$parent 访问父实例,同时子实例被推入父实例的 $children 数组中。

TIP:节制地使用 $parent 和 $children - 它们的主要目的是作为访问组件的应急方法。更推荐用 props 和 events 实现父子组件通信  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 父组件访问</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<zj></zj>
</div>

<template id="zj">
<div>
子组件的名称是:{{zj_name}} <br>
我的父组件名称是:{{fzj_name2}}
</div>
</template>

<script>
const app=new Vue({
el:"#app",
data:{
fzj_name:'叫爸爸'
},
components:{
zj:{
template:'#zj',
data(){
return {
zj_name:'子组件名称',
fzj_name2:this.$parent.fzj_name
}
}
}
}
});
</script>
</body>
</html>





访问根组件元素

使用 $root 访问当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 根组件访问</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<zj></zj>
</div>
<template id="zj">
<div>
我是子组件我的根组件是{{rootname}}
</div>
</template>

<script>
const app=new Vue({
el:"#app",
data:{
fzj_name:'叫爸爸'
},
components:{
zj:{
template:'#zj',
data(){
return {
rootname:this.$root.fzj_name
}
}
}
}
});
</script>
</body>
</html>











转载请注明出处:http://gl.paea.cn/n.php?n=178
 
如您看得高兴,欢迎随意投喂,让我们坚持创作!
赞赏一个鸡腿
还没有人留下遗迹
综合 · 搜索