使用 kebab-case
Vue.component('my-component-name', { /* ... */ })
当使用 kebab-case (短横线分隔命名) 定义一个组件时,必须在引用这个自定义元素时使用 kebab-case,例如
。
使用 PascalCase
Vue.component('MyComponentName', { /* ... */ })
当使用 PascalCase (首字母大写命名)
定义一个组件时,在引用这个自定义元素时两种命名法都可以使用。
也就是说
和
都是合法的。
注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。
这意味着当使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '{{ postTitle }}
'
})
在HTML 中,需要将组件的属性 postTitle 改成 post-title。
重申一次,如果使用字符串模板,那么这个限制就不存在了。
即直接可以在 template 字符串中使用 postTitle
属性.
Vue.component('blog-post3', {
props: ['postTitle'],
template: `
{{ postTitle }}
`
})
// 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。请用字符串或数值类型的值。
// 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>
[Vue tip]: Prop "postdetail" is passed to component , 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>
<blog-post3
v-for="post3 in postList"
v-bind:key="'list3-' + post3.id"
v-bind:postDetail="post3"
>blog-post3>
完整的代码实例如下:
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,height=device-height">
<title>Vue组件title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js">script>
head>
<body>
<div id="app">
<hr/>
<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/>
<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/>
<strong>使用组件2: 绑定一个对象strong>
<blog-post2
v-for="post2 in postList"
v-bind:key="'list2-' + post2.id"
v-bind:post2="post2"
>blog-post2>
<hr/>
<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: ' {{ author }} : {{ title }}
'
})
// 组件2: 又一个组件
// 该组件不是传递一个字符串值,该传递一个对象。
// 这样可以直接在模板里使用对象,而不必一个一个属性的传入
Vue.component('blog-post2', {
props: ['post2'],
template: `
{{ post2.author}} : {{ post2.title }}
`
})
// 组件3: 再来一个组件
// 该组件定义一个 postDetail 属性,注意在DOM中绑定属性时要使用 "v-bind:post-detail"
Vue.component('blog-post3', {
props: ['postDetail'],
template: `
{{ postDetail.author }} : {{ postDetail.title }}
`
})
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]