1、Bus(总线)实现非父子组件通信

Vue2.0提供了Vuex进行非父子组件之间的通信,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。

实现代码示例:

<div id="app">
<c1></c1>
<c2></c2>
</div>
var Bus = new Vue();   //为了方便将Bus(空vue)定义在一个组件中,在实际的运用中一般会新建一Bus.js
Vue.component('c1',{   //这里以全局组件为例,同样,单文件组件和局部组件也同样适用
template:'<div>{{msg}}</div>',
data: () => ({
msg: 'Hello World!'
}),
created() {
Bus.$on('setMsg', content => {     //监听Vue示例 Bus 的某一个事件
this.msg = content;
});
}
});
Vue.component('c2',{
template: '<button @click="sendEvent">Say Hi</button>',
methods: {
sendEvent() {
Bus.$emit('setMsg', 'Hi Vue!');  //触发vue示例 bus 的某一个事件,并且将参数作为数据传过去
}
}
});
var app= new Vue({
el:'#app'
})

在实际运用中,一般将Bus抽离出来:

// Bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus

组件调用时先引入

// 组件1
import Bus from './Bus'
export default {
data() {
return {
.........
}
},
methods: {
....
Bus.$emit('log', 120)
},
}
// 组件2
import Bus from './Bus'
export default {
data() {
return {
.........
}
},
mounted () {
Bus.$on('log', content => {
console.log(content)
});
}
}

但这种引入方式,经过webpack打包后可能会出现Bus局部作用域的情况,即引用的是两个不同的Bus,导致不能正常通信

1.1、推荐使用Bus的方式

(1)直接将Bus注入到Vue根对象中

import Vue from 'vue'
const Bus = new Vue()
var app= new Vue({
el:'#app',
   data:{
    Bus
}  
})

在子组件中通过this.$root.Bus.$on()、this.$root.Bus.$emit()来调用

(2)在一个教程视频中看过,也可以通过将Bus放在vue示例的原型对象中使用

Vue.prototype.bus = new Vue();

每个组件都是一个Vue示例,所以每个组件都会有bus属性,在组件中可以通过 this.bus.$emit、this.bus.$on 来调用

Vue.component('c2',{
template: '<button @click="sendEvent">Say Hi</button>',
methods: {
sendEvent() {
this.bus.$emit('setMsg', 'Hi Vue!');  
}
}
});

参考:https://www.cnblogs.com/fanlinqiang/p/7756566.html

2、异步组件(按需加载)

官方文档:https://cn.vuejs.org/v2/guide/components-dynamic-async.html

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

其实 vue 中实现按需加载也非常简单,只要将平常的导入组件的方式改一下就行,vue-router会自动帮我们实现按需加载需要的组件,而 webpack 会自动帮我们实现代码拆分,由此实现了在需要的时候才加载需要的组件文件。

2.1、使用resolve => require([’./_account’], resolve)实现按需加载

创建一个项目,组件目录:Helloworld 组件是首页,在 HelloWord 中引入加载 item01 组件,在 item01 组件中引入加载 item02 组件。

     1、使用普通的引入方式:

//HelloWord.vue 中的代码
<template>
<div class="hello">
<h3>this is HelloWorld</h3>
<template v-if="showItem">
<Item01></Item01>
</template>
<button @click="toggleItem">切换</button>
</div>
</template> import Item01 from './Item01.vue'
export default {
name: 'HelloWorld',
data () {
return {
showItem: false
}
},
components: {
Item01
},
methods: {
toggleItem () {
this.showItem = !this.showItem;
}
}
} //Item01.vue 中的代码
<template>
<div>
<h3>this is item01</h3>
<Item02></Item02>
</div>
</template> import Item02 from './Item02.vue'

运行项目:

点击切换按钮,显示 item01、item02 组件:

可以看到,加载的 JS 文件并没有任何变化,即没有新加载 JS 文件。可以看到 item01和 item02 组件都被打包到了 app.js 文件中,所有的组件 JS 代码都被打包到了一个文件中,这会导致该文件过大,影响加载速度。

      2、使用按需加载的方式:

//HelloWord.vue 中的代码
<template>
<div class="hello">
<h3>this is HelloWorld</h3>
<template v-if="showItem">
<Item01></Item01>
</template>
<button @click="toggleItem">切换</button>
</div>
</template> const Item01 = resolve => require(['./Item01'],resolve) //按需加载 item01 组件
export default {
name: 'HelloWorld',
data () {
return {
showItem: false
}
},
components: {
Item01
},
methods: {
toggleItem () {
this.showItem = !this.showItem;
}
}
} //Item01.vue 中的代码
<template>
<div>
<h3>this is item01</h3>
<Item02></Item02>
</div>
</template> const Item02 = resolve => require(['./Item02'],resolve) //按需加载 item02 组件

运行项目:

点击切换按钮,显示 item01、item02 组件:

可以看到,一开始没有显示 item01、item02 组件时,浏览器只加载了 app.js 文件。当点击按钮显示 item01、item02 组件后,开始依次加载 item01、item02打包后的 JS 文件。

通过按需加载,webpack 会帮我们将需要按需加载的组件跟一开始需要加载的 JS 文件分离开,当需要加载的时候再加载。按需加载只是改变掉加载组件的方式而已,webpack 会自动帮我们实现按需加载。

利用此特性,我们便能做很多针对前端的优化。比如:将页面核心功能(音、视频播放、文章、商品等等)打包成一个核心模块,通过框架优先加载。其他的一些周边功能打包后,通过服务器异步加载,从而解决业务需求越来越多导致的系统难维护、访问慢问题。

参考:https://segmentfault.com/a/1190000012138052

