第十八节:带你梳理Vue2: Vue组件中的注意事项和特例

news2024/11/20 21:31:51

1. Vue组件名推荐使用驼峰命名

现在我们来看看为什么在Vue中推荐注册组件时使用驼峰写法, 在了解这个之前,相信大家应该都能明白为什么在Vue中, 局部组件的使用频率高于全局组件.

推荐使用驼峰写法也是和局部组件有关系

我们先看一个示例

<div id="app">
    <!-- 3. 在注册了局部组件的实例中使用局部组件 -->
    <my-component></my-component>
</div>


<script>
    // 1. 创建局部组件的选项对象
    let MyComponent = {
        template: `
            <div>
           		<h2>局部组件</h2>
            </div>
        `,
    }

    const vm = new Vue({
        el:"#app",
        // 2. 将选项对象注册为局部组件
        components: {
            "my-component": MyComponent
        }

    })
</script>

通过前面的学习,这个例子应该已经熟悉了,

  1. 首先定义一个选项对象myComponent
  2. 在Vue实例中通过components注册为局部组件
  3. 在HTML模板中通过<my-component>自定义标签使用组件

示例中,不使用驼峰命名组件,依然可以正常运行,那么为什么组件名还要推荐使用驼峰命名


那先看下面几点:
  1. 首先在定义选项对象的时候使用的变量名绝对不可以是连字符, 这是标识符命名规范,因此如果要使用连字符就必须加引号

  2. 在注册组件时,components中的属性名my-component就是我们的组件名称, 其值MyComponent就是将谁注册为组件


好此时大家想一想,如果组件名和选项对象的变量名一样会怎么样

是不是就会变成如下的写法

const vm = new Vue({
    el:"#app",
    components: {
        MyComponent: MyComponent
    }
})

在思考一下,我们之前在学习ES6的时候讲过在定义对象的是有一种简便写法. 当属性跟值长得一样时,就可以简写
因此这里我们就可以简写为

const vm = new Vue({
    el:"#app",
    components: {
        MyComponent
    }
})

所以,为什么推荐使用驼峰写法,这里就应该可以看出端倪了, 如果我们定义组件的组件名使用驼峰写法,也就是和需要被注册为组件的选项对象一致时,我们注册组件将变得简单

如果此时需要注册n个组件,就可以如下写法

const vm = new Vue({
    el:"#app",
    components: {
        one,two,three,four.....
    }
})

是不是感觉很优雅,


总结:

  1. 在定义组件时推荐使用驼峰写法,最好组件名和需要被创建为组件的选项对象名一致
  2. 使用组件时推荐使用连字符

2. 组件中的template 选项

尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。

Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。


2.1 使用script标签将template模板分离出来

在使用script标签将template模板分离出来时,要注意script标签的type类型选择,

<div id="app">
    <!-- 3. 使用组件 -->
    <my-component></my-component>
</div>

<!-- 组件模板 -->
<!-- 注意: 如果不添加type属性,可能会显示效果,但是会报错, -->
<script id="myComponent" type="text/x-template">
    <div>
        <h2>我想被创建为局部组件</h2>
    </div>
</script>


<script>
    // 1. 创建组件选项对象
    let MyComponent = {
        // 此时的模板template的值就是一个选择器
        template: "#myComponent",

    }


    const vm = new Vue({
        el:"#app",
        // 2. 注册组件
        components: {
            "my-component": MyComponent
        }

    })


</script>

template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译。

注意:

使用<script> 标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>标签内定义的内容。


2.2 使用template 标签处理模板

如果使用<template>标签,则不需要指定type属性。

<div id="app">
    <!-- 3. 使用组件 -->
    <my-component></my-component>
</div>

<!-- 组件模板 -->
<!-- template标签不需要指定type,标签的本意就是告诉浏览器这是模板 -->
<template id="myComponent">
    <div>
        <h2>我想被创建为局部组件</h2>
    </div>
</template>


<script>
    // 1. 创建组件选项对象
    let MyComponent = {
        // 此时的模板template的值就是一个选择器
        template: "#myComponent",

    }


    const vm = new Vue({
        el:"#app",
        // 2. 注册组件
        components: {
            "my-component": MyComponent
        }

    })


</script>

在理解了组件的创建和注册过程后,我建议使用<script><template>标签来定义组件的HTML模板。

这使得HTML代码和JavaScript代码是分离的,便于阅读和维护。

另外,在Vue.js中,可创建.vue后缀的文件,.vue文件就是一个组件,称为单文件组件,这个内容我会在后面的文章介绍。


