Vue组件

  • 将一个具备完整功能的项目的一部分分割多处使用
  • 加快项目的进度
  • 可以进行项目的复用    // 就是活字印刷

组件注册分为:全局注册 和 局部注册


全局组件

全局组件,定义完毕后,就可以直接在项目中任何组件中使用

Vue.component('组件名称', { })

第1个参数是标签名称,第2个参数是一个选项对象。全局组件注册后,任何vue实例都可以用。

!注意:

  • data 必须是函数,同时这个函数要求 返回一个对象

            => 会被调用多次,对象是引用类型,会影响到别人,但是通过函数返回的话每次都是一个新的,互相之间没有影响

  • 必须是单个根节点包裹
  • 内容可以是模板字符串

 太麻烦(不会这么写的)!看看就行

<div id="app">
  <!-- 全局组件注册完毕后,直接调用 -->
  <hello></hello>
</div>

<script>
  // 全局组件注册 -- 一次定义,全局可用
  // vue2.x中建议我们组件用小写(首字母大小写不区分)
  // 组件是小驼峰名称 userName => 转成小写的形式 => user-name
  // data必须是一个函数返回一个对象
  // Vue.component('名称',{配置})
  let cmp = Vue.component('hello', {
    data() {
      return {
        title: 'hello 全局组件'
      }
    },
    // template (字符串模板)/render(接近于原生的json对象)  => vue它是一个虚拟dom(json对象)
    // render中的入参默认是h变量,建设更换,更换后它不支持 jsx
    // template: `<div>{{ title }}</div>`
    render(h) {
      return h(
        'div',
        { attrs: { name: 'aaa' } },
        [
          h('h3', {}, this.title),
          h('h3', {
            on: {
              click: () => {
                console.log('click22222', this.title)
              }
            }
          }, '22222'),
          h('h3', {}, '3333'),
        ])
    }
  });
  // 虚拟dom
  /*
  {
    // <div id="1" name="aaa"><h3>aaaa</h3></div>
    tag:'div',
    attrs:{id:1,name:'aaa'},
    level:1
    children:[
      {
        tag:'h3'
        attrs:{},
        text:'aaaa'
      }
    ]
  }
  */

  // console.log(cmp)

  const vm = new Vue({
    el: '#app',
    data: {
    }

  })
</script>

局部组件(最常用的)!!!

在哪里使用,就需要引入并注册

也是工程化后,所谓的单文件组件,一个文件就是一个组件,此文件的名称一般为.vue

局部组件,使用它有3步

    // 第1步:定义局部组件

    // 第2步:在使用到它的组件中引用

    // 第3步:在使用它的组件中通过配置来注册一下

 定义

<template>
  <div>
  
  </div>
</template>
<script>
  export default {
    name:'组件名称',
    data(){
      return {
        
      }
    } 
  }
</script>
<style lang="scss" scoped>
</style>

引入

import 名称  from 路径

注册

// 在使用使用的组件中注册
export default {
  
  components:{
    名称
  }
}

例子: 


【组件传值 / 边界处理】

父传子 -- props(单向数据流)!!!

props: 单向数据流,修改数据只能通过父组件来修改,通知子组件更新

  • 父组件以属性的形式绑定值到子组件身上
  • 子组件通过使用属性props接收(props是单向绑定的(只读属性):当父组件的属性变化时,将传导给子组件,但是反过来不会)

数组的方案是指给自己去使用    // props: ['age'],

封装一个公用组件给别人用,一定要用对象  类型首字母大写

props: {
  // age: Number
  age: {
    type: Number,
    // 多个类型 => 联合类型
    // type: [Number, String],
    // 此属性必须要存在 true必须值, false可以不传
    // required: true,
    // 默认值,普通类型直接写,引用类型用回调函数
    default: 10,
    // 自定义验证器
    validator: (v) => {
      if (v >= 160) {
        return false
      }
      return true
    }
  },
  user: {
    type: Object,
    /* default: () => {
      return { name: '张三' }
    } */
    // 返回一个对象
    default: () => ({ name: '张三' })
  },
  setagefn: Function
},

利用父组件传入子的【函数】,修改数据

// 父把【方法】传过去,透传

【改数据这步操作永远要在父操作】!!!


子传父    // this.$emit() !!!

给当前此组件添加一个自定义事件

this.$emit('自定义事件的名称',[...参数])

【改数据这步操作永远要在父操作】!!!

<div id="app">
  <child :age="age" @onsetage="setage"></child>
</div>

<script>
  // 子组件
  const Child = {
    data() {
      return {
        title: '我是一个局部组件'
      }
    },
    props: {
      age: Number
    },
    template: `<div @click="incr">{{title}}  --- {{age}}</div>`,
    methods: {
      incr() {
        // props单向数据流
        // this.$emit('自定义事件的名称',[...参数])
        // 给当前此组件添加一个自定义事件
        this.$emit('onsetage', 10)
      }
    }
  }

  // 根组件
  const vm = new Vue({
    el: '#app',
    data: {
      age: 100
    },
    // key就是在html中使用的标签名称,value组件对象
    components: { child: Child },
    methods: {
      setage(num) {
        this.age += num
      }
    }

  })
</script>


事件总线 eventBus

在Vue中通过单独的事件中心来管理组件间的传值。

就是一个对象,一个往对象里写东西,一个读取对象内的东西。

得到一个事件总线对象

const bus = new Vue();

 

<div id="app">
  <h3 @click='parentsend'>new Vue -- {{msg}}</h3>
  <app></app>
</div>

<script>
  // 得到一个事件总线对象
  const bus = new Vue();

  const Child1 = {
    data() {
      return {
        msg: ''
      }
    },
    created() {
      // console.log('Child1')
      // bus.$on('hello', (msg) => console.log('child1 ---' + msg))
      bus.$on('hello', msg => this.msg = msg)
    },
    /* mounted(){
      console.log('mounted -- Child1')
    }, */
    template: `<div>
      <h3>我是Child1 -- {{msg}}</h3>
      </div>`
  }
  const Child2 = {
    data() {
      return {
        world: ''
      }
    },
    created() {
      // console.log('Child2')
      bus.$on('world', world => this.world = world)
    },
    /* mounted(){
      console.log('mounted -- Child2')
    }, */
    template: `<div>
      <h3 @click="sendhello">我是Child2 -- {{world}}</h3>
      </div>`,
    methods: {
      sendhello() {
        bus.$emit('hello', 'child2消息')
      }
    }
  }

  const App = {
    data() {
      return {

      }
    },
    /* created(){
      console.log('App')
    },
    mounted(){
      console.log('mounted -- App')
    }, */
    components: {
      Child1,
      Child2
    },
    template: `<div>
      <h3>我是App</h3>
      <child1></child1>
      <child2></child2>
      </div>`
  }



  // new Vue
  const vm = new Vue({
    el: '#app',
    data: {
      msg: ''
    },
    components: { App },
    created() {
      // 订阅
      bus.$on('hello', msg => this.msg = msg)
    },
    beforeDestroy() {
      // 关闭订阅
      bus.$off('hello')
    },
    methods: {
      parentsend() {
        // 发布 
        bus.$emit('world', 'new Vue发过来了')
      }
    }
  })
</script>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值