博客列表 >PHP大牛成长之路:Vue组件注册与参数传递

PHP大牛成长之路:Vue组件注册与参数传递

周Sir-BLOG
周Sir-BLOG原创
2020年09月12日 10:21:40717浏览

1、Vue组件注册

1.1、全局组件注册

  1. <script src="../vue.js"></script>
  2. <div class="app1">
  3. <component-a></component-a>
  4. </div>
  5. <hr />
  6. <div class="app2">
  7. <component-a></component-a>
  8. </div>
  9. <script>
  10. // 自定义组件:可以理解为自定义DOM结构
  11. // 1、定义模板内容
  12. const htmlcontent ={
  13. // 注意:template中组件模板应该只包含一个根元素,可以使用一对<div></div>进行包裹
  14. template: `
  15. <div>
  16. <p>我是一个全局组件</p>
  17. <p>在任何Vue实例中我都可以使用</p>
  18. </div>
  19. `,
  20. };
  21. // 2、注册组件:Vue.component(组件标签名称, 对象/数据/模板)
  22. Vue.component("component-a",htmlcontent);
  23. // 创建一个 Vue 实例:app1
  24. const app1 = new Vue({
  25. el: ".app1", //挂载点
  26. });
  27. // 创建一个 Vue 实例:app2
  28. const app2 = new Vue({
  29. el: ".app2",
  30. });
  31. </script>

全局组件注册可在任意Vue实例挂载点渲染

1.2、局部组件注册

  1. <script src="../vue.js"></script>
  2. <div class="app1">
  3. <component-a></component-a>
  4. </div>
  5. <hr />
  6. <div class="app2">
  7. <component-a></component-a>
  8. </div>
  9. <script>
  10. // 定义组件
  11. const ComponentA = {
  12. template: `
  13. <div>
  14. <p>我是一个局部组件</p>
  15. <p>我只能在app1实例中使用</p>
  16. </div>
  17. `,
  18. };
  19. // 自定义组件:可以理解为自定义DOM结构
  20. // 创建一个 Vue 实例:app1
  21. const app1 = new Vue({
  22. el: ".app1", //挂载点
  23. // 注册组件:
  24. components: {
  25. "component-a": ComponentA,
  26. },
  27. });
  28. // 创建一个 Vue 实例:app2
  29. const app2 = new Vue({
  30. el: ".app2",
  31. });
  32. </script>

局部组件, 则无法在其它挂载的区域内渲染;

1.3、组件模板写法优化

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a></component-a>
  4. </div>
  5. <!-- 定义组件(html不会渲染template标签:源码可以看到) -->
  6. <template id="ComponentA">
  7. <div>
  8. <p>我是一个局部组件</p>
  9. <p>我只能在app实例中使用</p>
  10. </div>
  11. </template>
  12. <script>
  13. // 创建一个 Vue 实例:app
  14. const app = new Vue({
  15. el: ".app", //挂载点
  16. components: {
  17. "component-a": {
  18. template: "#ComponentA",
  19. },
  20. },
  21. });
  22. </script>

使用<template>标签方向定义模板,html不会渲染,相当于不显示;

2、Vue组件参数传递(props 通信)

props 可以是数组对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

2.1、使用自定义属性向组件传参【数组】

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a name="aRwanG" age="三十岁"></component-a>
  4. </div>
  5. <template id="ComponentA">
  6. <div>
  7. <span>{{ name }}</span>
  8. <span>{{ age }}</span>
  9. </div>
  10. </template>
  11. <script>
  12. // 创建一个 Vue 实例:app
  13. const app = new Vue({
  14. el: ".app", //挂载点
  15. components: {
  16. "component-a": {
  17. template: "#ComponentA",
  18. //props组件通信
  19. props: ["name", "age"],
  20. },
  21. },
  22. });
  23. </script>

