前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue组件高级(下)

vue组件高级(下)

作者头像
岳泽以
发布2022-10-26 17:34:37
1.8K0
发布2022-10-26 17:34:37
举报
文章被收录于专栏:岳泽以博客

1. ref引用

1.1 ref引用

ref用来辅助开发者在不依赖jQuery的情况下,获取DOM元素或组件的引用。

每个vue的组件实例上,都包含一个 refs对象,里面存储着对应的DOM元素或组件的引用。默认情况下,组件的 refs指向一个空对象。

代码语言:javascript
复制
<template>
<h3>MyRef组件</h3>
<button @click="getRef">获取$refs引用</button>
</template>

<script>
export default{
    methods:{
        getRef(){console.log(this)} //this代表当前组件的实例对象,this.$rtefs默认指向空对象
    }
}
</script>

1.2 使用ref引用DOM元素

如果想要使用ref引用页面上的DOM元素,则可以按照如下的方式进行操作:

代码语言:javascript
复制
<!-- 使用ref属性,为对应的DOM添加引用名称 -->
<template>
<h3 ref="myh3">MyRef组件</h3>
<button @click="getRef">获取$refs引用</button>
</template>

<script>
export default{
    methods:{
        getRef(){
            console.log(this.$refs.myh3)
            this.$refs.myh3.style.color='red'
        } 
}
</script>

1.3 使用ref引用组件实例

如果想要使用ref引用页面上的组件实例,则可以按照如下的方式进行操作:

代码语言:javascript
复制
<!-- 使用ref属性为对应的组件实例添加引用名称 -->
<template>
<MyCounter ref="counterRef"></MyCounter>
<button @click="getRef">获取$refs引用</button>
</template>

<script>
export default{
    methods:{
        getRef(){
            //通过this.$refs.引用名称,可以引用组件的实例
            console.log(this.$refs.counterRef)
            //引用到组件的实例之后,就可以调用组件上的methods方法
            this,$refs.counterRef.add()
        }
    }
}
</script>

1.4 控制文本框和按钮的按需切换

通过布尔值 inputVisible来控制组件中的文本框与按钮的按需切换:

代码语言:javascript
复制
<template>
<input type="text" v-if="inputVisible">
<button v-else @click="showInput">展示input输入框 </button>
</template>

<script>
export default{
    data(){
        return{
            //控制文本框和按钮的按需切换
            inputVisible:false
        }
    },
    methods:{
        showInput(){//切换布尔值,显示文本框
            this.inputVisible = true
        }
    }
}
</script>

1.5 让文本框自动获得焦点

当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加ref引用,并调用原生DOM对象的 .focus()方法即可。

代码语言:javascript
复制
<template>
<input type="text" v-if="inputVisible" ref="ipt">
<button v-else @click="showInput">展示输入框</button>
</template>


<script>
methods:{
    showInput(){
        this.inputVisible = true
        //获取文本框的DOM引用,并调用.focus()使其自动获得焦点
        this.$refs.ipt.focus()
    },
}
</script>

但是因为这个操作是异步的,所以会报错,可以使用下一个方法来解决。

1.6 this.$nextTick(cb)方法

组件的$nextTick(cb)方法,会把cb回调推迟到下一个DOM更新周期之后执行。

通俗的理解就是:等组件的DOM异步重新渲染完成后,再执行cb回调函数,从而能保证cb回调函数可以操作到最新的DOM元素。

代码语言:javascript
复制
<template>
<input type="text" v-if="inputVisible" ref="ipt">
<button v-else @click="showInput">展示输入框</button>
</template>


<script>
data() {
    return {
      inputVisible: false,
    };
},  
methods:{
    showInput(){
        this.inputVisible = true
        //把对input文本框的操作,推迟到下次更新DOM之后,否则页面上根本不存在文本框元素
        this.$nextTick(()=>{
        this.$refs.ipt.focus()          
        })
    },
}
</script>

2. 动态组件

动态组件指的是动态切换组件的显示与隐藏。vue提供了一个内置的 <component>组件,专门用来实现组件的动态渲染。

  1. <component>是组件的占位符
  2. 通过is属性动态指定要渲染的组件名称
  3. <component is="要渲染的组件的名称"></component>

2.1 实现动态组件渲染

代码语言:javascript
复制
<template>
//点击按钮,动态切换组件的名称
    <button @click="comName='MyNamic1'">组件1</button>
    <button @click="comName='MyNamic2'">组件2</button>
//通过is属性,动态指定要渲染的组件的名称
    <component :is="comName"></component>
</template>

data(){
    return{
    comName:'MyNamic1'//当前渲染的组件名称
    }
}

2.2 使用keep-alive保持状态

默认情况下,切换动态组件时无法保持组件的状态,此时可以使用vue内置的 <keep-alive>组件保持动态组件的状态。

代码语言:javascript
复制
<keep-alive>
    <component :is="comName"></component>
</keep-alive>  

3. 插槽

插槽(slot)是vue为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。

可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

3.1 基础用法

在封装组件时,可以通过 <slot>元素定义插槽,从而为用户预留内容占位符。

代码语言:javascript
复制
<template>
<p>这是MyCom1组件的第一个p标签</p>
<!-- 通过slot标签,为用户预留内容占位符(插槽) -->
<slot></slot>
<p>这是MyCom1组件的最后一个p标签</p>
</template>
代码语言:javascript
复制
<MyCom1>
<!-- 在使用MyCom1组件时,为插槽指定具体的内容 -->  
    <p>用户自定义内容</p>
</MyCom1>

3.1.1 没有预留插槽的内容会被丢弃

如果在封装组件时没有预留任何 <slot>插槽,则用户提供的任何自定义内容都会被丢弃。

代码语言:javascript
复制
<template>
<p>这是MyCom1组件的第一个p标签</p>
<!-- 封装组件时,没有预留任何插槽 -->
<p>这是MyCom1组件的最后一个p标签</p>
</template>
代码语言:javascript
复制
<MyCom1>
<!-- 下面用户自定义的内容会被丢弃 -->  
    <p>用户自定义内容</p>
</MyCom1>

3.1.2 后备内容

封装组件时,可以为预留的 <slot>插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。

代码语言:javascript
复制
<template>
<p>这是MyCom1组件的第一个p标签</p>
<slot>后备内容</slot>
<p>这是MyCom1组件的最后一个p标签</p>
</template>

3.2 具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个 插槽指定具体的 name 名称。这种带有具体 名称的插槽叫做“具名插槽”。

代码语言:javascript
复制
<template>
<header>
    <!-- 页头 -->
    <slot name="header"></slot>
</header>
<main>
    <!-- 主体 -->
    <slot name="main"></slot>  
</main>
<footer>
    <!-- 页脚 -->
    <slot name="footer"></slot>  
</footer>
</template>

注意:没有指定name名称的插槽,会有隐含的名称叫做"default"

3.2.1 为具名插槽提供内容

在向具名插槽提供内容的时候,我们可以在一个template元素上使用v-slot指令,并以v-slot的参数的形式提供名称:

代码语言:javascript
复制
    <MyAritcle>
      <template v-slot:header> <h1>静夜思</h1></template>
      <template v-slot:default>
        <p>床前明月光,疑是地上霜</p>
        <p>举头望明月,低头思故乡</p>
      </template>
      <template v-slot:footer> <p>作者:李白</p></template>
    </MyAritcle>

3.2.2 具名插槽的简写形式

根v-on和v-bind一样,v-slot也有缩写,即把参数之前的所有内容(v-slot:)替换为字符 #

代码语言:javascript
复制
    <MyAritcle>
      <template #header> <h1>静夜思</h1></template>
      <template #default>
        <p>床前明月光,疑是地上霜</p>
        <p>举头望明月,低头思故乡</p>
      </template>
      <template #footer> <p>作者:李白</p></template>
    </MyAritcle>

3.3. 作用域插槽

在封装组件的过程中,可以为预留的插槽绑定 props 数据,这种带有 props 数据的 <slot> 叫做“作用域插槽”。

代码语言:javascript
复制
<!-- 预留插槽 -->
<slot :info="infomation"></slot>

<!-- 使用自定义组件 -->
<MyTest>
<template v-slot:default="scope">
{{scope}}  
</template>
</MyTest>

3.3.1 解构作用域插槽的prop

作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程。

代码语言:javascript
复制
    <MyTable>
      <template #default="{ user }">
      <!-- 使用作用域插槽的数据 -->
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
      </template>
    </MyTable>

3.3.2 声明作用域插槽

在封装MyTable组件的过程中,可以通过作用域插槽把表格每一行的数据传递给组件的使用者。

代码语言:javascript
复制
    <tbody>
      <!-- 循环渲染数据 -->      
      <tr v-for="item in list" :key="item.id">
      <!-- 下面的slot是一个作用域插槽 -->        
        <slot :user="item"></slot>
      </tr>
    </tbody>

3.3.3 使用作用域插槽

在使用MyTable组件时,自定义单元格的渲染方式,并接收作用域插槽对外提供的数据。

代码语言:javascript
复制
    <MyTable>
      <!-- 接收作用域插槽对外提供的数据 -->  
      <template #default="scope">
      <!-- 使用作用域插槽的数据 -->
        <td>{{ scope.user.id }}</td>
        <td>{{ scope.user.name }}</td>
      </template>
    </MyTable>

4. 自定义指令

vue官方提供了v-for、v-model、v-if等常用的内置指令。除此之外vue还允许开发者自定义指令。

vue中的自定义指令分为两类,分别是:

  • 私有自定义指令
  • 全局自定义指令

4.1 声明私有自定义指令的语法

在每个vue组件中,可以在directives节点下声明私有自定义指令。

代码语言:javascript
复制
directives:{
    //自定义一个指令
    focus:{
        //当被绑定的元素插入到DOM元素中时,自动触发mounted函数
        mounted(el){
            el.focus()//让被绑定的元素自动获得焦点
        }
    }
}

4.2 使用自定义指令

在使用自定义指令时,需要加上v-前缀。

代码语言:javascript
复制
<!-- 声明自定义指令时,指令的名字是focus --> 
<!-- 使用自定义指令时,需要加上v- 指令前缀 -->
<input v-focus>

4.3 声明全局自定义指令的语法

全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明,示例代码如下:

代码语言:javascript
复制
const app = Vue.createApp({})

//注册一个全局自定义指令 ‘v-focus’
app.directive('focus',{
    //当被绑定的元素插入到DOM中时,自动触发mounted函数
    mounted(el){
        el.focus()
    }
})

4.4 updated函数

mounted函数只在元素第一次插入DOM时被调用,当DOM更新时mounted函数不会被触发。updated函数会在每次DOM更新完成后被调用。

代码语言:javascript
复制
app。directive('focus',{
    mounted(el){//第一次插入DOm时触发这个函数
        el.focus()
    },
    updated(el){//每次DOM更新时都会触发updated函数
        el.focus()
    }
})

注意:在vue2的项目中使用自定义指令时,【mounted -> bind】【updated -> update】

4.5 函数简写

如果mounted和updated函数中的逻辑完全相同,则可以简写如下格式:

代码语言:javascript
复制
app.directive('focus',(el)=>{
    el.focus()
})

4.6 指令的参数值

在绑定指令时,可以通过“等号”的形式为指令绑定具体的参数值。

代码语言:javascript
复制
<input type="text" v-model.number="count" v-focus v-color="'red'">
<p v-color="'blue'"> {{count}}</p>
<button @click="count++">+1</button>

//自定义v-color指令
app.directive('color',(el,binding)=>{
    //binding.value是通过等号为指令绑定的值
    el.style.color=binding.value
})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 10 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. ref引用
    • 1.1 ref引用
      • 1.2 使用ref引用DOM元素
        • 1.3 使用ref引用组件实例
          • 1.4 控制文本框和按钮的按需切换
            • 1.5 让文本框自动获得焦点
              • 1.6 this.$nextTick(cb)方法
              • 2. 动态组件
                • 2.1 实现动态组件渲染
                  • 2.2 使用keep-alive保持状态
                  • 3. 插槽
                    • 3.1 基础用法
                      • 3.1.1 没有预留插槽的内容会被丢弃
                      • 3.1.2 后备内容
                    • 3.2 具名插槽
                      • 3.2.1 为具名插槽提供内容
                      • 3.2.2 具名插槽的简写形式
                    • 3.3. 作用域插槽
                      • 3.3.1 解构作用域插槽的prop
                      • 3.3.2 声明作用域插槽
                      • 3.3.3 使用作用域插槽
                  • 4. 自定义指令
                    • 4.1 声明私有自定义指令的语法
                      • 4.2 使用自定义指令
                        • 4.3 声明全局自定义指令的语法
                          • 4.4 updated函数
                            • 4.5 函数简写
                          • 4.6 指令的参数值
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档