Vue笔记(三)深入组件

组件注册

组件注册有两种方式:

  1. 全局注册
    可以使用Vue应用实例的.component()方法,让组件在当前Vue应用中全局可用,.component()方法可以被链式调用。全局注册的组件可以在此应用的任意组件的模版中使用。

    javascript 复制代码
    import { createApp } from 'vue'
    import { MyComponent } from './MyComponent.vue'
    
    const app = createApp({
    })
    app.component('MyComponent',MyComponent)
  2. 局部注册
    局部注册的组件需要在它的父组件中显示导入,并且只能在父组件中使用,依赖关系更加明确。

    javascript 复制代码
    <script>
    import MyComponent from './MyComponent'
    
    export default{
        components:{
            MyComponent
        }
    }
    </script>
    
    <template>
        <MyComponent />
    </template>s

Props

一个组件需要显示声明它所接受的props。声明props的方式有两种:

  1. 字符串数组

    javascript 复制代码
    export default{
        props:['animal','zoo'],
        created(){
            //props 会暴露到 this 上
            console.log(this.animal);
            console.log(this.zoo);
        }
    }
  2. 对象的形式

    javascript 复制代码
    export default{
        props:{
            title:string,
            age:number
        }
    }

静态Prop、动态Prop

  1. 静态Prop传参形式

    javascript 复制代码
    <child-component title="this is title" />
  2. 动态Prop传参形式,使用v-bind或缩写:来进行动态绑定

    javascript 复制代码
    <child-component :title="自定义的变量"/>

事件

触发与监听事件

  1. 触发(子组件):在组件模版表达式中,可以直接使用$emit方法触发自定义事件

    javascript 复制代码
    //1. 第一种触发方式
    <button @click="$emit('click')">触发click事件</button>
    //2. 第二种触发方式,函数触发, this.$emit
    export default{
        methods:{
            submit(){
                this.$emit('click');
            }
        }
    }
  2. 父组件可以通过v-on@来监听事件

    javascript 复制代码
    //1. 触发
    <child-component @click="alert(1)" />
    //2. 事件监听器也支持 .once 修饰符
    <child-component @click.once="alert(1)" />

事件参数

可以给触发的事件传入参数,父组件可以处理传入的参数

  1. 子组件传入参数

    javascript 复制代码
    <button @click="emit('click',1,2)">传入参数给父组件</button>
  2. 父组件处理参数

    javascript 复制代码
    <child-component @click="fun1"/>
    
    //处理参数的方法
    methods:{
        fun1:function(var1,var2){
            console.log(var1);
            console.log(var2);
        }
    }

插槽 Slots

  1. 父组件传入,插槽内容可以是任意合法的模版内容,不局限于文本,可以传入多个HTML元素,甚至组件

    javascript 复制代码
    <child-component>
        传入内容
    </child-component>
  2. 子组件插槽占位

    javascript 复制代码
    <h1>
        <slot></slot>
    </h1>

插槽渲染作用域

插槽可以访问到父组件的数据作用域,因为插槽内容本身是在父组件中定义的。插槽无法访问子组件的数据。

插槽默认内容

如果父组件没有提供任何内容,可以为插槽指定默认内容

javascript 复制代码
<button>
    <slot>默认内容</slot>
</button>

具名插槽

  1. 子组件为插槽指定名称,没有提供name<slot>会隐式地命名为default

    javascript 复制代码
    <div>
        <slot name="header"></slot>
        <slot name="footer"></slot>
        <slot></slot>
    </div>
  2. 父组件指定插槽名称传入内容,v-slot简写#

    javascript 复制代码
    <child-component>
        <template #header>
            This is header
        </template>
        <template #footer>
            This is footer
        </template>
        <template #default>
            This is default
        </template>
    </child-component>

动态插槽名

可以使用动态的插槽名,传给子组件内容

javascript 复制代码
<child-component>
    <template v-slot:[defineSlotName]>
    </template>
    
    <template #[defineSlotName]>
    </template>
</child-component>

作用域插槽