3. 组件选项对象中的特例

组件中的选项基本与实例选项对象一致, 但是有两个选项是特例,分别为el 和 data 属性

这个说的特例是指组件的选项对象和实例选项对象使用的不同


3.1 在组件中不能使用el

el属性的作用我们都了解了, 就是在实例中使用,决定Vue需要接管的DOM元素. 组件是在实例中使用,所以不需要el属性,
如果一个选项对象被注册为组件,添加el属性就会造成报错,

// 1. 创建局部组件的选项对象
let MyComponent = {
    el:"",
    template: "#myComponent",

}


const vm = new Vue({
    el:"#app",
    // 2. 将选项对象注册为局部组件
    components: {
        "my-component": MyComponent
    }
})

// 会报错, 告诉你el属性只能在实例中使用

组件使用el选项报错.png

可以通过报错信息了解到, el选项只能使用在new创建的vue实例上


3.2 组件中data属性值必须是一个函数,

组件中的data选项必须是一个函数,返回一个数据对象.

为什么需要是一个函数,而不可以像Vue实例的选项对象一样是一个对象呢


3.2.1 组件data属性值如果是一个对象的问题

不能使用对象的原因:

  1. 首先因为组件会被多次复用,
  2. 而对象是引用数据类型,如果组件数据使用对象的话,那么组件所有的复用都共享这些数据,

这样就会出现问题,看代码:

示例代码如下:

<div id="app">
    <!-- 3. 使用组件 -->
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>

<template id="myComponent">
    <div>
        <h2>组件{{num}}</h2>
        <button @click="handleClick">点击+1</button>
    </div>
</template>


<script>
    // 组件共享数据
    let data = {
        num : 10
    }

    // 1. 选项对象
    let MyComponent = {
        template: "#myComponent",
        data: function(){
            return data
        },
        methods: {
            handleClick(){
                this.num++
            }
        }
    }

    const vm = new Vue({
        el:"#app",
        // 2. 注册组件
        components: {
            "my-component": MyComponent
        }

    })
</script>

示例结果:

组件data数据.png

实例说明:

  1. 如果在组件的data中直接写对象就会报错,
  2. 因此我们将data函数中返回的对象提取出来.这样所有的组件都共用一个数据对象.
  3. 一次来模拟组件data选项值为对象的情景

通过案例我们就会发现如果所有的组件都共享数据,当有一个组件中的数据发生了变化,所有的组件显示的数据都会发生变化, 这不是我们想要的,


3.2.2 解决组件共享数据的问题

所以组件的data数据属性才会需要函数,每次初始化化的时候都会执行函数,将返回的结果作为组件的数据,
这样每次执行函数都会给每个组件创建一个独立的数据

<div id="app">
    <!-- 3. 使用组件 -->
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>

<template id="myComponent">
    <div>
        <h2>组件{{num}}</h2>
        <button @click="handleClick">点击+1</button>
    </div>
</template>


<script>
 
    // 1. 选项对象
    let MyComponent = {
        template: "#myComponent",
        data: function(){
            // 每次函数执行都会返回新的数据,非共享数据
            return {
                num : 10
            }
        },
        methods: {
            handleClick(){
                this.num++
            }
        }
    }


    const vm = new Vue({
        el:"#app",
        // 2. 注册组件
        components: {
            "my-component": MyComponent
        }

    })


</script>

显示结果:

组件data数据方法.png

通过示例就会发现, 当一个组件数据发生改变的时候, 其他组件的数据不会变化,因为每个组件都有自己独立的数据


3.3 组件的命名

当注册组件 (或者 prop) 时,可以使用 kebab-case (短横线分隔命名)、camelCase (驼峰式命名) 或 PascalCase (单词首字母大写命名)。

// 在组件定义中
components: {
  // 使用 kebab-case 注册
  'kebab-cased-component': { /* ... */ },
  // 使用 camelCase 注册 俗称小驼峰
  'camelCasedComponent': { /* ... */ },
  // 使用 PascalCase 注册 俗称大驼峰
  'PascalCasedComponent': { /* ... */ }
}

在 HTML 模板中,请使用 kebab-case:

<!-- 在 HTML 模板中始终使用 kebab-case -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<pascal-cased-component></pascal-cased-component>

这个问题已经在前面认真探讨过了,这里不再详细阐述


4. 组件使用问题

通过上面上的例子我们已经了解了组件的使用,就是把组件名当做自定义标签使用,但是这种使用方法有的时候也会出现问题,


4.1. 组件标签解析错误

通过下面的实例了解组件标签解析时发生的问题.

