• 【vue-03】组件化开发 component


    vue组件化思想

    组件化是vue的一个重要思想

    它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构建我们的应用。

    任何的应用都会被抽象成一颗组件树。

    IMG_256

    注册组件

    组件的使用分成三个步骤:创建组件构造器、注册组件、使用组件。

    注意:不论使用哪一种注册方式,template属性只能有一个,并且有且仅有一个根节点。

    <body>
      <div id="app">
        <my-component></my-component>
        <my-component2></my-component2>
        <my-component3></my-component3>
        <my-component4></my-component4>
      </div>
    </body>
    
    <template id="temp">
      <div>
        <p>我是p标签</p>
        <h1>我是h1标签</h1>
        <div style="color: red;">哈哈哈</div>
      </div>
    </template>
    <script>
      var num = 10
      /**
       * 1 使用Vue.extend来注册 组件
       * 按照了Java的开发思想,变量名往往是驼峰规则。
       * 但是使用组件的时候一般不使用驼峰规则
       * 而是将驼峰规则全部改成小写,然后中间用-连接
       */
      Vue.component('myComponent', Vue.extend({
        // template就是组件要展示的内容,可以是html标签
        template: '<h3>这是用extend注册的组件</h3>'
      }))
      /**
       * 2.不使用extend去注册组件
       */
      Vue.component('myComponent2', {
        // template就是组件要展示的内容,可以是html标签
        template: '<div><h3>这是不用extend注册的组件</h3><h3>我是第二个h3</h3></div>'
      })
      // 不论使用哪一种注册方式,template属性只能有一个,并且有且仅有一个根节点。
      
      Vue.component('myComponent3', {
        // template就是组件要展示的内容,可以是html标签
        template: `<div><h3>组件中使用外部变量num:${num}</h3></div>`
      })
      // 3.使用template
      Vue.component('myComponent4', {
        template: '#temp'
      })
      let app = new Vue({
        el: '#app'
      })
    </script>
    

    私有组件

    我们上面使用Vue.component注册组件时,注册的是全局的组件。这意味着我们可以再任意的Vue实例中,使用该组件

    如果我们想要注册一个局部的私有组件,可以将组件挂载到某个实例上。

    <body>
      <div id="app">
        <my-component></my-component>
        <my-comp></my-comp>
      </div>
      <div id="app2">
        <my-component></my-component>
      </div>
    </body>
    
    <script>
      /**
       * 注册的是全局组件
       */
      Vue.component('myComponent', Vue.extend({
        // template就是组件要展示的内容,可以是html标签
        template: '<h3>这是用extend注册的组件</h3>'
      }))
      let myComp = Vue.extend({
        // template就是组件要展示的内容,可以是html标签
        template: '<h3>我是私有组件</h3>'
      })
      let app = new Vue({
        el: '#app',
        components: {
          myComp 
          //'myComp':myComp 当名字和变量名相同的时候,名字可以省略
        }
      })
      let app2 = new Vue({
        el: '#app2'
      })
    </script>
    

    父子组件

    ​ 前面我们看到了组件树,组件和组件之间存在层级关系。这就是父组件与子组件。组件中也有components关键字,同样是使用components将子组件注册到父组件。

    <body>
      <div id="app">
        <parent-com></parent-com>
      </div>
    </body>
    
    <script>
      // 1.创建一个子组件
      let childCom = Vue.extend({
        template: `
          <div>我是子组件内容。</div>
      })
      // 2.创建一个父组件
      let parentCom = Vue.extend({
        template: `
          <div>
            <h1>我是父组件内容</h1>
            <child-com></child-com>
          </div>
        `,
        components: {
          childCom
        }
      })
      let app = new Vue({
        el: '#app',
        components: {
          parentCom
        }
      })
    </script>
    

    组件的数据

    组件是一个单独的功能模块的封装,这个模块有属于自己的HTML模板,也应该有属于自己的data。

    我们先测试一下组件是否能使用Vue实例中的data。

    <body>
      <div id="app">
        <my-com></my-com>
      </div>
    </body>
    
    <script>
      let myCom = Vue.extend({
        template: `<div>我是组件{{msg}}</div>`
      })
      let app = new Vue({
    el: '#app',
        data: {
          msg: '哈哈哈'
        },
        components: {
          myCom
        }
      })
    </script>
    

    经过测试,我们发现不能使用。即使可以使用,如果将所有的数据都放到vue实例中,vue实例是不是会变得非常臃肿。

    那么 组件的数据存放到哪里?

    组件也有个data属性、methods、filters等等等等,使用方式与vue一致(data不一样。)

    Data必须是一个方法,返回一个对象。其他的与vue实例使用方式一样。

    <script>
      let myCom = Vue.extend({
        template: `<div>我是组件{{msg}}</div>`,
        data() {
          return {
            msg: '我是子组件的msg'
          }
        }
      })
      let app = new Vue({
        el: '#app',
        data: {
          msg: '哈哈哈'
        },
        components: {
          myCom
        }
      })
    </script>
    

    组件的通信

    在开发中,往往会存在这个场景,让子组件使用父组件的数据。

    比如我们从后台获取到一些数据后,这些数据需要传递到子组件去使用,或者我们获取到了很多的数据,这些数据分别需要分发到下面的各个子组件中使用。怎么操作?

    父组件向子组件传值 props

    组件中,可以使用props来声明需要从父级接受到的数据。

    使用:

    1. 首先在父组件中使用v-bind将数据绑定给子组件
    2. 再在子组件中,使用props接收。

    propsdatamethods平级,有两种使用方式。

    1. 字符串数组,数组中的字符串就是传递时的名称。
     props: [
          // 第二步,使用props接收.
          'msg'
        ]
    

    具体例子

    <body>
      <div id="app">
        <!-- 第一步,用绑定的方式,将父组件的数据绑定给子组件 -->
        <my-com :msg="msg"></my-com>
      </div>
    </body>
    <template id="myTemp">
      <div>
        <span>当前数量:{{count}}</span>
        <div>{{msg}}</div>
      </div>
    </template>
    <script>
      let myCom = Vue.extend({
        template: '#myTemp',
        data() {
          return {
            count: 0
          }
        },
        props: [
          // 第二步,使用props接收.
          'msg'
        ]
      })
      let app = new Vue({
        el: '#app',
        data: {
          msg: '我是父组件的msg'
        },
        components: {
          myCom
        }
      })
    </script>
    
    1. 对象,对象可以设置传递时的类型和默认值。

    Type支持的类型:String、Number、Boolean、Array、Object、Date、Function、Symbol

    props: {
          msg: {
            type: String,
            default: '我是默认值,父组件没有传给我msg'
          }
        }
    

    具体例子

    <body>
      <div id="app">
        <!-- 第一步,用绑定的方式,将父组件的数据绑定给子组件 -->
        <my-com :msg="msg"></my-com>
      </div>
    </body>
    <template id="myTemp">
      <div>
        <span>当前数量:{{count}}</span>
        <div>{{msg}}</div>
      </div>
    </template>
    <script>
      let myCom = Vue.extend({
        template: '#myTemp',
        data() {
          return {
            count: 0
          }
        },
        // 第二步,使用props接收.
        props: {
          msg: {
            type: String,
            default: '我是默认值,父组件没有传给我msg'//如果父组件没有绑定的时候显示
          }
        }
      })
      let app = new Vue({
        el: '#app',
        data: {
          msg: '我是父组件的msg'
        },
        components: {
          myCom
        }
      })
    </script>
    

    父组件向子组件传递方法 $emit

    我们可以使用自定义事件来完成。父组件调用子组件的方法,使用$emit来实现。

    <body>
      <div id="app">
        <!-- 第一步,在子组件上,使用@符号为该组件绑定一个事件 -->
        <my-com @alert-msg="alertMsg"></my-com>
      </div>
    </body>
    <template id="myTemp">
      <div>
        <button @click="handlerMethod">点我</button>
      </div>
    </template>
    <script>
      let myCom = Vue.extend({
        template: '#myTemp',
        methods: {
          handlerMethod() {
            // 第一个参数表示要调用的方法。用alert-msg,而不是alertMsg
            // 第二个参数往后,就是我们需要传递的参数
            this.$emit('alert-msg', '调用')
          }
        }
      })
      let app = new Vue({
        el: '#app',
        data: {
          msg: '我是父组件的msg'
        },
        methods: {
          alertMsg(msg) {
            alert(msg)
          }
        },
        components: {
          myCom
        }
      })
    </script>
    

    父组件调用子组件方法 $refs

    $refs是和ref一起使用的。通过ref给某个子组件绑定一个特定的ID,然后我们使用$refs.ID就可以访问到子组件了。

    <body>
      <div id="app">
        <button @click="countAdd">点我</button>
        <!-- 第一步,给子组件绑定一个ref -->
        <my-com ref="myComp"></my-com>
      </div>
    </body>
    <template id="myTemp">
      <div>
        {{count}}
      </div>
    </template>
    <script>
      let myCom = Vue.extend({
        template: '#myTemp',
        data() {
          return {
            count: 1
          }
        },
        methods: {
          addCount() {
            this.count++
          }
        }
      })
      let app = new Vue({
        el: '#app',
        methods: {
          countAdd() {
            // 第二步,在父组件中使用this.$refs.id就行了
            console.log(this.$refs.myComp.count)
            this.$refs.myComp.addCount()
          }
        },
        components: {
          myCom
        }
      })
    </script>
    
  • 相关阅读:
    CSS input
    CSS 伪类选择器
    input placeholder 文字颜色修改
    css flex弹性布局学习总结
    jqGrid使用方法
    GridView控件RowDataBound事件的一个实例
    GridView控件RowDataBound事件中获取列字段值的几种途径 !!!
    .net中ckeditor的应用
    博客第一天
    用python实现数学多元数学方程式计算
  • 原文地址:https://www.cnblogs.com/10134dz/p/13594997.html
Copyright © 2020-2023  润新知