注册自定义特性(特性即是指元素上的属性)
组件默认只是写好结构、样式和行为,使用的数据应由外界传递给组件。
如何传递?注册需要接收的prop,将数据作为一个自定义特性传递给组件。
如:
<div id="app">
<video-item
title="羊村摇"
poster="https://developer.duyiedu.com/bz/video/955bac93ccb7f240d25a79b2ff6a9fdbda9537bc.jpg@320w_200h.webp"
play="638000"
rank="1207"
></video-item>
</div>
Vue.component('video-item', {
props: ['title', 'poster', 'play', 'rank'],
})
在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样:
Vue.component('video-item', {
props: ['title', 'poster', 'play', 'rank'],
template: `<div>{{ title }}</div>`
})
Prop的大小写
HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。故:当 传递的prop为 短横线分隔命名时,组件内 的props 应为 驼峰命名 。
如:
<div id="app">
<!-- 在 HTML 中是 kebab-case 的 -->
<video-item sub-title="hello!"></video-item>
</div>
Vue.component('video-item', {
// 在 JavaScript 中是 camelCase 的
props: ['subTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
要注意的是:如果使用的是字符串模板,那么这个限制就不存在了。
传递一个对象的所有属性
如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind 。例如,对于一个给定的对象 person:
person: {
name: 'shanshan',
age: 18
}
传递全部属性:
<my-component v-bind="person"></my-component>
上述代码等价于:
<my-component
:name="person.name"
:age="person.age"
></my-component>
通过prop向子组件传递静态数据
效果图
代码
<section id="app">
<!-- 视频列表 -->
<video-list>
</video-list>
</section>
<script>
// 传递数据 生成大致机构
Vue.component('video-list',{
template:`
<div class="video-list">
<video-item v-for='video in 12' :key='video'
title="羊村摇"
poster="https://developer.duyiedu.com/bz/video/955bac93ccb7f240d25a79b2ff6a9fdbda9537bc.jpg@320w_200h.webp"
play="638000"
rank="1207">
</video-item>
</div>
`
})
// 渲染每个视频的信息
Vue.component('video-item',{
props:['title','poster','play','rank'],
template:`
<div class="video-item" >
<div class="poster">
<img :src="poster"
:alt="title">
<div class="info">
<div class="play">{{ play }}</div>
<div class="rank">{{ rank }}</div>
</div>
</div>
<div class="title">{{ title }}</div>
</div>
`
})
const vm = new Vue({
el:'#app',
})
</script>
通过prop向子组件传递动态数据
效果图
代码如下
<section id="app">
<!-- 组件,并且将数据传递过去 -->
<!-- 注意此时是在Vue的实例对象vm中的使用的,故可以访问到vm中的属性 ,所以才能将获取到的数据传递过去-->
<video-list :video-list='videoList'>
</video-list>
</section>
<script>
Vue.component('video-list', {
props: ['videoList'],
template: `
<div class="video-list" >
<video-item v-for='video in videoList' v-bind='video' :key='video.id'></video-item>
</div>
`,
// 模板下只能有一个根元素,故在此处循环,如果多个元素需要使用一个父级元素包裹
// 当需要使用对象中的所有属性时可以使用v-bind='对象名' 将对象中的每一个属性只作为数据传递给子组件
})
Vue.component('video-item',{
// 接受数据
props:['poster','title','play','rank'],
// 模板
template:`
<div class="video-item">
<div class="poster">
<img :src="poster"
:alt="title">
<div class="info">
<div class="play">{{ play }}</div>
<div class="rank">{{ rank }}</div>
</div>
</div>
<div class="title">{{ title }}</div>
</div>
`,
})
const vm = new Vue({
el: '#app',
data: {
videoList: [],
},
created() {
// 获取数据
axios.get('https://developer.duyiedu.com/vue/bz/video', {
params: {
start: 0,
offset: 12,
}
}).then(res => {
if (res.status === 200) {
this.videoList = res.data.data
this.videoList.map(ele => {
ele.play = ele.play > 10000 ? (ele.play / 10000).toFixed(1) + '万' :
ele.play;
ele.rank = ele.rank > 10000 ? (ele.rank / 10000).toFixed(1) + '万' :
ele.rank;
})
}
})
}
})
</script>