vue 组件和组件通信

vu 两大特性:

1 . 指令 – 用来操作 dom

2 . 组件 – 组件是 html css js的聚合体

为什么要使用组件?

  1. 组件可以在项目中进行复用
  2. 加快项目进度
  3. 将一个具备完整功能的项目的一部分进行多处使用

要想使用组件化,那么这个组件是完整的

组件中的根元素必须是唯一

组件要先注册,再实例化,要在实例范围内执行

vue 借鉴 react ,组件以标签的形式呈现的。

//组件使用前必须先注册
Vue.component(组件名称,组件配置)
var Hello = Vue.extend({})
Vue.compoent('Father', Hello)

可以简化
Vue.componet('Father', {
	template
})

组件的创建

  1. 全局注册

    所有实例都可以使用

    Vue.componet('Father', {
    	template
    })
    
  2. 局部注册

    在实例中间使用 components:{ }

    new Vue({
    	el: '#app',
    	components: {
    		'Father': {
    		   template: '<div>局部组粗</div>'
    		}
    	}
    })
    

组件的嵌套

在父组件里放子组件: 将子组件以标签的形式放在父组件中

全局嵌套

<div id="app">
	<Father></Father>
</div>
<template id="father">
	<h3>这里是父组件模板</h3>
	</Son>
</template>
Vue.component('Father',{
	template: '#father'
})
Vue.component('Son', {
	template:'<div> son </div>'
})

局部嵌套

new Vue([
    el: '#app',
    compoents: {
		template: '<div> father 组件 </Son> </div>',
		components: {
			'Son': {
				template: '<div> son 组件 </div>
			 }
		}
	}
])

is 规则

ul>li ol>li table>tr>td select>option

如上直属父子级如果直接组件以标签化形式使用,会出现 bug

解决:需要通过 is 属性来绑定一个组件

组件的一些特殊使用规则 【

组件通信

1. 为什么要进行组件通信?

  • 每个组件都是一个独立功能的整体,当我们要将这些组件拼接在一起时,就需要在这些组件之间建立通信

2 组件的通信有哪些?

1. 父子组件通信

​ 使用 props 来实现

//1.在父组件的模板中将数据用单项数据绑定的形式(v-bind)绑定到子组件上
 <Son :aa = "money"  :maskFlag = "maskFlag"/>
 Vue.component('Father',{
    template: '#father',
    data () { 
      return {
        money: 2000,
      }
    }
  })
  Vue.component('Son',{
    template: '#son',
    props: ['aa','maskFlag']          
  })

2. 子父组件通信

​ 使用做自定义事件通信

  1. 在父组件模板中,通过事件绑定的形式,绑定一个自定义事件在子组件身上

    <Son @a = 'fn'>  //注意: fn 是在父组件配置项 methods 中定义
    
  2. 在子组件的配置项 methods 中写一个事件处理程序,在事件处理程序中 使用 $emit() 触发父组件中绑定的自定义事件

     Vue.component('Son',{
        template: '#son',
        props: ['aa','maskFlag']          
      })
    
  3. 将子组件定义事件处理函数 ,绑定到子组件的按钮上

    
    

3. 非父子组件通信

1.ref 链

父组件通过 ref 链得到一个子组件的数据,在把数据发送到另一个子组件上,就可以实现非父子组件的通信,当是如果层级太多,就比较繁琐

2.bus 事件总线

通过 bus. o n 来 定 义 事 件 , 通 过 on 来定义事件,通过 onemit 来触发事件

  1. 在其中一个组件的 mounted 钩子函数上进行事件声明

     Vue.component('sma', {
        template: '#sma',
        data() {
          return {
            flag: false
          }
        },
        mounted () { //在 mounted 钩子函中事件声明  
          let _this = this
          bus.$on('aa', function(){   // 事件声明 
            _this.flag = true;
          })
        }
      })
    
  2. 在另一个组件中,通过 bus.$emit(‘aa’) 来触发这个事件

4. 多组件状态共享 ( 多组件共有同一个数据)

vuex

5. 非常规通信方式

不推荐:因为 mvvm 框架是单项数据流

1. 父子通信

父组件窗体一个 对象类型 给子组件,子组件通过 props 接收,

会发现:子组件修改数据时,父组件的数据也会发生改变

因为父组件传递给子组件的是一个对象引用地址

<body>
  <div id="app">
    <Father></Father>
  </div>
  <template id="father">
    <div>
      <h3>这是fatcher 组件</h3>
      <p>父组件小金库 ---{{ xiaojingku.money }}</p>
      <Son :xiaojingku="xiaojingku"></Son>
    </div>
  </template>

  <template id="son">
    <div>
      <h3>这是 son组件</h3>
      <button >give</button>
      <input type="text" v-model="xiaojingku.money">
      <p>son : {{ xiaojingku.money}}</p>
    </div>
  </template>
</body>
<script>

2. 子父通信

