组件传值、中央事件总线、动态组件、缓存组件、异步组件

组件传值-provide-inject

通常情况下,组件向组件传递数据,可以采用父子props层层传递,也可以使用busVuex直接交互。在Vue2.2.0之后,Vue还提供了provide/inject选项
但是官网还是不太建议我们直接使用这个方法,因为怕我们“管不好”

//爷爷
<template>
  <div>
    <p>{{ title }}</p>
    <son></son>
  </div>
</template>
<script>
  import Son from "./son"
  export default {
    name: 'Father',
    components: { Son },
    // provide选项提供变量
    provide: {
      message: 'provided by father'
    },
    data () {
      return {
        title: '父组件'
      }
    },
    methods: { ... }
  }
</script>

//爸爸
<template>
  <div>
    <p>{{ title }}</p>
    <grand-son></grand-son>
  </div>
</template>
<script>
import grandSon from "./grandSon "
export default {
  name: "Son",
  components: { grandSon },
  data () {
    return {
      title: '子组件'
    }
  },
};
</script>
//孙子
<template>
  <div>
    <p>message:{{ message }}</p>
  </div>
</template>
<script>
export default {
  name: "GrandSon",
  inject: [ "message" ],
  data () {
    return {
      title: '孙组件'
    }
  },
  methods: { ... }
};
</script>

我在App中可以调用Box2的数据,但是当我点击按钮时,是修改不了页面的数据的。
在这里插入图片描述

组件传值-provide-inject 响应式设计

这个就比较麻烦,provide得是一个函数返回值是data中的数据,使用者使用的时候,就是Box中使用的时候得把msg当成一个函数来使用,通过调用来收到数据

这里我点击按钮,可以发现页面变了
在这里插入图片描述

自定义事件的语法

Vue提供的技术:某继承Vue的组件有三个功能:
1.触发x组件的a事件: x.$emit(“a事件”,参数…)
2.给x组件绑定a事件 x.$on(“a事件”,监听器函数)
3.给x组件解绑a事件 x.$off(“a事件”,监听器函数)

现在当我直接点击第二个按钮时是界面是没有仍和反应的
在这里插入图片描述
现在我点击了第一个按钮,界面也没有仍和反应,但是当我现在点击第二个按钮时,控制台出现了打印,说明我点第一个按钮时成功给App组件绑定了myclick事件
在这里插入图片描述

<template>
  <div>
    <button @click="fn1">给App组件绑定一个myclick事件</button>
    <button @click="fn2">触发自定义myclick事件</button>
  </div>
</template>
<script>
export default {
  methods:{
    fn1(){
      // 给App组件绑定myclick事件
      this.$on('myclick',
      function(arg1,arg2){
        console.log('myclick事件触发了',arg1,arg2);
      })
    },
    // 触发App组件的myclick事件
    fn2(){
      this.$emit('myclick',1,2)
    }
  }
};
</script>

<style scoped="scoped" lang="scss"></style>

中央事件总线

$bus 思路是在全局挂载一个实例,通过这个实例里的事件派发和事件监听实现跨组件通信,设计模式叫做观察者模式。一般用于跨多层级组件传参。

使用$bus的时候在接受bus的组件中别忘了再beforDestroy函数中销毁bus,不销毁的话会一直叠加的调用这个方法:

  beforDestroy(){
         this.$bus.$off("event");  //当这个组件销毁的时候bus也跟着一起销毁
     }

通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果

//vue-bus.js文件
const install = function (Vue) {
  const Bus = new Vue({
    methods: {
      emit(event, ...args) {
        this.$emit(event, ...args);
      },
      on(event, callback) {
        this.$on(event, callback);
      },
      off(event, callback) {
        this.$off(event, callback);
      }
    }
  });
  Vue.prototype.$bus=Bus;//由于这个新的vm放在与界面绑定的那个vm的原型上,因此页面上的所有组件都能通过this.$bus访问这个新vm对象
};
export default install;




//main.js文件
import VueBus from './vue-bus'
Vue.use(VueBus);

//组件文件中:
任意业务中都可以通过调用来绑定事件,触发事件并传值,和销毁事件 
this.$bus.on(event,callback) 
this.$bus.off(event,callback) 
this.$bus.emit(event, ...args)

