一、组件相关知识
(1)
1> 模版
样式模版,有样式(css)有结构(html)的内容
2> 模块
js功能模块
3> 组件
带有结构样式和功能的内容,叫组件
(2)vue项目,就纯纯是使用组件构建的!
- 通过vue制作单页面应用程序(spa - single page application)
- vue实例其实就是最大的根组件!
二、注册组件
1.全局注册
将组件注册到根实例(根组件)上,那么,这个组件就是全局组件。
全局组件可以被任意组件去使用
代码如下(示例):
app.component('my-thumbnail',{
template:`
<div class="thumbnail">
<img src="../img/1.jpeg" alt="...">
<div class="caption">
<h3>Thumbnail label</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p>
</div>
</div>
`
})
2.局部注册
将组件注册到某个组件的内部,通过components属性完成!局部组件只能在当前注册的组件使用
代码如下(示例):
let app = Vue.createApp({
components: {
"my-label": {
template:`
<span class="label label-default">Default{{count}}</span>
`,
data(){
return {
count:1
}
}
}
}
})
三、组件的属性
1.简述
1> 组件名:
组件名称有两种风格:
kebab-case (my-button)(推荐)
PascalCase (MyButton)
2> 组件中第二个参数的属性
- template 定义组件的结构样式
注意:组件可以有多个根节点,但是,尽量就一个
- 剩下的属性和你vue实例中可以写的属性一摸一样
而且,每个组件都是一个独立的作用域,都会维护自己的状态,不用担心冲突
2.props
组件提供一个props属性,专门用来接受你在使用组件时,写在组件身上的属性(标签属性)的属性(组件内容属性)
(1)基本使用方式
<my-btn btnname="登录" type="btn-primary"></my-btn>
// 注册组件
app.component('my-btn',{
template:`
<button class="btn btn-default" :class="type" @click="add">{{btnname}}</button>
`,
// props的使用方式,跟data一模一样
props:['btnname',"type"],
data(){
return {
count:1
}
},
methods:{
add(){
this.count++
}
}
})
(2)关于props的数据流向问题
1> 通过props可以完成父组件传值到子组件。
遵循数据的单向流通原则:父组件的值改变,子组件中的值改变!
注意:props 只能读,不能改!!
2>props 用处
- 动态改变组件的某些值
- 可以做为初始值使用
- 可以作为依赖属性去使用
3>关于props传递引用类型数据(对象/数组)的时候
如果你在子组件中修改引用类型的某个属性,他是允许修改的,因为你改某个属性的时候,并没有修改这个指针。
(3)props的约束
- 类型约束
String Number Array Object Boolean
props:{
bn: [String,Number],
info: Object
},
- 属性必填验证(此验证不是验证属性值必填,是验证属性必填)
props:{
bn: {
type: null, // 如果类型上允许任何类型通过,则写null即可
required: true
}
},
- 默认值
props:{
bn: {
type: null,
required: true,
default: '按钮' // 普通类型的默认值
},
info:{
type: Object,
default: () => { // 引用类型的默认值
return {title:'你未传递值'}
}
}
},
- 自定义验证规则
bn: {
type: null,
required: true,
default: '按钮', // 普通类型的默认值
validator: (value) => {
let reg = /^[A-Z]\w*$/g;
// 返回值为true,表示验证通过;
return reg.test(value)
}
},
3. 非props
1> 什么是?
没有在组件内通过props接受的属性 – 即非props属性
2>特性
前提:你的组件必须只有一个根节点
非props属性会自动成为你根节点的属性,这种现象叫属性继承
3>经常将哪些属性做成非props属性
class style id
4> 非props属性可以被禁止继承
-如何使用
在组件内部填写一个属性:
inheritAttrs: false
- 什么情况下禁止继承?
让非props属性在非根节点生效
- 在vue实例中,有一个属性:$ attrs,这个属性的作用就是接受所有非props属性
- < div v-bind=“$attrs”> // 此对象的属性会自动成为标签的属性
四、自定义事件
1> 自定义事件使用步骤
A. 给组件绑定自定义事件
<my-btn @myclick="change"></my-btn>
- 如果使用一段内联逻辑
<my-thumbnail @myclick="count+=$event.step"></my-thumbnail>
$event 就代表你传递过来的实参
B. 自定义事件会传输到子组件内部,需要使用 emits接受
emits:['myclick']
C. 在子组件内部的某个节点上绑定传统事件,触发自定义事件
this.$emit('myclick', {msg:'hello'})
2> 自定义事件可以完成子组件传值到父组件
五、组件中的双向绑定
1> 当你在组件上使用v-model时,vue自动向你的子组件发送了props(modelValue)属性emits(update:moveValue)自定义事件。
- 发送的props属性是:modelValue (v-model=‘值’)
- 发送的emits事件是:update:modelValue
2> 自定义属性的名称是可以修改的
<my-input v-model:age="info"></my-input>
- 子组件
props: {
age:null
}
emits:["update:age"]
3> 修饰符
当你给组件的v-model使用了修饰符之后,那么,将会传递一个对象到子组件之中 – modelModifiers;
此属性是由你的修饰符组成(值为true)的对象!
- 对于带参数的 v-model 绑定,生成的 prop 名称将为 arg + "Modifiers"
例:
v-model:age.number = 'age';
props:[age,ageModifiers]
六、插槽
1> 在子组件中开辟插槽
app.component('my-btn',{
template:
<button class="btn btn-primary">
<slot></slot>
</button>
`
})
2> 插入内容
可以是字符串
<my-btn>登录</my-btn>
<my-btn>注册</my-btn>
<my-btn>提阿娇</my-btn>
<my-btn>充值</my-btn>
可以是dom
<my-btn>
<b>登录</b>
</my-btn>
可以是组件
<my-btn>
<my-icon></my-icon>
搜索
</my-btn>
3> 插槽默认值
app.component('my-btn',{
template:
<button class="btn btn-primary">
<slot>按钮</slot>
</button>
`
})
4> 具名插槽
如果你组件的结构比较复杂,可以插入内容的位置比较多,这时,就需要具名插槽了
-
带有名字的插槽
-
插值到具体位置
<template v-slot:名字>你要插的内容</ template> -
v-slot指令的简写
<template #名字>你要插的内容</ template>
补充
(1) 深层组件传值
在祖父级组件上提供数据:
provide:{
属性:值,
…
}
在儿孙级注入数据:
inject:[属性…](2) 动态组件
<component is='组件名称'></component>
- 如果要缓存组件呢?
<keep-alive>
<component :is="show"></component>
</keep-alive>