2.2、使用自定义属性向组件传参【对象】(验证类型)

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a name="aRwanG" v-bind:age="age"></component-a>
  4. </div>
  5. <template id="ComponentA">
  6. <div>
  7. <span>{{ name }}</span>
  8. <span>{{ age }}</span>
  9. </div>
  10. </template>
  11. <script>
  12. // 创建一个 Vue 实例:app
  13. const app = new Vue({
  14. el: ".app",
  15. // 注册子组件
  16. components: {
  17. "component-a": {
  18. template: "#ComponentA",
  19. //props组件通信(使用对象)
  20. props: {
  21. name: String, //声明字符类型
  22. age: Number, //声明数字类型
  23. },
  24. },
  25. },
  26. // 父组件数据
  27. data: {
  28. age: 18,
  29. },
  30. });
  31. </script>
  32. // 输出:aRwanG 18

name为属性直接赋值,age为绑定父组件数据,并分别为name和age声明类型,当类型错误时会报错(还是会渲染结果)

2.3、使用 data() 向组件传参【对象】

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a></component-a>
  4. </div>
  5. <template id="ComponentA">
  6. <div>
  7. <span>{{ name }}</span>
  8. <span>{{ age }}</span>
  9. </div>
  10. </template>
  11. <script>
  12. //子组件
  13. const son = {
  14. "component-a": {
  15. template: "#ComponentA",
  16. //data()对象可以直接在组件使用
  17. data() {
  18. return {
  19. name:"peter-zhu",
  20. age:18
  21. }
  22. },
  23. }
  24. };
  25. // 创建一个 Vue 实例:app
  26. const app = new Vue({
  27. el: ".app", //挂载点
  28. components: son
  29. });
  30. </script>
  31. <!-- 输出:peter-zhu 18 -->

2.4、使用 data() + 属性 向组件传参

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a v-bind:email="email"></component-a>
  4. </div>
  5. <template id="ComponentA">
  6. <div>
  7. <span>{{ name }}</span>
  8. <span>{{ age }}</span>
  9. <span>{{ email }}</span>
  10. </div>
  11. </template>
  12. <script>
  13. //子组件
  14. const son = {
  15. "component-a": {
  16. template: "#ComponentA",
  17. //props组件通信(获取父组件data的Email)
  18. props:["email"],
  19. //data()对象可以直接在组件使用
  20. data() {
  21. return {
  22. name:"peter-zhu",
  23. age:18
  24. }
  25. },
  26. }
  27. };
  28. // 创建一个 Vue 实例:app
  29. const app = new Vue({
  30. el: ".app", //挂载点
  31. components: son,
  32. data:{
  33. email:"peter@php.cn"
  34. }
  35. });
  36. </script>
  37. <!-- 输出:peter-zhu 18 peter@php.cn -->

2.5、父组件向子组件传参(2.4已经举例说明)

  1. <script src="../vue.js"></script>
  2. <div class="app">
  3. <component-a :user="user"></component-a>
  4. </div>
  5. <template id="ComponentA">
  6. <div>
  7. <span>{{ user.name }}</span>
  8. <span>{{ user.age }}</span>
  9. <span>{{ user.email }}</span>
  10. </div>
  11. </template>
  12. <script>
  13. // 注册: 全局组件
  14. Vue.component("component-a", {
  15. template: "#ComponentA",
  16. // props组件通信
  17. // 子组件中接收一个父组件传递过来的user对象
  18. props: ["user"],
  19. });
  20. // 创建一个 Vue 实例:app
  21. const app = new Vue({
  22. el: ".app", //挂载点
  23. data: {
  24. user: {
  25. name: "peter-zhu",
  26. age: 18,
  27. email: "peter@php.cn",
  28. },
  29. },
  30. });
  31. </script>
  32. <!-- 输出:peter-zhu 18 peter@php.cn -->

