在阅读vue官方文档中关于props的时候发现这么两段话:
HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
const app = Vue.createApp({})
app.component('blog-post', {
// 在 JavaScript 中使用 camelCase
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中使用 kebab-case -->
<blog-post post-title="hello!"></blog-post>
重申一次,如果你使用字符串模板,那么这个限制就不存在了。
结论在文档末尾,想看可以直接划过去
当时看这两句话一头雾水,想了好久,动手试过之后才发现这句话确实不难理解,只是官方文档比较绕,于是记录下来。
翻译一下第一段话:如果你直接在dom中使用的话,那么你必须使用短横线命名,而不管你的props中是驼峰式还是短横线式。
接下来我们实验一下:
首先我们定义一个组件,把它的props设置为驼峰式并使用:
const MyComponent = defineComponent({
props:['myName'],
template:`
<h1>1{{myName}}</h1>
`
});
然后创建一个vue 实例并注册使用这个组件,然后挂载到我们的dom上:
const app = {
}
const ap = createApp(app)
ap.component('my-component',MyComponent).mount('#main')
注意:这个时候我们并没有为这个实例定义template属性,所以它默认会将id='main'元素中的内容作为template,简而言之,此时我们的模板是直接定义在了dom中,在html中像是这样:
<body>
<div id="main">
<my-component my-name='sxk'/>
</div>
<script src="./script1.js"></script>
</body>
上面代码会正常显示:
而如果你把其中用来传参的 my-name 换成 myName ,虽然看起来一模一样,但无法传入:
我们也可以嚣张一些, 在dom中使用短横线时,甚至可以将组件props中接受时的参数名改为短横线:
const MyComponent = defineComponent({
props:['my-name'],
template:`
<h1>1{{myName}}</h1>
`
});
可以正常显示,没有任何问题
再回头看第一段话:
当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名
也就是说如果直接在dom中使用props传参,那么在传参时父组件必须要短横线式,至于子组件props用来接受的名字短横线或者驼峰都可以 ;
这句话应该很容易理解了,接下来我们看下一句:
重申一次,如果你使用字符串模板,那么这个限制就不存在了。
在我们使用字符串模板的时候不存在这个限制,首先我们要搞懂字符串模板是什么,字符串模板其实就是在创建组件中的定义的template元素
还记得初始定义的根组件吗,之前我们是将app直接挂载,使用挂载元素的内置内容,像是这样:
<body>
<div id="main">
<my-component my-name='sxk'/>
</div>
<script>
const app = {
}
const ap = createApp(app)
ap.component('my-component',MyComponent).mount('#main')
</script>
</body>
接下来我们使用字符串模板的写法:
const app = {
template:`
<my-component myName='sxk'/>
`
}
然后同样挂载到 main块上,这次因为定义了template元素,所以vue会直接忽略掉main块中原本的涅内容,使用template中的元素渲染
你会发现按照上面这种驼峰写法来写html竟然可以成功将值传给子组件显示:
而短横线也可以:
到这里就结果就显而易见了:
在使用template定义html时,传参两种方式都可以,但在dom中直接定义html时,传参只能用短横线
而原因也很好猜,既然dom无法处理驼峰,而我们又可以正常使用,那么必然是万能的vue帮我们对template做了处理,而当我们直接定义dom时,vue不敢贸然更改我们设置的变量(因为myName 和 my-name对于html来说是myname和my-name,即两个不同的变量),所以没有做处理。
(注册组件名驼峰/短横线也是这个道理)
稍微总结一下用法:
props: ['my-name'] 或者 ['myName'] (建议使用这样,js中都会使用这样的命名方式)
dom: my-name='sxk'(直接在dom中写死的很少了,vue项目都是使用template定义单文件组件)
template: my-name='sxk' 或者 myName='sxk' (建议使用这样,js中都会使用这样的命名方式)
子组件中使用这个值:myName