父组件将一个方通过属性绑定的形式给了子组件,子组件用 props 接收方法,在子组件中调用方法并传参

<div id="app">
    <Father></Father>
  </div>
  <template id="father">
    <div>
      <h3>这是fatcher 组件</h3>
      <Son :add="add"></Son>  //1.将方法绑定到子组件上
      {{ n }}  //2000
    </div>
  </template>

  <template id="son">
    <div>
      <h3>这是 son组件</h3>
      <button @click="add(money)">give</button>  //3. 子组件调用传来的方法,并传值
    </div>
  </template>
</body>
<script>

  Vue.component('Father', {
    template: '#father',
    data() {
      return {
        n: 0
      }
    },
    methods: {
      add (val) {
        this.n = val;
      }
    }
  })
  Vue.component('Son', {
    template: '#son',
    data() {
      return {
        money: 1000
      }
    },
    props: ['add']   //2. 子组件接收方法
  })
  new Vue({
    el: '#app',
  })

3. 动态组件

  1. 什么是动态组件?

​ 可以修改的组件

  1. 使用

​ vue 提供过了 一个 compoent 标签(组件) + is 属性 来实现

<body>
  <div id="app">
    <button  @click="change" >切换</button>
    <keep-alive>       <kee-alive> 组件 可以对组件进行浏览器缓存,在切换组件时就可以提高效率。
        <component :is = "type"></component>
    </keep-alive>
  </div>
</body>
  
<script>
    Vue.component('A',{
      template: '<div>A组件啊</div>'
    })
    Vue.component('B',{
      template: '<div>B组件啊啊</div>'
    })
    new Vue({
      el: '#app',
      data: {
        type: 'A',
      },
      methods: {
        change(){
          this.type = this.type === 'A' ? 'B':'A';
        }
      }
    })
  </script>

语法糖: 对代码的另一种语法实现,功能保持不变,提高代码的可读性,减少出错

组件中data定义是一个函数?

因为组件是一个独立的个体,应该拥有的自己独立的作用域数据。

为什么data 为什么要有 return,return 的还是一个对象?

1. 因为Vue 是通过observer 来观察 data选项的,所以必须要有 返回值。
2. 应为Vue 要通过 es5 的Object.defineProperty 属性对对象 进行getter 和 setter 设置,这个属性传的第一个参数是一个对象。

自定义事件的发布

  1. 通过$on 发布, $emit 触发

vm.$on(自定义事件名称,自定义事件处理函数)

vm.$on('a', function() {
	console.log( 'aaa');
})
vm.$emit(自定义事件的名称,自定义事件需要的参数);
  1. 把事件在组件上定义,通过 $emit() 触发

app实例的手动挂载

new Vue({
}).$mount('#app');

属性验证

  1. props: [ ‘msg’ ] 只是单纯的接收了一个父组件传来的数据,没有验证

  2. props: { attr: attType } 进行数据类型验证

  3. props: { type: typeType, defalut: value } 为数据设置初始值

  4. props: { varlidator ( val ) { return boolean }} 对数据进行条件比较,return booblean

  5. 第三方包: vue-validata vee-validate…

     Vue.component('Son', {
        template: '#son',
        props:{
          // key: value
          'money': Number,
          'n': {
            validator ( val ) { //属性验证函数,一般用于条件比较
              return val > 200
            }
          },
          'num': {
            type: Number,
            default: 200
          }
        }
      })
    

过滤器

  1. 什么是过滤器?

    • 用来格式化数据的一个函数

      vue 1.x 借鉴啦 angular, 提供了 10 个过滤器( 日期,小数点位数保留,货币,大小写)

      vue 2.x 废弃了 这10个过滤器,提供自定义过滤器的方式

  2. 使用方式

    过滤器要想获得我们的数据,要通过一个叫 ‘管道符 | ’ 来获取数据

    过滤器是对已有的数据进行格式化,必须先得到数据在可视化

    1. 全局定义过滤器
     
       ```vue
       // Vue.filter(过滤器名称, 回调函数);
       <body>
         <div id="app">
           <p>{{ time | timeFilter("/") }}</p>
         </div>
       </body>
       <script>
          Vue.filter('timeFilter', (val, type) => {
            let data = new Date();
            return data.getFullYear() + type + ( data.getMonth() + 1 ) + type + data.getDate();
         })
       ```
    
    1. 局部定义过滤器

      <body>
        <div id="app">
          <p> {{time | timeFilter('-')}}</p>
        </div>
      </body>
      <script>
        new Vue({
          el: '#app',
          data: {
            time: Date.now()
          },
          filters: {
            'timeFilter': function (val, type) {
              let date = new Date();
              return date.getFullYear() + type + date.getMonth() + 1 + type + date.getDate();
            }
          }
        })
      

    solot 插槽

  3. 作用/概念: 预先将将来要是用的内容进行保留

  4. 具名插槽:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值