VUE学习-优化组件
组件(优化)
动态组件
keep-alive
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。
有时我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>

** 切换tag时保存标签页状态
注意这个
<keep-alive>要求被切换到的组件都有自己的名字,不论是通过组件的name选项还是局部/全局注册。
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :exclude="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
<keep-alive :max="10">
<component :is="view"></component>
</keep-alive>
异步组件
Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
// 模拟异步组件
Vue.component('async-example', function (resolve, reject) {
// 向 `resolve` 回调传递组件定义
setTimeout(function () {
resolve({template: '<div>I am async!</div>'})
}, 1000)
})
// 结合webpack使用
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 require 语法将会告诉 webpack自动将你的构建代码切割成多个包,这些包会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
// 动态导入 --这个动态导入会返回一个 `Promise` 对象。
Vue.component('async-webpack-example',() => import('./my-async-component'))
new Vue({components: {'my-component': () => import('./my-async-component')}})
异步组件工厂函数
const AsyncComponent = () => ({
component: import('./MyComponent.vue'),// 需要加载的组件 (应该是一个 `Promise` 对象)
loading: LoadingComponent,// 异步组件加载时使用的组件
error: ErrorComponent,// 加载失败时使用的组件
delay: 200,// 展示加载时组件的延时时间。默认值是 200 (毫秒)
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
注意如果你希望在 Vue Router 的路由组件中使用上述语法的话,你必须使用 Vue Router 2.4.0+ 版本。
$root
在每个 new Vue 实例的子组件中,其根实例可以通过 $root property 进行访问。
所有的子组件都可以将这个实例作为一个全局 store 来访问或使用。
// Vue 根实例
new Vue({
data: {foo: 1},
computed: {
bar: function () { /* ... */ }
},
methods: {
baz: function () { /* ... */ }
}
})
this.$root.foo // 获取根组件的数据
$parent
$parent property 可以用来从一个子组件访问父组件的实例。
// 在层级嵌套组件里会失控。因此向任意更深层级的组件提供上下文信息时推荐依赖注入
var map = this.$parent.map || this.$parent.$parent.map
$refs
在 JavaScript 里直接访问一个子组件可以通过 ref 这个 attribute 为子组件赋予一个 ID 引用。
<base-input ref="usernameInput"></base-input>
现在在 JS 里可以通过 this.$refs.usernameInput引用这个组件
$refs只会在组件渲染完成之后生效,并且它们不是响应式的。
<div id="comp">
<base-input ref="usernameInput"></base-input>
</div>
<script>
Vue.component('base-input',template:`<input ref="input">`)
new Vue({
el:'#comp',
...
this.$refs.input.focus()
...
})
</script>
依赖注入 (provide & inject)
使用 $parent property 无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provide 和 inject。
- provide 选项允许我们指定我们想要提供给后代组件的数据/方法。
- inject 选项允许接收指定的我们想要添加在这个实例上的 property。
- from property 是在可用的注入内容中搜索用的 key
- default property 是降级情况下使用的 value
provide: [object | ()=>object]
inject: Array<String>
// 父级组件提供 'getMap'
provide: function () {
return {getMap: this.getMap}
}
// 子组件注入 'getMap'
inject: ['getMap']
// 用 from 来表示其源 property
const Child = {
inject: {
foo: {from: 'bar',default: () => [1, 2, 3]}
}
}
相比 $parent 来说,这个用法可以让我们在任意后代组件中访问 getMap,而不需要暴露整个 <google-map> 实例。
- 祖先组件不需要知道哪些后代组件使用它提供的 property
- 后代组件不需要知道被注入的 property 来自哪里
provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
事件侦听器
- 通过
$on(eventName, eventHandler)侦听一个事件 - 通过
$once(eventName, eventHandler)一次性侦听一个事件 - 通过
$off(eventName, eventHandler)停止侦听一个事件
// 一次性将这个日期选择器附加到一个输入框上,它会被挂载到 DOM 上。
// Pikaday 是一个第三方日期选择器的库
mounted: function () {
this.picker = new Pikaday({field: this.$refs.input,format: 'YYYY-MM-DD'})
},
// 在组件被销毁之前,也销毁这个日期选择器。
beforeDestroy: function () {
this.picker.destroy()
}
上述的picker挂载到了Vue实例的data上,而实际我们 只需要在生命周期钩子函数上使用并销毁
一次侦听可以解决这样的问题,每个新的实例都程序化地在后期清理它自己。
mounted: function () {
var picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
})
this.$once('hook:beforeDestroy', function () {
picker.destroy()
})
}
// 封装picker,每个picker在实例销毁之前销毁自身
mounted: function () {
this.attachDatepicker('startDateInput');
this.attachDatepicker('endDateInput')},
methods: {attachDatepicker: function (refName) {
var picker = new Pikaday({
field: this.$refs[refName],
format: 'YYYY-MM-DD'
})
this.$once('hook:beforeDestroy', function () {picker.destroy()})
}
}
递归组件
组件是可以在它们自己的模板中调用自身的。不过它们只能通过 name 选项来做这件事
// 使用一个最终会得到 false 的 v-if
Vue.component('stack', {
template: '<div><stack v-if="done"></stack></div>'
})
组件间的循环引用
如果你使用一个模块系统依赖/导入组件,例如通过 webpack 或 Browserify,你会遇到一个错误
<!-- <tree-folder> 组件 -->
<p>
<span>{{ folder.name }}</span>
<tree-folder-contents :children="folder.children"/>
</p>
<!-- <tree-folder-contents> 组件 -->
<ul>
<li v-for="child in children"><tree-folder v-if="child.children" :folder="child"/>
<span v-else>{{ child.name }}</span>
</li>
</ul>
- Vue.component 全局注册组件的时候,这些组件在渲染树中互为对方的后代和祖先。
- 等到生命周期钩子 beforeCreate 时去注册它
beforeCreate: function () {
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default}
- 使用 webpack 的异步 import
components: {TreeFolderContents: () => import('./tree-folder-contents.vue')}
内联模板
当 inline-template 这个特殊的 attribute 出现在一个子组件上时,这个组件将会使用其里面的内容作为模板,而不是将其作为被分发的内容。
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
</div>
</my-component>
内联模板需要定义在 Vue 所属的 DOM 元素内。
X-Template
在一个 <script> 元素中,并为其带上 text/x-template 的类型,然后通过一个 id 将模板引用过去。
<script type="text/x-template" id="hello-world-template">
<p>Hello world</p>
</script>
<script>
Vue.component('hello-world', {template: '#hello-world-template'})
</script>
x-template 需要定义在 Vue 所属的 DOM 元素外。
强制更新
$forceUpdate :迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
v-once
有的时候你可能有一个组件,这个组件包含了大量静态内容。在这种情况下,你可以在根元素上添加 v-once attribute 以确保这些内容只计算一次然后缓存起来。
Vue.component('terms-of-service', {
template: `<div v-once><h1>Terms of Service</h1>... a lot of static content ...</div>`
})
可能导致无法正确更新。
VUE学习-优化组件的更多相关文章
- vue学习之组件
组件从注册方式分为全局组件和局部组件. 从功能类型又可以分为偏视图表现的(presentational)和偏逻辑的(动态生成dom),推荐在前者中使用模板,在后者中使用 JSX 或渲染函数动态生成组件 ...
- vue学习之四组件系统
vue.js既然是框架,那就不能只是简单的完成数据模板引擎的任务,它还提供了页面布局的功能.本文详细介绍使用vue.js进行页面布局的强大工具,vue.js组件系统. 一.Vue.js组件系统 每一个 ...
- Vue学习之--------组件的基本使用(非单文件组件)(代码实现)(2022/7/22)
文章目录 1.为啥要使用组件 2.基本使用 3.代码实例 4.测试效果 5.注意点 1.为啥要使用组件 好用啊.像堆积木一样 2.基本使用 Vue中使用组件的三大步骤: 一.定义组件(创建组件) 二. ...
- vue学习笔记——组件的优化
Vue 应用性能优化指南 1 给组件定义name,然后在同级目录新建index文件: import Count from './count.vue' export Count; 2 优化大数据的列表 ...
- Vue 学习笔记 — 组件初始化
简书 在vue中有3个概念很容易搞混,data,computed,props,特别是我们这些原后端开发人员. new Vue({ el: "#x", data: { id: 1 } ...
- Vue学习之组件切换及父子组件小结(八)
一.组件切换: 1.v-if与v-else方式: <!DOCTYPE html> <html lang="en"> <head> <met ...
- Vue学习笔记-组件通信-子传父(自定义事件)
props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中.我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成.什么时候需要自定义事件呢?当子组件需要向父组件传递 ...
- Vue学习之--------组件嵌套以及VueComponent的讲解(代码实现)(2022/7/23)
欢迎加入刚建立的社区:http://t.csdn.cn/Q52km 加入社区的好处: 1.专栏更加明确.便于学习 2.覆盖的知识点更多.便于发散学习 3.大家共同学习进步 3.不定时的发现金红包(不多 ...
- 40.VUE学习之--组件之间的数据传参父组件向子组件里传参,props的使用实例操作
父组件向子组件里传参,props的使用实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...
- 43.VUE学习之--组件之使用.sync修饰符与computed计算属性超简单的实现美团购物车原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- [随笔所想] CSDN认证博客专家申请通过随笔所想
本篇博客写于2020年5月13日晚,为了纪念CSDN博客专家申请通过. 2020年5月10日晚,也就是2020年的母亲节当晚提交了博客专家申请.在2020年5月13日上午,就知道博客专家申请通过啦!前 ...
- Vue + Element 自定义上传封面组件
前一段时间做项目,频繁使用到上传图片组件,而且只上传一个封面,于是想着自定义一个图片封面上传组件.先来看一下效果: 第一张图片是上传之前,第二张图片是上传 ...
- [Leetcode]设计循环队列
题目 代码 class MyCircularQueue { public: /** Initialize your data structure here. Set the size of the ...
- 把KMP算法嚼碎了喂给你吃!(C++)
相信不少人在学数据结构的时候都被KMP算法搞的迷迷糊糊的,原理看的似懂非懂,代码写不出来,或者写出来了也不知道为什么就可以这么写.本文力求尽可能通俗详细的讲解KMP算法,让你不再受到KMP算法的困扰. ...
- three.js一步一步来--如何画出构造辅助线
可以参考下面代码,粘贴上去就有了~ <template> <div class="container"> <h1>初步构造出辅助线</h1 ...
- 动力节点——day01
eclipse的快捷键: 1.ctrl+d删除一行 2.ctrl+1进行纠错 3.alt+/自动补全 4.单行注释ctrl+/ 5.多行注释ctrl+shift+/ 取消ctrl+shift+\ 6. ...
- dapr本地托管的服务调用体验与Java SDK的Spring Boot整合
1 简介 之前在文章<dapr入门与本地托管模式尝试>中介绍了dapr和本地托管,本文我们来介绍如果在代码中使用dapr的服务调用功能,并把它整合到Spring Boot中. Dapr服务 ...
- get请求与post请求的区别
大小限制 get请求一般通过url传输的数据量时比较少的,最多传3~5个参数,如果要传递多个参数,要在url地址中利用"&"符号拼接多个参数, 栗子:/test/demo. ...
- 《自定义工作流配置,springboot集成activiti,前端vue,完整版审批单据》
前言 activiti工作流引擎项目,企业erp.oa.hr.crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求. 一.项目形式 springboot+v ...
- 微信小程序【关于地址信息的接入以及自动选择当前位置】
在做收货地址的时候,通常会让用户填写或者打开地图选择收获地址,此时就需要用到微信提供的地址API,在使用地址API的时候需要注册对应的API,而且地址API会经常调整,需要关注官方公告,下面就是关于地 ...