1.组件注册
- 组件名:驼峰命名法和短横线命名法
- 全局注册:全局注册后,可以在任意根实例中使用
import common from '@/components/common'
Vue.component('common', common)
- 局部注册: 在根实例的components引入你想要的组件即可
import HelloWorld from '../components/HelloWorld.vue'
import KebabCase from '../components/kebab-case.vue'
export default {
components: { HelloWorld, KebabCase },
}
2.prop
- 驼峰命名的prop名需要使用其等价的短横线命名法,除了字符串
- 传入一个数字,即使是静态的,我们也需要使用v-bind来告诉vue,(v-bind)可省略
<BaseFooter :footer-number="45"></BaseFooter>
- 传入一个布尔值,没有值得情况下意为true,需要传入静态时,使用v-bind来告诉vue(v-bind)可省略
<BaseTime :status="false"></BaseTime> <BaseTime status></BaseTime> <BaseTime :status="status"></BaseTime>
- 传入一个数组,静态数组也需要使用v-bind来告诉vue(v-bind)可省略
- 传入一个对象,静态数组也需要使用v-bind来告诉vue(v-bind)可省略
- 传入一个对象的所有property
<span>{{name}}</span> <span>{{age}}</span> <span>{{city}}</span> props: { name: String, age: Number, city: String } <BaseTime v-bind="post" ></BaseTime> post: { name: 'lily', age: 18, city: '山西' },
- .单向数据流 父组件向子组件传值:父级prop的更新流动到子组件,但是反过来不行。每次父组件的变更,子组件的prop都将会刷新为最新的值,想要内部子组件改变prop,有以下方法
<template> <div> <span>{{insertage}}</span> <button @click="addage">增加年龄</button> </div> </template> <script> export default { props: { age: Number, }, data () { return { insertage: this.age } }, methods: { addage () { this.insertage++ } } } </script>
- prop验证
props: { TitleName: { type: [String, Boolean], //数据类型,可以是多个 required: true,//必填的 default: '题目' //默认值 }, //对象和数组默认值必须从一个函数中获取 post: { type: Object, default: () => ({ name: 'xxx', sex: '女' }) }, postarray: { type: Array, default: function () { return [{title: '123', context: '456'}, {title: '123', context: '456'}] } }, }
- 非Prop的Attribute。 对于绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入
type="text"
就会替换掉type="date"
并把它破坏! 庆幸的是,class
和style
attribute 会稍微智能一些,即两边的值会被合并起来。 当我们遇到3个组件间的传值A-B-C,需要将值从C-传到A,但是B没有使用,那么在B组件可以使用&attrs来将值从上级传到下级<script> let vm = new Vue({ el: '#app', data: { msg: '100' }, components: { 'MyButton': { // props: ['msg'], template: `<div>B<my-input v-bind="$attrs"></my-input></div>`, components: { 'MyInput': { props: ['msg'], template: '<div>C{{msg}}</div>' } } }, } }) </script>
3.自定义事件
- 事件名。推荐使用kebab-case的事件名,v-on事件监听器在DOM模板中会自动转换为全小写的
- 自定义组件的v-model
<template> <div class="hello"> <input type="text" :value="value" @input="$emit('input', $event.data)"> </div> </template> <script> export default { model: { prop: 'value', event: 'input' }, props: { value: String } } </script> <common v-model="value" ></common>
实现效果如左图。vue3中可以多个v-model绑定,后续文档会更新
-
将原生事件绑定到组件上
-
修饰符
4.插槽
- 插槽内容
- 编译作用域 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
- 后备内容 插槽内的内容为默认内容,父组件引入带有插槽的子组件,若设置的内容即显示父组件设置的内容,没有则显示插槽的默认内容
- 具名插槽(可以用#代替v-slot:)
<slotcom> <template v-slot:left>vue组件</template> <template v-slot:center>vue插槽</template> <template #right> vue </template> </slotcom> <template> <div class="header"> <slot name="left">logo</slot> <slot name="center">题目</slot> <slot name="right">搜索</slot> </div> </template>
-
作用于插槽,想要让插槽访问子组件的内容(如果子组件默认只有一个插槽,则父组件的:name可省略)
子组件 <template> <div> <slot name="name" v-bind:user="user">{{user.lastname}}</slot> </div> </template> <script> export default { data () { return { user: { firstname: '12', lastname: '456' } } } } </script> 父组件 <slotwork v-slot:name="userrule">{{userrule.user.firstname}}</slotwork>
子组件 <template> <div> <slot name="header" v-bind:user="user1">{{user1.lastname}}</slot> <slot v-bind:user="user">{{user.lastname}}</slot> </div> </template> <script> export default { data () { return { user1: { firstname: 'lili', lastname: 'sarh' }, user: { firstname: 'tom', lastname: 'jonn' } } } } </script> 父组件 <slotwork> <template v-slot="userrule">{{userrule.user.firstname}}</template> <template v-slot:header="userrule">{{userrule.user.firstname}}</template> </slotwork>
- 动态插槽名
<template> <div> <div v-for="(item,index) in arrayname" :key="index"> <slot :name="item">第{{index+1}}个插槽</slot> </div> </div> </template> <script> export default { props: { arrayname: Array }, data () { return { } } } </script> 父组件 <slotdyna :arrayname="arrayname"> <template v-slot:[slotname]> <h2>我是动态插槽</h2> </template> </slotdyna> export default { components: { HelloWorld, KebabCase, slotcom, slotwork, slotdyna }, data () { return { arrayname: [ 'name1', 'name2', 'name3' ] } }
5.动态组件&异步组件
- 使用<keep-alive>标签将组建包裹起来,这样遇到标签类的组件时,第一次进入会将所有的标签内容缓存起来
6.处理边界问题
后续继续更新
7.父子组件间传值
- 父组件通过props向子组件传值
- 父组件通过ref调用子组件的方法
- 父组件通过emit调用子组件的方法
- 子组件通过ref向父组件传值
- 子组件在mounted里通过emit向父组件传值
- 子组件通过this.$parent.event调用父组件的方法
- 子组件通过props定义一个函数调用父组件的方法