3、父子组件通讯例子-购物车

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <script src="../vue.js"></script>
  7. <style>
  8. table {
  9. border-collapse: collapse;
  10. width: 90%;
  11. text-align: center;
  12. margin: auto;
  13. }
  14. table caption {
  15. margin-bottom: 15px;
  16. font-size: 1.5rem;
  17. }
  18. table th,
  19. table td {
  20. /* border: 1px solid #888; */
  21. border-bottom: 1px solid #888;
  22. padding: 5px;
  23. }
  24. table thead tr:first-of-type {
  25. background-color: rgb(222, 222, 222);
  26. }
  27. button {
  28. width: 150px;
  29. height: 30px;
  30. outline: none;
  31. border: none;
  32. background-color: #f40;
  33. color: white;
  34. letter-spacing: 5px;
  35. }
  36. button:hover {
  37. background: #999;
  38. background-color: coral;
  39. cursor: pointer;
  40. }
  41. .my {
  42. color: #f40;
  43. font-weight: 700;
  44. }
  45. </style>
  46. <title>父子组件通讯例子-购物车</title>
  47. </head>
  48. <body>
  49. <div id="app">
  50. <v-table :goods="goods" :tn="tNum" :tp="tPrice" @tp-count="totalPrice" @tn-count="totalNum"></v-table>
  51. </div>
  52. <template id="goods">
  53. <div>
  54. <table>
  55. <caption class="my">
  56. 购物车
  57. </caption>
  58. <thead>
  59. <tr>
  60. <th>ID</th>
  61. <th>品名</th>
  62. <th>单位</th>
  63. <th>单价/元</th>
  64. <th>数量</th>
  65. <th>金额/元</th>
  66. </tr>
  67. </thead>
  68. <tbody>
  69. <tr v-for="item of goods">
  70. <td>{{item.id}}</td>
  71. <td>{{item.name}}</td>
  72. <td>{{item.unit}}</td>
  73. <td>{{item.price}}</td>
  74. <td>
  75. <input type="number" v-model="item.num" @change="Count" />
  76. </td>
  77. <td>{{item.num * item.price}}</td>
  78. </tr>
  79. </tbody>
  80. <tfoot>
  81. <tr>
  82. <td colspan="4" style="font-weight: 700">总计:</td>
  83. <td class="my">{{ tn }}</td>
  84. <td class="my">{{ tp }}</td>
  85. </tr>
  86. </tfoot>
  87. </table>
  88. <div style="width: 90%; margin: 10px auto">
  89. <button style="float: right; width: 100px">结算</button>
  90. </div>
  91. </div>
  92. </template>
  93. <script>
  94. Vue.component("v-table", {
  95. template: "#goods",
  96. props: ["goods", "tn","tp"],
  97. methods: {
  98. Count() {
  99. // 向父组件发送消息,调用父组件的方法
  100. this.$emit("tp-count");
  101. this.$emit("tn-count");
  102. },
  103. },
  104. });
  105. const app = new Vue({
  106. el: "#app",
  107. data: {
  108. goods: [
  109. { id: 1, name: "iPhone12 pro", unit: "台", price: 8999, num: 1 },
  110. { id: 2, name: "Huawei p40 pro", unit: "台", price: 4999, num: 1 },
  111. { id: 3, name: "ipad2020", unit: "台", price: 5000, num: 1 },
  112. { id: 4, name: "Apple TV 65寸", unit: "台", price: 18999, num: 1 },
  113. ],
  114. tPrice: 0,
  115. tNum: 0,
  116. },
  117. mounted() {
  118. this.totalNum();
  119. this.totalPrice();
  120. },
  121. methods: {
  122. //计算总价格
  123. totalPrice() {
  124. this.tPrice = 0;
  125. this.goods.forEach((item) => {
  126. this.tPrice += item.num * item.price;
  127. });
  128. return this.tPrice;
  129. },
  130. //计算总商品数
  131. totalNum() {
  132. this.tNum = 0;
  133. this.goods.forEach((item) => {
  134. this.tNum += parseFloat(item.num) ;
  135. });
  136. return this.tNum;
  137. },
  138. },
  139. });
  140. </script>
  141. </body>
  142. </html>

总结:

1、组件间的通讯总算有了一定了解
2、this.$emit()方法有个大坑,就是不支持驼峰命名法,折腾了几个小时—
3、本来想加上复选框的,结果又折腾了几个小时,没弄成功—哭哭
4、这个作业想着简单,做起来太难了~~~~

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议