其它实现按需加载的引入方法可以参考:https://blog.csdn.net/scarlett_dream/article/details/83756392https://segmentfault.com/a/1190000011519350

3、Vue 动态插入组件

代码示例:

<div id="app">
<p>{{ message }}</p >
<button @click="add('a-component', '我是A')">添加A组件</button>
<button @click="add('b-component', '我是B')">添加B组件</button>
<component :is="item.component" :text="item.text" v-for="item in items"></component>
</div>
js: <script>
const aComponent = Vue.extend({
props: ['text'],
template: '<li>A Component: {{ text }}</li>'
}) const bComponent = Vue.extend({
props: ['text'],
template: '<li>B Component: {{ text }}</li>'
}) new Vue({
el: '#app',
data () {
return {
message: 'Hello Vue.js!',
items: []
}
},
methods: {
add (name, text) {
this.items.push({
component: name,
text: text
})
}
},
components: {
aComponent,
bComponent
}
})
</script>

Vue.extend 是构造一个组件的语法器。你给它参数它给你一个组件,然后这个组件你可以作用到Vue.component 这个全局注册方法里, 也可以在任意vue模板里使用<apple>组件

var apple = Vue.extend({
....
})
Vue.component('apple',apple)

也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件

new Vue({
components:{
apple:apple
}
})

Vue使用的扩展的更多相关文章

  1. 第3章-Vue.js 指令扩展 和 todoList练习

    一.学习目标 了解Vue.js指令的实现原理 理解v-model指令的高级用法 能够使用Vue.js 指令完成 todoList 练习(重点+难点) 二.todoList练习效果展示 2.1.效果图展 ...

  2. 2、Vue构造器和扩展

    1.VUE构造器简介 VUE构造器是一个非常重要的语法. 每个Vue.js应用都是通过构造函数Vue创建一个根实例. New了Vue对象,然后调用了这个vue对象的构造器,并向构造器传入了数据. 在实 ...

  3. vue 安装sass扩展

    1.创建一个基于 webpack 模板的新项目 $ vue init webpack myvue 1 2.在当前目录下,安装依赖 $ cd myvue $ npm install 1 2 3.安装sa ...

  4. Vue的思考扩展

    1.Vue是如何实现数据双向绑定的 1.1.实现双向绑定的基本原理 数据驱动:Vue会通过Dircetives指令,对DOM做一层封装,当数据发生改变会通知指令去修改对应的DOM,数据驱动DOM变化, ...

  5. vue开发chrome扩展,数据通过storage对象获取

    开发chrome插件时遇到一个问题,那就是单文件组件的data数据需要从chrome提供的storage对象中获取,但是 chrome.storage.sync.get 方法是异步获取数据的,需要通过 ...

  6. vue - Vue路由(扩展)

    忙里偷闲,还在学校,趁机把后面的路由多出来的知识点学完 十.缓存路由组件 让不展示的路由组件保持挂载,不被销毁 在我们的前面案例有一个问题,都知道vue的路由当我们切换一个路由后,另一个路由就会被销毁 ...

  7. Vue 向下扩展后就类似于 jQuery

    https://cn.vuejs.org/v2/guide/comparison.html

  8. Vue.js——60分钟组件快速入门(上篇)

    组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢?组件可以扩展HTML ...

  9. Vue.js组件学习

    组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素.组件系统提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用. 一个简单组件例子(全局注册) &l ...

随机推荐

  1. MySQL分组聚合group_concat + substr_index

    场景:给予一张商品售卖表,表中数据为商品的售卖记录,假设表中数据是定时脚本插入的,每个时间段的商品售卖数量不同,根据此表找各个商品的最多售卖数量的数据. 1.数据表 CREATE TABLE `goo ...

  2. Linux下安装mysql教程

    Linux下安装mysql  MySQL官网:https://dev.mysql.com/downloads/mysql/ 到mysql官网下载mysql编译好的二进制安装包,在下载页面Select ...

  3. ruby的require路径问题

    ruby1.9删除当前目录功能,require "Action.rb"不行. 用下面2种方式: require_relative "trig.rb" .rb可以 ...

  4. 关于Vue+iview的前端简单的导入数据(excel)

    前一段时间项目经历了纯前端处理导入excel文件并处理等问题,数据量大的时候时间上长的一比,三千条数据需要三四秒甚至更长,不管产品咋想的,具体做法为: 首先下载一个这玩意: 进行简单封装一下: < ...

  5. 洛谷T89643 escape

    题目描述 题目链接:https://www.luogu.org/problem/T89643 由于 Kiana 实在是太忙了,所以今天的题里面没有 Kiana. 某一天学校里有 n 节课,出题人希望逃 ...

  6. 题解1235. 洪水 (Standard IO)

    Description 一天, 一个画家在森林里写生,突然爆发了山洪,他需要尽快返回住所中,那里是安全的.森林的地图由R行C列组成,空白区域用点“.”表示,洪水的区域用“*”表示,而岩石用“X”表示, ...

  7. ICPC2019上海区域赛 部分题解(正在更新)

    K. Color Graph 题意: 给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少? 思路: 如果一个图中无奇数边的环,那么这个图一定是个二分 ...

  8. upc组队赛17 Stone Game【极小值】

    Stone Game 题目链接 题目描述 Alice and Bob are always playing game! The game today is about taking out stone ...

  9. php开发环境是什么

    软件开发环境(Software Development Environment,SDE)是指在基本硬件和数字软件的基础上,为支持系统软件和应用软件的工程化开发和维护而使用的一组软件,简称SDE.它由软 ...

  10. Struts2之处理结果集

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-/ ...