Vue 学习笔记
当需要在数据变化时执行异步或开销较大的操作时,使用watch自定义侦听器
小点:
-
array.splice(index, step) 从index开始 删除包括自己在内的后step位, 返回删除的内容,会改变原有数组
array.splice(index, step, val) 从index, 以val替换index后step位元素
array.slice(from, to) 截取字符串 to为空表示截取到最后
a.contact(b) 连接数组
obj.charAt(index) 返回index所在字符串
obj.charCodeAt(index) 返回index所在字符串的unicode编码 -
config.silent : 不会打印错误日志
/* istanbul ignore next */ 代码覆盖率检测的时候忽略该段代码 -
arrayObject.shift() 删除数组第一个元素并返回值
arrayObject.unshift(newelement1,newelement2,....,newelementX) 向数组开头添加一个或多个元素, 返回新数组长度 -
Object.isFrozen() 判断是一个对象是否是可拓展的, (一个对象的冻结是指它不可拓展,所有属性都是不可配置的, 且所有数据属性都是不可写的, 即没有getter/setter组件的访问器))
-
{} 和 Object.create(null); 的区别 {} 等同于 new Object()
Object.create(null) 创建一个没有继承任何原型的对象, 没有任何属性方法, 不用考虑会和原型链上的属性重名问题,可以重写所有属性和方法, 是一种函数式编程
function create(o){
function F(){
F.prototype = o;
return new F();
}
}
数组索引:
["s", "b", "e"].indexOf("e") !== -1
call()和apply()
参考:https://blog.csdn.net/ganyingxie123456/article/details/70855586
1,每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
2,作用一样, 改变this的指向
3, 接收参数方式不同
apply([thisObj [,argArray..]]); 参数2必须是有小数组或者arguments对象
call([thisObj [,arg1 [,arg2 ..]]]); 传递给函数的参数必须列举出来
```js
function add(c,d){
return this.a + this.b + c + d;
}
var s = {a:1, b:2};
console.log(add.call(s,3,4)); // 1+2+3+4 = 10
console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14
```
property属性
参考:https://blog.csdn.net/yh1061632045/article/details/81518138
js 中的可枚举属性(enumerable) propertylsEnumerable()
obj.propertyIsEnumerable(prop) 判断属性是否可枚举 > 返回 true or false
不可枚举属性不会被遍历
for ... in
可枚举属性对以下操作的影响
Object.keys(), JSON.stringify() 不会列举出不可枚举属性, 也不会列举出原型链上的所有属性
Object.defineProperty(obj, prop, descriptor);
//直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象
//configurable,wriable,enumerable默认为false, value,get,set 默认为undefined
var obj = new Object();
Object.defineProperty(obj, 'name', {
configurable: false, // configurable属性为false, 如果writable为false 修改所有内部属性值会抛出错误, 如果writable为true 则只有writable和value的值可修改,修改其他则会报错
writable: true,
enumerable: true,
value: '张三'
});
Object.defineProperties(obj, props);
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: '张三',
configurable: false,
writable: true,
enumerable: true
},
age: {
value: 18,
configurable: true
}
});
Object.getOwnPropertyDescriptor(obj, prop); //返回指定对象上一个自有属性对应的属性描述符
var person = {
name: '张三',
age: 18
}
var desc = Object.getOwnPropertyDescriptor(person, 'name');
console.log(desc) 结果如下
// {
// configurable: true,
// enumerable: true,
// writable: true,
// value: "张三"
// }
问题1--正则:
[^\w.$] 相当于 \W.*
\B 非单词边界字符左右两边没有空白字符
\b 单词边界左右两边有空白
(?=) 作为匹配校验,但不会出现在匹配结果字符串里
(?😃 作为匹配校验,会出现在匹配结构字符串中,但不作为子匹配, 可以提高正则性能
eg:
```js
var data = 'windows 98 is ok';
data.match(/windows (?=\d+)/); // ["windows "]
data.match(/windows (?:\d+)/); // ["windows 98"]
data.match(/windows (\d+)/); // ["windows 98", "98"]
/(?:^|[-_])(\w)/g //匹配开头或者-_ 后的一个字符, 所以 $1就是(\w)
```
检测对象类型
typeof 无法准确判断
Object.prototype.toString.call(obj) 可以区分各种类型
```js
"jerry".toString() >> jerry
Object.prototype.toString.call("jerry") >> [object String]
```
instanceof 自定义类型使用instanceof
问题2:
参考:https://blog.csdn.net/fakerac/article/details/52819009
(函数名) :
var generateComponentTrace = (noop);//命名函数表达式 一般用在递归上, var res = function a(){}() 必须有一个变量接收返回值, (function a(){})() 立即执行函数, 不必须使用变量接收
var hasSymbol =
typeof Symbol !== 'undefined' && isNative(Symbol) &&
typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
参考:http://www.w3school.com.cn/jsref/jsref_replace.asp
str.replace(regexp/substr, replacement/func);
参数1: 子字符串, 或者替换的正则对象
如果replacement是1 ---- & : 与regexp相匹配的字串
' : 位于匹配子串右侧的文本
$$ : 直接量符号
参数2:替换后的字符串 / 一个函数(每个匹配都调用该函数,返回字符串作为替换文本使用)
注意事项
Vue 不能检测以下变动的数组:
1.使用索引直接设置值的时候 vm.items[indexOfItem] = newValue
2.当修改数组的长度时,vm.items.length = newLength
var vm = new Vue({
data:{
items:[1,2,3,4]
}
});
vm.items[1] = 'x';//不是响应性的
vm.items.length = 2;//不是响应性的
解决方法
- 对于1:可以用vm.$set(vm.items, indexOfItem, newValue);
vm.items.splice(indexOfItem, 1, newValue)
- 对于2:vm.items.splice(newLength)
注意事项:#
-
在组件中使用v-for时,key是必须的
-
使用事件修饰符时,顺序很重要
eg: v-on:click.prevent.self 阻止所有点击事件
v-on:clcik.self.prevent 只阻止对元素自身的点击 -
在选择框中使用v-model, 如果v-model表达式的初始值不能匹配任何选项, select 元素将被渲染为 "未选中"状态。在IOS中, 会使用户无法选择第一个选项 推荐提供一个值为空的禁用选项
-
<!-- #选项框的选项 --> <select v-model="selected"> <!-- 内联对象字面量 --> <option v-bind:value="{number: 123}">123</option> </select>
typeof vm.selected // > object vm.selected.number => 123
-
组件的data必须是一个函数, 因为组件是可服用的, 每个组件实例都维护一份被返回对象的独立拷贝。才不会造成数据安全问题。
-
每个组件必须只有一个根元素, 即每个组件只能有一个最大的标签,在最外层没有兄弟元素。
-
<input v-model="searchText"> <!-- 等价于 --> <input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
-
解析 DOM 模板时的注意事项:is用法
实现效果与 -
单向数据流
-
跟组件和 prop 不同,事件名不存在任何自动化的大小写转换, 事件名需要完全匹配监听这个事件所用的名称,自定义事件最好使用小写命名或者始终使用kebab-case命名 因为HTML是大小写不敏感的,所有大写会转成小写, 导致事件不能被监听到。
-
插槽 slot
元素作为承载分发内容的出口, 相当于jinjia2模板引擎的 占位模板 - 普通slot
- 具名slot
- 普通slot
-
父组件模板的所有内容都会在父级作用域内编译; 子组件模板的所有内容都会在子组件作用于内编译
实现数据mvvm双向绑定
- 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,有变动可拿到最新值并通知订阅者
- 实现一个指定解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定响应的更新函数
- 实现一个Watcher, 作为Obsever和Compile的桥梁,能够订阅并受到每个属性变动的通知,执行指令绑定的响应回调函数,从而更新视图
- mvvm入口函数, 整合以上三者
Vue整个生命周期中, 有4类地方会实例化Watcher
- Vue实例化的过程中有watch选项
- Vue实例化的过程中有computed计算属性选项
- Vue原型上有挂载watch,可以直接通过实例调用this.$watch方法
- Vue生成了render函数,更新视图时
vm._render 调用vm.$options.render 返回生成的虚拟节点(vnode)
vm._update 将虚拟节点渲染称真实的DOM
渲染观函数的观察者并不是同步更新变化的,而是将变化放到一个异步更新队列中
update () {
if (this.computed) {
//
} else if (this.sync) {
this.run();
} else {
queueWatcher(this); //这个队列会在调用栈被清空之后按照一定的顺序执行,将观察者放到一个队列中等待所有突变完成之后统一执行更新
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构