@作者 陶务华

一、组件作用

  1. 组件(Component)是 Vue.js 最强大的功能之一。<br /> 组件可以扩展 HTML 元素,封装可重用的代码。<br /> 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个 组件树:<br />![](https://cdn.nlark.com/yuque/0/2020/png/1196645/1585550121904-30b8c97b-8af8-4ced-9a72-2936e7767c33.png#align=left&display=inline&height=544&originHeight=544&originWidth=1406&size=0&status=done&style=none&width=1406)<br /> 上图由页头、侧边栏组成,我们可以把他们理解为组件,每个组件又包含了其它的像导航链接、博文之类的 组件,这样做的好处是灵活方面,真正做到了面向对象的闭合原则

二、注册组件

2.1 全局注册(所有示例都能使用全局组件)

2.1.1 语法格式

全局注册这种方式通过Vue.commponent(tagName, options)创建了一个名为tagName的Vue组件,options 是一个对象,表明组件里面的数据、方法、html结构(注意:一个组件的 data 选项必须是函数,通过闭包的方式防止数据污染)。

2.1.2 调用组件:

<tagName></tagName> (注组件名尽量用小写)

2.1.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. <title>Document</title>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <!-- 调用 -->
  12. <button-counter></button-counter>
  13. </div>
  14. <script>
  15. //全局注册组件(注意先全局注册组件然后再挂载到vue实例上面)
  16. Vue.component("button-counter", {
  17. data: function() {
  18. return {
  19. name: "陶务华"
  20. };
  21. },
  22. template: "<p> {{name}}在前端小课体验局部注册组件</p>"
  23. });
  24. var obj = {
  25. el: "#app"
  26. };
  27. new Vue(obj);
  28. </script>
  29. </body>
  30. </html>

2.2 局部注册(实例选项中注册局部组件,这样组件只能在这个实例中使用)

2.2.1调用组件:

<templateName></templateName>

2.2.2 实例代码:

  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. <title>Document</title>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <register ></register>
  12. </div>
  13. <script>
  14. const vm = new Vue({
  15. el:'#app',
  16. data:function(){
  17. return{
  18. }
  19. },
  20. components:{
  21. register:{
  22. template:'<h1> 我在前端小课学习局部注册组件</h1>'
  23. }
  24. },
  25. methods: {
  26. },
  27. });
  28. </script>
  29. </body>
  30. </html>

三、通过 Prop 向子组件传递数据

3.1 为什么使用props 传值

  1. 子组件无法访问父组件的数据和方法,所以延伸出props

3.2 如何使用

3.2.1 父组件引用子组件并通过自定义属性的方式传递数据(注意:自定义属性的命名需要分割式,不建议 驼峰式。详情查看vue官方 https://cn.vuejs.org/v2/guide/components-props.html)
3.2.2 注册父组件传递子组件的自定义属性
3.2.3 子组件就可以调用了

3.3 代码示例

3.3.1 局部组件的传值

  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. <title>Document</title>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <!-- 第一步、父组件可以在引用子组件的时候通过属性绑定的形式(v-bind:自定义属性)
  12. 把需要传递给子组件的数据传过去 -->
  13. <con1 v-bind:parentmsg="msg"></con1>
  14. </div>
  15. <script>
  16. const obj = {
  17. el: '#app',
  18. data: function () {
  19. return {
  20. msg: 'taowuhua'
  21. }
  22. },
  23. components: {
  24. con1: {
  25. // 第二步、 把父组件传递的自定义属性定义下,然后子组件就可以用了
  26. props: ['parentmsg'],
  27. // 第三步、 子组件无法访问父组件间的数据和methods中的方法
  28. // 组件挂载在vm上,和子组件相关
  29. template: '<p> {{parentmsg}}正在前端小课学习vue </p>'
  30. }
  31. }
  32. }
  33. // 创建vue实例
  34. const vm = new Vue(obj)
  35. </script>
  36. </body>
  37. </html>

3.3.2 全局组件的传值

  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. <title>Document</title>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <register v-bind:name ='msg'></register>
  12. </div>
  13. <script>
  14. Vue.component("register", {
  15. data: function() {
  16. return {
  17. };
  18. },
  19. props:['name'],
  20. template: '<p >{{name}}正在前端小课学习全局注册组件</p>'
  21. });
  22. new Vue({
  23. el: "#app",
  24. data:function(){
  25. return{
  26. msg:'陶务华'
  27. }
  28. }
  29. });
  30. </script>
  31. </body>
  32. </html>

四、通过 $emit 向子组件传递数据

4.1 如何使用

4.1.1 父类中注册自定义click事件
image.png
4.1.2 子类模板触发的事件就是父类自定义click事件的表达式
image.png
4.1.3 在子类事件通过this.$emit(‘自定义click事件名’,数据)将数据回调给父类
image.png
4.1.4 父类通过回调方法收到需要的数据
image.png

4.2 代码示例

  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. <title>Document</title>
  7. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <register @sendparentdata='getChildData'></register>
  12. </div>
  13. <script>
  14. new Vue({
  15. el:'#app',
  16. data:function(){
  17. return{
  18. }
  19. },
  20. methods:{
  21. getChildData:function(e){
  22. console.log("getChildData===="+e)
  23. }
  24. },
  25. components:{
  26. register:{
  27. data:function(){
  28. return{
  29. msg:'taowuhua'
  30. }
  31. },
  32. methods: {
  33. getChildData:function(){
  34. console.log(this.msg)
  35. this.$emit('sendparentdata',this.msg)
  36. }
  37. },
  38. props:[],
  39. template:'<h1 @click="getChildData">这个方式不友好</h1>'
  40. }
  41. }
  42. })
  43. </script>
  44. </body>
  45. </html>

五、单文件组件