某些场景下插槽的内容想要同时使用父组件域内和子组件域内的数据,子组件可以在渲染时将一部份数据提供给插槽

  1. 默认插槽

    javascript 复制代码
    //子组件插槽插入数据
    <div>
        <slot :name="zqq" :age="18">
        </slot>
    </div>
    //父组件使用
    <child-component v-slot="vslot">
        {{ vsolt.name }} {{ vsolt.age }}
    </child-component>
  2. 具名作用域插槽

    javascript 复制代码
    //子组件插槽传入数据,name是vue特别保留的attribute,不会作为props传递给插槽
    <slot name="header" message="hello">
    </slot>
    //父组件使用
    <child-component>
        <template #header="data">
            {{ data s}}
        </template>
    </child-component>

依赖注入

一个父组件相当于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级多深,都可以注入由父组件提供给整条链路的依赖。关键字:provideinject

  1. provide(提供),为后代组件提供数据

    javascript 复制代码
    //为后代组件提供数据
    export default{
        privode:
        {
            message:'hello'
        }
    }
    //为后代组件提供data()定义的数据属性,以函数形式使用provide
    export default{
        data(){
            return{
                message:'hello'
            }
        },
        provide:(){
            return{
                message:this.message;
            }
        }
    }
    
    //在应用层为全部组件提供依赖
    import { createApp } from 'vue'
    
    const app = createApp({})
    // message是注入的名称,hello是值
    app.provide('message','hello');
  2. Inject(注入),子组件注入父组件(隔代父组件也可以)提供的依赖

    javascript 复制代码
    export default{
        inject:['message'],
        data(){
            return{
                //注入会在组件自身状态之前被解析,可以通过this访问注入的值
                localMessage:this.message
            }
        }
    }

注入别名和默认值

javascript 复制代码
export{
    inject:{
        // localMessage是自定义的本地别名,后续访问注入的内容,使用this.localMessage
        localMessage:{
            from:'message',
            default:'default' //可以指定默认值
        }
    }
}

和响应式数据配合使用

为了保证注入方和供给方之间的响应性链接,需要使用computed()函数提供一个计算属性

javascript 复制代码
import default{
    data(){
        return{
            message:'hello'
        }
    }
    provide(){
        return{
            message:computed(() => this.message)
        }
    }
    }
}

异步组件

在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件,Vue提供了defineAsyncComponent方法来实现

javascript 复制代码
const AsyncComp = defineAsynComponet(() => {
    return new Promise(() =>{
        //...从服务器获取组件
        resolve(/*获取到的组件*/);
    })
})

导入Vue单文件组件

javascript 复制代码
import { defineAsyncComponent } from 'vue'

const AsyncComp defineAsyncComponent(() => import('./components/MyComponent.vue'))

最后得到的AsyncComp是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。它会将受到的props和插槽传给内部组件,所以可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。

异步组件注册

  1. 全局注册

    javascript 复制代码
    app.component('MyComponent',defineAsyncComponent(() => import('./components/MyComponent.vue'))
  2. 局部注册

    javascript 复制代码
    <script>
    impoty { defineAsyncComponent } from 'vue'
    
    export default{
        components{
            MyComponent:defineAsyncComponent(() = import('./components/MyComponent.vue'))
        }
    }
    </script>

加载与错误状态

javascript 复制代码
const AsyncComp = defineAsyncComponent({
    //加载组件函数
    loader:() => import(',MyComponent'),
    //展示加载组件的延迟时间,默认200ms
    delay:200,
    //加载失败后展示的组件
    errorComponent:ErrorComponent,
    //加载组件超时时间,默认没有超时时间,如果超市,会显示 加载失败展示的组件
    timeOut: 3000
})
相关推荐
这颗橘子不太甜QAQ3 分钟前
Husky使用技巧
javascript·git·代码规范
장숙혜15 分钟前
ElementUi的tabs样式太难修改,自定义tabs标签页
前端·javascript
火星思想33 分钟前
Promise 核心知识点(非基础)
前端·javascript·面试
前端大白话34 分钟前
炸裂!10个 React 实战技巧,让你的代码从“青铜”秒变“王者”
前端·javascript·react.js
10年前端老司机41 分钟前
微信小程序模板语法和事件
前端·javascript·微信小程序
攻城狮的大师兄42 分钟前
红宝书(第四版)通读之查漏补缺
javascript
无敌小茶1 小时前
Linux学习笔记之环境变量
linux·笔记
苹果酱05671 小时前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
Deepsleep.1 小时前
react和vue的区别之一
javascript·vue.js·react.js
突头小恐龙1 小时前
Chrome devTools - Lighthouse
前端·javascript·chrome