《vuejs快跑构建触手可及的高性能web应用》读书笔记
1.cdn:内容分发网络(CDN)是将资源托管到全世界各处的服务器上以实现快速分发。CDN版本对于开发和快速验证比较有用,但是将unpkg应用于生产环境前,需要检查它是否适合你。
2.假值包括false、undefined、null、‘’、NAN。
3.使用v-show两个场景:
频繁切换某些内容;
如果元素包含任何图片,那么仅使用css隐藏父节点可以使浏览器在图片显示之前就加载它,这意味着一旦v-show变成真值,图片就可以显示出来。如果是v-if指令,图片就直到要显示时才开始加载。
4.响应式如何实现:
vue修改了每个添加到data上的对象,当该对象发生变化时vue会收到通知,从而实现响应式。对象的每个属性会被替换为getter和setter方法,因此可以像正常对象一样使用它,但当你修改这个属性时,vue会知道它发生了变化。
5.为对象添加新的属性。
因为getter,settter方法是在vue实例初始化的时候添加的,只有已经存在的属性是响应式的,当为对象添加一个新的属性的时候,直接添加并不会使这个属性成为响应式的。
1 const vm = new Vue({
2 data: {
3 formData: {
4 username: 'someuser'
5 }
6 }
7 });
有几种方法解决这个问题:
(1)最简单的办法是在初始化时对象上定义这个属性,并把它的值设置为undefined。上例中的formData对象会变成下面这样:
1 formData: {
2 username: 'someuser',
3 name: undefined
4 }
(2) 也可以使用Object.assign()来创建一个新的对象然后覆盖原来对象,当需要一次性更新多个属性时,这是最有效的方法:
1 vm.formData = Object.assign({}, vm.formData, {
2 name: 'Some User'
3 });
(3)Vue还提供了Vue.set()方法,可以使用它将属性设置为响应式的:
1 Vue.set(vm.formData, 'name', 'Some User');
在组件内部也可以使用this.$set来调用这个方法。
6.设置数组的元素
不能直接使用索引来设置数组的元素。下面的做法是行不通的:
1 const vm = new Vue({
2 data: {
3 dogs: ['Rex', 'Rover', 'Henrietts', 'Alan']
4 }
5 });
6 vm.dogs[2] = 'Bob'
有两种方法可以解决这一问题。一种是使用.splice( )方法移除旧元素并添加新元素:
vm.dogs.splice(2, 1, 'Bob');
另一种是使用Vue.set( ):
Vue.set(vm.dogs, 2, 'Bob');
7.设置数组的长度
在javascript中,可以设置一个数组的长度,自动让空元素填充数组至该长度或者截掉数组的尾部。不过这个方法不能用于处理data对象中的数组,因为Vue不能检测到该操作对数组的任何更改。
8.到目前为止已经了解如何将数据输出到模板,以及vue的响应式能力如何做到让模板随着数据的跟新而更新。但这只是单向数据绑定。试着运行下面的代码,你会发现inputText会保持不变。输入框下面的文本也会保持不变。
1 <div id="app">
2 <input type="text" :value="inputText">
3 <p>inputText: {{inputText}}</p>
4 </div>
5 <script>
6 new Vue({
7 el: '#app',
8 data: {
9 inputText: 'initial value'
10 }
11 })
12 </script>
可以使用v-model指令,它作用于输入框元素,将输入框的值绑定到data对象的对应属性上,因此输入框不但会接收data上的初始值,而且当输入框内容更新时,data上的属性值会被更新。
1 <div id="app">
2 <input type="text" v-model="inputText">
3 <p>inputText: {{inputText}}</p>
4 </div>
5 <script>
6 new Vue({
7 el: '#app',
8 data: {
9 inputText: 'initial value'
10 }
11 })
12 </script>
9.method妙用
(1)将代表状态的数字-转换为可读的、描述真实状态的字符串
1 <div id="app">
2 <p>当前状态: {{statusFromId(status)}}</p>
3 </div>
4 <script>
5 new Vue({
6 el: '#app',
7 data: {
8 status: 2
9 },
10 methods: {
11 statusFromId(id) {
12 const status = ({
13 0: '睡觉',,
14 1: '吃饭',,
15 2: '学习vue'
16 })[id];
17 return status || '未知状态:' +id;
18 }
19 }
20 })
21 </script>
(2)过滤for循环中的数据,避免v-for和v-if混用
1 <div id="app">
2 <ul>
3 <li v-for="number in filterPositive(numbers)">{{number}}</li>
4 </ul>
5 </div>
6 <script>
7 new Vue({
8 el: '#app',
9 data: {
10 numbers: [-5, 0, 2, -1, 1, 0.5]
11 },
12 methods: {
13 filterPositive(numbers) {
14 return numbers.filter((number)=> number > 0); // [2, 1, 0.5]
15 }
16 }
17 })
18 </script>
10. 在vue2.0中,mounted钩子触发时并不保证元素已经被添加到DOM上。如果想保证元素已经被添加,可以调用Vue,nextTick()方法,也可以通过this.$nextTick()调用,并传入一个回调函数,在回调函数中添加需要在元素被添加到DOM之后运行的代码。
1 <div id="app">
2 <p>Hello world</p>
3 </div>
4 <script>
5 new Vue({
6 el: '#app',
7 mounted() {
8 // 元素可能还没添加到DOM上
9 this.$nextTick(()=>{
10 // 确定元素已经被添加到DOM上了
11 })
12 }
13 })
14 </script>
11. 使用自定义指令directive, 来实现一个闪烁效果:
1 <body>
2 <div id="app">
3 <p v-blick>我会闪烁</p>
4 </div>
5 </body>
6 <script>
7 new Vue({
8 el: '#app',
9 data: {},
10 directives: {
11 'blick': {
12 bind(el) {
13 let isVisible = true;
14 setInterval(() => {
15 isVisible = !isVisible;
16 el.style.visibility = isVisible ? 'visible' : 'hidden';
17 }, 1000)
18 }
19 }
20 }
21 })
22 </script>
12. prop使用和.sync修饰符
如果prop的值不是字符串,那么就必须使用v-bind指令。
<display-number :number = "10"></display-number>
数据通过prop从父级组件传递给子组件中,当父级组件中的数据更新时,传递给子组件的prop也会更新。但是你不可以在子组件中修改prop。这就是所谓的单向下行绑定,防止子组件在无意中改变父级组件的状态。
然而,双向数据绑定在某种情况下可能很有用。如果想要使用双向绑定,可以使用一个修饰符来实现 : .sync修饰符。它只是一个语法糖:
<count-from-number :number.sync="numberToDisplay" />
13.自定义输入组件与v-model
与.sync修饰符相似,可以在组件上使用v-model指令来创建自定义输入组件。这里同样也是一个语法糖。请看示例:
<input-username v-model="username" />
上面的代码等效于:
<input-username :value="username" @input="value => username=value" />
14.响应路由变化
当/user/1234 与/user/5678 相互切换时,其中相同的组件会被重用,于是第一章所涉及到的生命周期钩子,诸如mounted,都不会被调用。不过,你可以使用beforeRouteUpdate导航守卫在URL动态部分变化时运行一些代码。
我们创建一个PageUser组件,它在挂载的时候会调用一次API,并且在路由变化时还会再调用一次:
<template>
<div v-if="state === 'loading'">
loading user...
</div>
<div>
<h1>user: {{userInfo.name}}</h1>
</div>
</template> <script>
export default {
data: ()=> ({
state: 'loading',
userInfo: undefined
}),
mounted() {
this.init();
},
beforeRouteUpdate(to, from, next) {
this.state = 'loading';
this.init();
next();
},
method: {
init() {
fetch(`/api/user/${this.$route.params.userId}`)
.then((res)=> res.json())
.then((data)=> {
this.userInfo = data;
});}
}
}
}
</script>
15.路由参数作为组件属性传入
除了在组件中使用this.$route.params,还可以让vue-router将params作为路由组件的props传入。以如下组件为例:
const PageUser = {
template: '<p>ID: {{ $route.params.userId }}</p>'
};
const router = new VueRouter({
routes: [{
path: '/user/:userId ',
component: PageUser
}]
});
当导航至/user/1234的时候,‘ID:1234’就会被输出到页面上。
要想让vue-router改为将userId作为组件的一个属性传入,你可以在路由中指定props:true
const PageUser = {
props: ['userId],
template: '<p>user ID: {{ userId }}</p>'
};
const router = new VueRouter({
routes: [
path: '/user/:userId',
component: PageUser,
props: true
]
});
使用props代替$route.$params的好处是:组件与vue-router不再紧密耦合。设想一下,将来你想在一个页面上展示多个用户,使用第一个例子的代码就会很棘手,但使用第二个例子的代码就会变得很简单,因为只要在另一个页面调用该组件就好了,就像它是一个与路由无关的通用组件那样。
16.vue-router中的tag属性
<router-link to="/user/1234" tag="li">go to user 1234</router-link>
这会在页面上渲染出如下结果:<li> go to user 1234 </li>
由此,在它上面悬停也就不会给你带来任何关于这个链接的消息,也不能通过鼠标右键在新窗口打开这个链接;
为了解决这个问题,可以在<router-link>元素里面加上锚点标签:
<router-link to="/user/1234" tag="li"><a>go to user 1234</a></router-link>
现在,渲染出来的html就是下面这样:
<li><a href="/user/1234" >go to user 1234</a></li>
如果想给<router-link>添加一个事件处理器,可以使用.native修饰符来监听:
<router-link to="/blog" @click.native="handleClick">blog</router-link>
17.导航守卫
当你维护的是一个拥有大量路由的网站,于是会发现另一个很有用的特性,它就是路由元信息。你可以在路由上添加一个meta属性,并在守卫那里重新获取它。例如,在account路由上设置一个requiresAuth属性,然后在守卫中查看该属性:
const router = new VueRouter({
routes: [{
path: '/account',
component: PageAccount,
meta: {
requiresAuth: true
}
}]
}); router.beforeEach((to, from, next)=> {
if (to.meta.requiresAuth) {
next('/login');
} else {
next();
}
})
当使用嵌套路由时,to.meta指向的是子路由的元信息,而非其父路由。也就是说,如果你在/account上添加了meta对象,而用户访问的是/account/email,则所获得的meta对象是关于该子路由的,而非父路由。可以通过遍历to,matched的方式来曲线救国,
它同样也包含了父路由的元信息:
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some((record) => {
return record.meta.requiresAuth;
})
if (to.meta.requiresAuth) {
next('/login');
} else {
next();
}
})
18.afterEach,可用于设置页面标题
const router = new VueRouter({
routes: [{
path: '/blog',
components: PageBlog,
meta: {
title: 'welcome to my blog'
}
}]
});
router.afterEach((to) => {
document.title = to.meta.title;
});
19.使用vuex和websocket,实现用户在页面上所拥有的的消息数量
组件代码:
const NotificationCount = {
template: `<p>messages: {{messageCount}}</p>`,
computed: {
messageCount() {
return this.$store.state.messages.length;
}
},
mounted() {
this.$store.dispatch('getMessages');
}
};
然后下面使我们的vuex store(store/index.js)
let ws;
export default new Vuex.Store({
state: {
messages: []
},
mutations: {
setMessages (state, messages) {
state.messages = messages;
}
},
actions: {
getMessages ({ commit }) {
if (ws) { return ; }
ws = new WebSocket('/api/message');
ws.addEventListener('message', (e)=> {
const data = JSON.parse(e.data);
commit('setMessages ', data.message);
});
}
}
});
阮一峰webSocket 教程: http://www.ruanyifeng.com/blog/2017/05/websocket.html?utm_source=tuicool&utm_medium=referral
实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。
《vuejs快跑构建触手可及的高性能web应用》读书笔记的更多相关文章
- csapp读书笔记-并发编程
这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...
- CSAPP 读书笔记 - 2.31练习题
根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1) 属于第一种情况 sum = x ...
- CSAPP读书笔记--第八章 异常控制流
第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...
- CSAPP 并发编程读书笔记
CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...
- 读书笔记汇总 - SQL必知必会(第4版)
本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...
- 读书笔记--SQL必知必会18--视图
读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...
- 《C#本质论》读书笔记(18)多线程处理
.NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...
- C#温故知新:《C#图解教程》读书笔记系列
一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...
- C#刨根究底:《你必须知道的.NET》读书笔记系列
一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...
- Web高级征程:《大型网站技术架构》读书笔记系列
一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...
随机推荐
- 使用Netty实现文件传输的HTTP服务器和客户端
现在我们来用netty实现文件传输的HTTP服务器和客户端 pom依赖文件: <?xml version="1.0" encoding="UTF-8"?& ...
- 使用 PyTorch FSDP 微调 Llama 2 70B
引言 通过本文,你将了解如何使用 PyTorch FSDP 及相关最佳实践微调 Llama 2 70B.在此过程中,我们主要会用到 Hugging Face Transformers.Accelera ...
- [USACO2007NOVG] Sunscreen
题目描述 To avoid unsightly burns while tanning, each of the$ C (1 ≤ C ≤ 2500) $cows must cover her hide ...
- Java操作Word修订功能:启用、接受、拒绝、获取修订
Word的修订功能是一种在文档中进行编辑和审阅的功能.它允许多个用户对同一文档进行修改并跟踪这些修改,以便进行审查和接受或拒绝修改.修订功能通常用于团队合作.专业编辑和文件审查等场景. 本文将从以下几 ...
- 华企盾科技:智能AI自动化研判分析服务系统概述
由中企网安全资子公司北京华企盾科技有限责任公司开发的<智能AI自动化研判分析服务系统>,获得国家版权局颁发的计算机软件著作权登记证书. 智能AI自动化研判分析服务系统是基于人工智能.大数据 ...
- 整一个工具类【根据URL地址获取file文件对象】
整一个工具类[根据URL地址获取file文件对象] 直接将网络url文件转换为file对象 import java.io.*; import java.net.URL; public class Im ...
- 探索 Linux Namespace:Docker 隔离的神奇背后
在 深入理解 Docker 核心原理:Namespace.Cgroups 和 Rootfs 一文中我们分析了 Docker 是由三大核心技术实现的. 今天就一起分析 Docker 三大核心技术之一的 ...
- GeoServer发布地图服务(WMS、WFS)
目录 1. 概述 2. 矢量数据源 3. 栅格数据源 1. 概述 我们知道将GIS数据大致分成矢量数据和栅格数据(地形和三维模型都是兼具矢量和栅格数据的特性).但是如果用来Web环境中,那么使用图片这 ...
- JavaFx之触发激发鼠标事件(二十三)
JavaFx之触发激发鼠标事件(二十三) 有时候,我们不能直接触发/激发某个按钮的点击事件,因为发起方可能是子线程.使用屏幕点击又不优雅,javafx已经提供了事件的激发,即使在子线程中也能激发某个按 ...
- Ubuntu20.04 安装shutter
1 sudo add-apt-repository ppa:linuxuprising/shutter 2 3 sudo apt install shutter 4 5 卸载 6 sudo apt-g ...