注册自定义特性(特性即是指元素上的属性)

组件默认只是写好结构、样式和行为,使用的数据应由外界传递给组件。
如何传递?注册需要接收的prop,将数据作为一个自定义特性传递给组件。
如:

  1. <div id="app">
  2. <video-item
  3. title="羊村摇"
  4. poster="https://developer.duyiedu.com/bz/video/955bac93ccb7f240d25a79b2ff6a9fdbda9537bc.jpg@320w_200h.webp"
  5. play="638000"
  6. rank="1207"
  7. ></video-item>
  8. </div>
  1. Vue.component('video-item', {
  2. props: ['title', 'poster', 'play', 'rank'],
  3. })

在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样:

  1. Vue.component('video-item', {
  2. props: ['title', 'poster', 'play', 'rank'],
  3. template: `<div>{{ title }}</div>`
  4. })

Prop的大小写

HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。故:当 传递的prop为 短横线分隔命名时,组件内 的props 应为 驼峰命名 。
如:

  1. <div id="app">
  2. <!-- 在 HTML 中是 kebab-case 的 -->
  3. <video-item sub-title="hello!"></video-item>
  4. </div>
  1. Vue.component('video-item', {
  2. // 在 JavaScript 中是 camelCase 的
  3. props: ['subTitle'],
  4. template: '<h3>{{ postTitle }}</h3>'
  5. })

要注意的是:如果使用的是字符串模板,那么这个限制就不存在了。

传递一个对象的所有属性

如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind 。例如,对于一个给定的对象 person:

  1. person: {
  2. name: 'shanshan',
  3. age: 18
  4. }

传递全部属性:

  1. <my-component v-bind="person"></my-component>

上述代码等价于:

  1. <my-component
  2. :name="person.name"
  3. :age="person.age"
  4. ></my-component>

通过prop向子组件传递静态数据

效果图
image.png
代码

  1. <section id="app">
  2. <!-- 视频列表 -->
  3. <video-list>
  4. </video-list>
  5. </section>
  6. <script>
  7. // 传递数据 生成大致机构
  8. Vue.component('video-list',{
  9. template:`
  10. <div class="video-list">
  11. <video-item v-for='video in 12' :key='video'
  12. title="羊村摇"
  13. poster="https://developer.duyiedu.com/bz/video/955bac93ccb7f240d25a79b2ff6a9fdbda9537bc.jpg@320w_200h.webp"
  14. play="638000"
  15. rank="1207">
  16. </video-item>
  17. </div>
  18. `
  19. })
  20. // 渲染每个视频的信息
  21. Vue.component('video-item',{
  22. props:['title','poster','play','rank'],
  23. template:`
  24. <div class="video-item" >
  25. <div class="poster">
  26. <img :src="poster"
  27. :alt="title">
  28. <div class="info">
  29. <div class="play">{{ play }}</div>
  30. <div class="rank">{{ rank }}</div>
  31. </div>
  32. </div>
  33. <div class="title">{{ title }}</div>
  34. </div>
  35. `
  36. })
  37. const vm = new Vue({
  38. el:'#app',
  39. })
  40. </script>

通过prop向子组件传递动态数据

效果图
image.png
代码如下

  1. <section id="app">
  2. <!-- 组件,并且将数据传递过去 -->
  3. <!-- 注意此时是在Vue的实例对象vm中的使用的,故可以访问到vm中的属性 ,所以才能将获取到的数据传递过去-->
  4. <video-list :video-list='videoList'>
  5. </video-list>
  6. </section>
  7. <script>
  8. Vue.component('video-list', {
  9. props: ['videoList'],
  10. template: `
  11. <div class="video-list" >
  12. <video-item v-for='video in videoList' v-bind='video' :key='video.id'></video-item>
  13. </div>
  14. `,
  15. // 模板下只能有一个根元素,故在此处循环,如果多个元素需要使用一个父级元素包裹
  16. // 当需要使用对象中的所有属性时可以使用v-bind='对象名' 将对象中的每一个属性只作为数据传递给子组件
  17. })
  18. Vue.component('video-item',{
  19. // 接受数据
  20. props:['poster','title','play','rank'],
  21. // 模板
  22. template:`
  23. <div class="video-item">
  24. <div class="poster">
  25. <img :src="poster"
  26. :alt="title">
  27. <div class="info">
  28. <div class="play">{{ play }}</div>
  29. <div class="rank">{{ rank }}</div>
  30. </div>
  31. </div>
  32. <div class="title">{{ title }}</div>
  33. </div>
  34. `,
  35. })
  36. const vm = new Vue({
  37. el: '#app',
  38. data: {
  39. videoList: [],
  40. },
  41. created() {
  42. // 获取数据
  43. axios.get('https://developer.duyiedu.com/vue/bz/video', {
  44. params: {
  45. start: 0,
  46. offset: 12,
  47. }
  48. }).then(res => {
  49. if (res.status === 200) {
  50. this.videoList = res.data.data
  51. this.videoList.map(ele => {
  52. ele.play = ele.play > 10000 ? (ele.play / 10000).toFixed(1) + '万' :
  53. ele.play;
  54. ele.rank = ele.rank > 10000 ? (ele.rank / 10000).toFixed(1) + '万' :
  55. ele.rank;
  56. })
  57. }
  58. })
  59. }
  60. })
  61. </script>