示例:
组件1:
 this.$bus.on('changedFormObject',(val) =>{
	        //接受并处理传过来的值:val
            this.msg = val;
        });

组件2:
this.$bus.emit('changedFormObject',this.inputValue);//把组件2的data中的给inputValue值传给组件1

动态组件

有的时候,我们希望页面中的某个地方,在不同组件之间进行动态切换,这时候除了条件渲染,还可以使用动态组件

component 标签的 is属性语法:is后跟组件的变量名决定使用哪个组件来渲染
注意: is是组件名 :is是data中的变量中保存的组件名

<template>
  <div id="app">
    <button @click="fn">xx</button>
     <components :is="com"></components>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import HelloWorld2 from './components/HelloWorld2.vue'
export default {
  name: 'app',
  data(){return{
	  flag:true,
	  com:"HelloWorld",
  
  }},
  components: {
    HelloWorld,"HelloWorld2"
  },
  methods:{
	  fn(){
		 this.flag=!this.flag
		 this.com=this.flag?"HelloWorld":"HelloWorld2"
	  }
  }
}
</script>

缓存组件keep-alive

动态组件的切换,切换后是不会缓存之前被切换掉的组件的,每次切换新组件的时候,Vue 都创建了一个新的组件对象。
有时候我们希望在A组件时用户做了一些操作,切换B组件时做了一些操作,当切回A组件时希望记住A的操作,不要重新创建A组件,keep-alive可以缓存动态切换的组件

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

<!-- 提供有include 和exclude 属性决定哪些组件可以被缓存(字符串或正则表达式)。!-->

<keep-alive :include="/a|b/"> 
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>
//include表示a,b组件被缓存,其他组件不缓存,exclude代表除了xx组件其他的组件缓存

匹配首先检查组件自身的 name 选项,匿名组件不能被匹配。

<template>
  <div id="app">
    <button @click="fn">xx</button>
     <keep-alive>
     	<components :is="com"></components>
     </keep-alive>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import HelloWorld2 from './components/HelloWorld2.vue'
export default {
  name: 'app',
  data(){return{
	  flag:true,
	  com:"HelloWorld",
  
  }},
  components: {
    HelloWorld,"HelloWorld2"
  },
  methods:{
	  fn(){
		 this.flag=!this.flag
		 this.com=this.flag?"HelloWorld":"HelloWorld2"
	  }
  }
}
</script>

异步组件

vue开发过程中,我们会做出特别多特别多的组件,包括login,header,footer,main等等。这样使整个网站看起来就十分的庞大,当我们在打开网页的时候,突然一下子把这些所有的组件加载上来,这么多的请求全部同时开始请求,势必会造成网页打开很慢,使客户得到的是非常差劲的体验。

SPA: single page app

在单页应用中,如果没有用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时

异步加载并缓存组件:
1、 异步加载组件:用不到的组件不会加载,因此网页打开速度会很快,当你用到这个组件的时候,才会通过异步请求进行加载;

官方解释:Vue允许将组件定义为一个异步解析(加载)组件定义的工厂函数,即Vue只在实际需要渲染组件时,才会触发调用工厂函数,并且将结果缓存起来,用于将来再次渲染

2、 组件缓存起来:通过异步加载的组件会缓存起来,当你下一次再用到这个组件时,丝毫不会有任何的疑迟,组件很快会从缓存中加载出来。

vue组件中require和import的区别
1.本质不同
import是一个解构过程,import语法会被转码为require;而require是一个赋值过程,其结果就是对象、数字、字符串、函数等,再把require的结果赋值给变量。
2.遵循的规范不同
import是es6中的一个语法标准,需要转化成es5语法;而require本身就是AMD规范的引入方式。
3.调用方式不同
import是在编译时调用,且必须在文件开头调用;而require是在运行时调用,可以在代码的任何地方进行调用。
4.性能不同
import只需要依据import中的接口在编译时引入指定模块;而require在在运行时引入模块并赋值给变量,性能相对于import稍低。
5.基本语法不同
使用import导出的对象与整个模块进行结构赋值,且对象必须与模块中的值一一对应;而require在导出的文件中定义module.export,其导出的对象的类型可以是任何类型,只需要在引入的文件中使用require()方法调用对象即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值