上一章已经更新了Vue基础,那么本章将更新Vue中最重要的概念--组件,会介绍到组件的使用,组件传值,插槽的使用,插槽的分类。
当第一章基础掌握差不多了,然后再学习了组件的开发,那么你就可以开发简单的Vue项目,路由文章还没有更新,学习完Router后,就可以开发实战项目了。
1. kebab-case
my-component-name
2. PascalCase
MyComponentName
命名使用kebab-case (短横线分隔命名) 命名: 如果 使用 驼峰命名 postTitle ==》 post-title
默认我们传递时是Prop 为 字符串数组形式;为了更好的管理Prop, 我们可以以对象的形式进行管理。
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
Vue.component('my-component', {
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。
父级组件状态发生变化,子组件会随着父级组件变化为最新的状态。反过来不可以,子级组件发生变化,父级组件跟真变化,这样Vue会发出警告
默认可以给子组件传递任意的 Attribute ,然后子组件接收使用 Attribute。 但有时,我们想限制给子组件传递 Attribute, 那么该怎么做呢?
这样做的目的是为了什么呢? 别人在接手开发时,他只能传递指定的Props,不能传递其它的Props
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
1.事件名不存在任何自动化的大小写转换。 2.触发的事件名需要完全匹配监听这个事件所用的名称。 Vue 官方推荐 事件命名采用 kebab-case
this.$emit('to-A','参数')
<A @to-A='父级的自定义事件'></A>
methods:{
receiveSon:(e){
接收传递过来的参数
console.log(e)
}
}
所谓插槽:就是 在Vue中, 子组件定义了
<slot></slot>
, 它就相当于在父组件占据了位置,你可以往里面插入任何数据,可以定义多个slot。 slot 又分为:具名slot 默认slot 作用域slot
所谓具名插槽, 就是 插槽有自己的name, 在子组件中定义好,可以在父组件中通过指定来渲染 格式: 使用:
v-slot
指令// 子组件
<template>
<div>
//具名插槽
<slot name="head"></slot>
<h1>Son 组件</h1>
// 默认插槽
<slot></slot>
<Button @click="toParent">子向父 传递值</Button>
<slot name="foot"></slot>
</div>
</template>
//父组件
<template>
<div>
<h1>Father 组件</h1>
<hr>
<Son @receiveToParent="receiveToSon">
<template v-slot>
<h1>我是默认插槽</h1>
</template>
<template v-slot:head>
<hr>
<h1>我是具名插槽 head</h1>
<hr>
</template>
<template v-slot:foot>
<hr>
<h1>我是具名插槽 foot</h1>
<hr>
</template>
</Son>
</div>
</template>
有时,我们可能遇到这种需求: 在插槽内容中能够访问子组件数据,那么就用到作用域插槽。 简单的说: 父组件在子组件中使用子组件提供的prop数据 如何使用呢? 1.通过 在子组件 slot 中动态绑定数据
<slot :obj='obj'></slot>
v-slot:default = "son"
使用prop中数据 {{son.obj.name}}
(2)v-slot= "{obj}"
使用prop中数据 {{obj.name}}
优先采用第二种,这样可以使模板更简洁,尤其是在该插槽提供了多个 prop 的时候。
默认插槽的缩写语法不能和具名插槽混用会导致作用域不明确
出现多个插槽,可以要使用多个template
// 子组件
<template>
<div>
<slot :obj='obj'></slot>
<slot :obj='games'></slot>
</div>
</template>
<script>
export default {
name: 'Son',
data () {
return {
name: '测试',
obj: {
name: '张三',
age: 22
},
games: {
version: '版本:0.1',
name: '王者农药'
}
}
},
}
</script>
//父组件
<template>
<div>
<h1>Father 组件</h1>
<hr>
<Son @receiveToParent="receiveToSon">
// 通过v-slot:自定义 = “{}” 使用prop数据
<template v-slot:default= "{obj}">
{{obj.name}}
</template>
<templatev-slot:other= "{games}">
{{games.name}}
</template>
<template v-slot:head>
<hr>
<h1>我是具名插槽 head</h1>
<hr>
</template>
</Son>
</div>
</template>
<template #head>
<hr>
<h1>我是具名插槽 head</h1>
<hr>
</template>
keep-alive
来达到缓存效果可能你遇到这种需求,第一次点击了首页,然后点击个人主页,返回的时候,首页组件会被重新加载,浪费必要的性能问题,想解决此类问题,Vue中 提供了 在 组件上 动态绑定
keep-alive
来处理
{
path: '/',
name: 'Father',
component: Father,
meta: {
keepAlive: true // 需要缓存
}
}
<el-col :span="24" class="content-wrapper">
<transition name="fade" mode="out-in">
//这里需要缓存,使用keep-alive标签包裹
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
//这里不需要缓存
<router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>
</el-col>