例如:实例代码如下

<div id="app">
    <!-- 3. 使用组件 -->
    <table>
        <tbody>
            <row></row>
            <row></row>
            <row></row>
        </tbody>
    </table>
</div>


<!-- 组件模板 -->
<template id="myComponent">
    <tr>
        <td>内容</td>
        <td>123</td>
    </tr>
</template>


<script>


    // 1. 组件选项对象
    let MyComponent = {
        template: "#myComponent",
    }

	 // 2. 注册组件
    const vm = new Vue({
        el:"#app",
        components: {
            "row": MyComponent
        }

    })

</script>

显示结果:

template模板编译问题.png

实例中的写法,在查看代码结构时,发现子组件的tr标签并不在tbody里,

原因在与浏览器规范中tbody标签里面必须放tr标签,但是我们放的是row自定义标签,所以在解析的时候就会出问题


诸如此类的还有ul,ol标签里只能放li标签, select标签中只能放option,这些都是需要注意的事项

那么我们怎么解决这类问题呢?


4.2 通过is属性使用组件

vue允许我们使用is属性来使用组件, is属性的值是组件名

所以可以采用is属性来制定组件

示例代码如下:

<div id="app">
     <!-- 3. 使用组件 -->
    <table>
        <tbody>
            <tr is="row"></tr>
            <tr is="row"/>
            <tr is="row"/>
        </tbody>
    </table>
</div>

显示结果:

通过is属性使用组件.png

此时我们就会发现不仅结果没问题, 编译后标签的嵌套也没有什么问题,

因为我们是按照标准在tbody标签中使用的是tr标签,只不过通过is属性将tr标签替换为了组件row的模板标签.

此时tr标签中没有嵌套内容,所有使用单标签,双标签都可以

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1707194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA云HIS医院系统源码 云HIS运维平台源码 融合B/S版电子病历系统,支持电子病历四级,saas模式

JAVA云HIS医院系统源码 云HIS运维平台源码 融合B/S版电子病历系统&#xff0c;支持电子病历四级&#xff0c;saas模式 HIS系统就是医院信息管理系统&#xff0c;HIS系统是整个医院信息化的核心&#xff0c;门诊、住院、药房、药库等都是由HIS系统来承载起来的&#xff0c;所以…

MATLAB | 儿童节一起来玩转MATLAB叭

hey, 儿童节要到啦&#xff0c;提前祝各位大朋友&#xff0c;小朋友儿童节快乐&#xff0c;本篇将会在前半部分给出一些有趣且简短的代码&#xff0c;在后半部分展示一下我准备的游戏大礼包里面的游戏效果&#xff0c;完整代码获取方式请见文末&#xff0c;让我们一起玩转MATLA…

【SpringBoot】单元测试实战演示及心得分享

目录 1.指定测试标准 2.设计测试用例 3.测试集示例 4.跑测试集 1.指定测试标准 单元测试会用到mock和junit的内容&#xff0c;作者前文有详解&#xff0c;可移步&#xff1a; Spring Boot单元测试-CSDN博客 mockito的详细使用-CSDN博客 1.1.测哪一层&#xff1f; 以当…

conda 环境找不到 libnsl.so.1

安装prokka后运行报错 perl: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory 通过conda list 可以看到 有libsnl 2.00版本&#xff0c;通过修改软链接方式进行欺骗

K8s集群中的Pod调度约束亲和性与反亲和性

前言 在 K8s 集群管理中&#xff0c;Pod 的调度约束——亲和性&#xff08;Affinity&#xff09;与反亲和性&#xff08;Anti-Affinity&#xff09;这两种机制允许管理员精细控制 Pod 在集群内的分布方式&#xff0c;以适应多样化的业务需求和运维策略。本篇将介绍 K8s 集群中…

【软考】设计模式之外观模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.为子系统中的一组接口提供一个一致的界面&#xff0c;Facade模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。2.Facade Pattern。3.是一种结构型设计模式&…

OM电商系统asp.net

OM电商系统&#xff0c;可以让顾客全面了解商品的详细信息&#xff0c;消除网上购物的信息不对称问题。通过商品分类来组织众多的商品&#xff0c;方便顾客找到所需要的商品。提供客服顾客互动机制&#xff0c;提高顾客的参与度。通过设计合理的订单处理流程&#xff0c;提高顾…

JavaSE:String类常用方法(巨详细)

1、引言 在学习C语言时&#xff0c;我们就已经了解了字符串&#xff0c;但是在C语言中字符串只能用字符数组或者指针来表示&#xff0c;没有特定的字符串类型&#xff0c;而在Java中&#xff0c;我们有了字符串这一特定的类型---String类。 2、String类的常用方法 2.1 字符串…

