Vue组件--潘登同学的前端笔记
组件
组件基础
- 创建组件(在于APP.vue文件同级目录下的compoents中创建
My_components.vue
)
<!-- vue + 回车 快速生成模板 -->
- 引用组件
<!-- 在APP.vue文件中,引入组件 -->
import MyComponent from "./components/My_components.vue";
<!-- 在JS中的watch,methods同级下,注入组件 -->
components:{
MyComponent,
},
<!-- 再回到APP.vue的body中,调用该组件 -->
<MyComponent />
- 组件的复用
一个组件可以视作一个独立的整体,可以复用,且互不干涉;因为你每用一次组件,就会有一个它的新实例被创建。
所以在export default
下, data
必须是个函数 data()
组件的组织
通常一个应用会以一棵嵌套的组件树的形式来组织:
Prop(让组件变得动态)
<!-- 第一个组件改为 对于num,因为已经绑定了,所以"5"其实是对象5,就是数字-->
<MyComponent title="组件基础" :num="5"/>
<!-- 第二个组件改为 -->
<MyComponent title="组件深入" :num="8"/>
<!-- 回到My_components.vue,在JS中的watch,methods同级下, -->
props:{
title:{
type:String,
default:"default value",
},
num:{
type:Number,
default:0,
}
},
methods: {
addI: function () {
this.count += this.num;
},
},
<!-- 组件body改为 -->
<div>
<!-- 唯一根元素 -->
<p>组件:{{ title }}</p>
<div>
<p>{{ count }}</p>
<button @click="addI">加{{ num }}操作</button>
</div>
</div>
Prop 验证
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true // 必填的字符串
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
注意
注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data
、computed
等) 在 default
或 validator
函数中是不可用的。(但是我们的methods
,data
却能使用props的值,如我们前面的methods修改一样)
Type
的取值
[String,Number,Boolean,Array,Object,Date,Function,Symbol]
type
还可以是一个自定义的构造函数,并且通过 instanceof
来进行检查确认。例如,给定下列现成的构造函数:
props: {
author: function(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
}
自定义事件
如果Props理解为从APP.vue
传递数据(父传子),那么自定义事件就是子传父;
<!-- 在My_components.vue中,新增 -->、
<button @click="sendMessageHandle">传递数据</button>
data() {
return {
message:"我是一条数据",
};
methods: {
addI: function () {
this.count += this.num;
},
<!-- onMyEvent是父级对象 -->
sendMessageHandle(){
this.$emit("onMyEvent",this.message)
},
},
<!-- APP.vue中 -->
<MyComponent title="组件基础" :num="5" @onMyEvent="getMyComponentMessage"/>
<!-- methods中 -->
getMyComponentMessage(data){
console.log(data);
}
插槽
- 插槽内容(
标签)
<!-- 新建components -->
<div>
<h3>插槽</h3>
<div>
<slot></slot>
</div>
</div>
<!-- 回到APP.vue -->
import NewComponent from "./components/New_components.vue";
data() {
return {
content:"我是插槽内容",
}
},
components:{
MyComponent,
},
<!-- 通过组件的双标签来实现插槽功能,如果只写单标签的话,与组件功能相同 -->
<NewComponent>
<div>{{ content }}</div>
</NewComponent>
- 编译作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
写在哪就在哪声明,而不是呈现在哪就在哪声明,上面的content也是声明在APP.vue中
- 后备内容
<!-- 如果插槽中(APP.vue中)没有传内容,还会呈现默认值 -->
<!-- 修改New_components.vue -->
<div>
<h3>插槽</h3>
<div>
<slot>默认值/缺省值</slot>
</div>
</div>
- 具名插槽
可能在一个组件中,插槽内容分为很多条;每一条插槽内容都要放在template中,并且用 v-slot
进行绑定
<!-- 在APP.vue中 -->
<NewComponent>
<template v-slot:header>
<div>{{ content1 }}</div>
</template>
<template v-slot:body>
<div>{{ content2 }}</div>
</template>
<template v-slot:footer>
</template>
</NewComponent>
data() {
content1:"我是插槽header",
content2:"我是插槽body",
content3:"我是插槽footer",
},
<!-- 修改New_components.vue -->
<div>
<h3>插槽</h3>
<div>
<slot name="header">默认值/缺省值</slot>
<hr>
<slot name="body">默认值/缺省值</slot>
<hr>
<slot name="footer">默认值/缺省值</slot>
</div>
</div>
- 作用域插槽
让插槽内容能够访问子组件中才有的数据是很有用的;
<!-- 修改New_components.vue -->
<slot name="beiwanglu" :demo="demo1" >默认值/缺省值</slot>
data(){
return{
demo1:"我是demo",
}
},
<!-- 在APP.vue中 -->
<template v-slot:beiwanglu="b">
<h3>{{ b.demo }}</h3>
</template>
- 缩写
v-slot
可以被缩写为 #
动态组件&异步组件
动态组件
<!-- 新建两个组件Child1与Child2 -->
<div>
<h3>Child1</h3>
</div>
<div>
<h3>Child2</h3>
<p>{{ msg }}</p>
<button @click="clickHandle">修改</button>
</div>
data(){
return{
msg:"第一次呈现数据",
}
},
methods:{
clickHandle(){
this.msg = "new Data";
},
},
<!-- 新增一个组件Dycomponent -->
<div>
<h3>我是动态组件</h3>
<button @click="changeComponent">切换组件</button>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</div>
import Child1 from "./Child1.vue";
import Child2 from "./Child2.vue";
data(){
return {
currentComponent:Child1,
}
},
methods:{
changeComponent(){
if(this.currentComponent === Child1){
this.currentComponent = Child2;
}else{
this.currentComponent = Child1;
}
},
},
components:{
Child1,
Child2,
}
<!-- 在APP.vue下 -->
import DyComponent from "./components/DyComponent.vue";
components:{
DyComponent,
},
这样就能实现,在点击切换组件
后,转变成了child2,点击修改
,数据变为 new Data
后,在此点击切换组件
(两次),回到child2后,还是new Data
,起到了保留输入的情况;
异步组件
加载形式改变,在组件没有被使用的时候是不加载的,知道被使用了才加载
<!-- 原来import -->
import Child2 from "./Child2.vue";
<!-- 异步import -->
const Child2 = () => import ("./Child2")
好处: 当一次性把所有组件加载进来会非常的卡,这样加载会有效缓解