第15章-超声波避障功能 HC-SR04超声波测距模块详解STM32超声波测距

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 15.1-超声波测距 完成超声波测距功能、测量数据显示在OLED屏幕上 硬件介绍 使用&#…

OpenHarmony实战开发——宿舍全屋智能开发指南

项目说明 基于OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;、数字管家开发宿舍全屋智能&#xff0c;实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似&#xff0c;本文主要以碰一碰开门为例介绍如何在现有OpenHar…

野外作战武器操作3D模拟实操仿真训练以便老兵能适应不同的训练需求

强国必须强军&#xff0c;我国在军事方面的投入持续加大&#xff0c;自然在军事武器培训方面不容忽视&#xff0c;在军事领域&#xff0c;3D模拟展示不仅提升了军事训练的效率&#xff0c;还为我们提供了更加直观、真实的武器体验。 首先&#xff0c;3D军事武器模拟展示能够提供…

Django革新者:突破传统,构建下一代Web应用

书接上文 —— 家园建筑师&#xff1a;用Django打造你的Web帝国&#xff0c;从前面的学习中&#xff0c;咱们我们经历了一个完整的Django Web开发之旅&#xff0c;涵盖了从基础概念到高级特性的各个方面&#xff1a; 引言&#xff1a;介绍了企业级Web框架的需求&#xff0c;并概…

分享个自用的 Nginx 加强 WordPress 防护的规则

Nginx WordPress 的组合是目前非常普及的组合了&#xff0c;我们完全可以借助 Nginx 规则来加强 WordPress 的防护&#xff0c;提高 WordPress 的安全性&#xff0c;今天明月就给大家分享个自用的 Nginx 针对 WordPress 的防护规则&#xff0c;部分规则大家只需要根据自己的需要…

ABB焊接功能介绍

1.基本配置 1.2配置Robot Ware Arc 2.焊接语句 2.1直线焊接语句 过渡点指令必须位于起弧指令与熄弧指令之间&#xff0c;不能单独使用。 2.2直线焊接示例 2.3圆弧焊接语句 2.4圆弧焊接示例 2.5摆动参数 关于ABB焊接机器人摆动参数设定 一般情况下&#xff0c;主要设置以…

[Linux]磁盘管理

一.Linux磁盘管理的原理 磁盘分区与Linux的目录是借助"挂载机制"链接的&#xff0c;将一个分区与一个目录连接起来。访问目录&#xff0c;相当于访问某块分区 lsblk命令: lsblk命令可以查看磁盘分区&#xff0c;以及每个分区所挂载的目录 lsblk -f 可以查看更细节的…

利用NewGIS平台将FME模板发布为接口

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 一、模板编写 二、发布模板 三、接口获取 四、移动端调用 ​​​​​ 前言 在实际的应用生产过程中&#xff0c;尤其是移动端GIS软件的开发&#xff0c;针对一些闭…

win11中文文件名称乱码解决方案

解压后出现以下的乱码 解决方案 步骤1.winR 输入intl.cpl 或 windows 自带的搜索搜“intl.cpl”&#xff0c;打开这个面板控制项 步骤2.在新打开的区域面板中&#xff0c;选择“管理”标签页&#xff0c;点击下方的“更改系统区域设置”按钮 步骤3.取消"Beta版…"选…

Nginx的配置与调试

目录 1、安装Nginx 2、Nginx的配置文件结构 2.1 Nginx的全局配置 2.2 HTTP服务器配置 2.3 HttpGzip模块配置 2.4 负载均衡配置 2.5 server虚拟主机配置 2.6 location URL匹配配置 2.7 StubStatus模块配置 1、安装Nginx 在安装Nginx之前&#xff0c;需确保系统已经安装…

Day38 代码随想录打卡|二叉树篇---二叉树的最大深度

题目&#xff08;leecode T104&#xff09;&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 递归法&#xff1a; 递归法首先将根节点作为参数传入&#xff0c;随后每一轮传入当前节点的…

【openlayers系统学习】3.3假彩色图像合成(三个波段合成假彩色图像)

三、假彩色图像合成 在上一步中&#xff0c;我们使用 ol/source/GeoTIFF​ 源从单个多波段源&#xff08;具有红色、绿色、蓝色和Alpha波段&#xff09;渲染真彩色图像。在下面这个例子中&#xff0c;我们将从可见光谱之外提取数据&#xff0c;并使用它来呈现假彩色合成。 我…