渐进式框架
国人开发、易学、易上手
Vue 的核心库只关注视图层
声明式渲染
组件系统
比较常见的三种开发模式:MVC、MVP、MVVM
MVVM模式
M:(model)数据对象,数据层
V:(view)前端展示页面,显示层
VM:(ViewModel)vue对象,逻辑层
所谓的mvvm模式,通过vm层可以将v层和m层的数据进行双向绑定
设计模式:开发模式、发布订阅模式、工厂模式、单例模式、代理模式、观察者模式、生产消费模式、原型模式
js和jquery都需要先获取到某个节点,再对这个节点进行操作,性能不好
区别 | 传统DOM | Vue |
数据驱动 | 手动更新DOM元素以反映数据的变化。需要编写大量的代码。 | 使用数据驱动的方式,只需要关注数据的变化,Vue.js会自动更新DOM以反映这些变化。大大减少手动操作DOM的代码量。 |
响应式 | 要实现数据的响应式,需手动编写代码来监听数据变化,并更新相关的DOM元素。 | 通过其响应式系统可以自动追踪数据的变化,并且在数据变化时更新相关的DOM元素,从而使得数据和DOM保持同步。 |
模板 | 通常需要手动拼接HTML字符串来动态生成DOM元素,代码可读性较差。 | 使用基于HTML的模板语法,使得编写动态内容更加直观和易于理解。 |
组件化 | 要实现组件化通常需要手动管理DOM元素的创建、销毁和更新。 | 提供了组件化的能力,可以将页面拆分成多个独立组件,每个组件都有自己的模板、逻辑和样式,使得代码更加模块化和可维护。 |
vue2. *版本,数据双向绑定是通过数据劫持Object.defineProperty()结合发布者-订阅者模式的方式来实现的,每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
注意:v-html
容易引起xss攻击,尽量少用或不用。
双向绑定指令
v-model
本质上不过是语法糖 (v-bind
和v-on
的语法糖结构)用在input、select等表单里
性别: 男//选男会把value值传给sex 女 { {sex==0?'女':'男'}}
可以解决vue屏幕闪白的问题,网络不好,网页先显示 { { message }},vue加载完毕,显示 hello vue
v-once只能渲染一次,值不能修改
vue中当遇到变量,boolean类型或者number类型时,需要使用绑定属性
作用:绑定事件监听器(事件绑定)
v-on
简写 @1.绑定事件常规写法
2.事件绑定简写 @
3.事件绑定函数,直接写函数名
4.事件绑定函数,传递参数
5.ev的使用
如果没有小括号,函数可以直接写 ev属性,如果写了小括号,函数不能直接写 ev属性 ,值是undefined,如果写了小括号,需要在小括号中添加 $event属性
不及格
一般
优秀
大神
1.循环显示数组内容
- { {item}}
2.可以显示下标
- 下标{ {index}} : { {item}}
3. 可以使用 of
- 下标{ {index}} : { {item}}
4. 循环对象
{ {value}}--{ {key}}--{ {index}}
在vue2中,v-for的优先级高于v-if
在vue3中,v-if的优先级高于v-for
在vue中,永远不要把v-if和v-for同时用在同一个元素上,会带来性能方面的浪费(每次渲染都会先循环再进行条件判断);想要避免出现这种情况,可在外层嵌套template(页面渲染不生成dom节点),在这一层进行v-if判断,然后在内部进行v-for循环
提高性能,不影响显示效果( 如果没有id,可以考虑使用索引替代 )
因为key 可以唯一的确定一行数据,在对这行数据进行修改、删除、新增的时候,不需要在轮询查找这条数据
实际项目中循环时,不写key会报警告
春华秋月何时了
往事知多少
v-if 直接改变 dom节点 ,性能差一些
v-show 改变的样式,性能好,更改的次数较多,频繁切换状态,建议使用 v-show
//class 使用 v-bind绑定时可以使用对象的方式
春花秋月何时了****
往事知
往事知多少
****class的三目运算符的使用
class的三目运算符的使用
//style 使用 v-bind绑定时可以使用对象的方式
春花秋月何时了****
往事知多少
往事知多少
****style的三目运算符的使用
style的三目运算符的使用
事件修饰符:
stop
阻止冒泡
prevent
阻止默认事件
capture
事件捕获模式
self
点到自己才运行
once
只运行一次
passive
滚动事件的默认行为会立即触发
v-model修饰符:
lazy
光标从input框移出才触发更新
number
变为 数值类型
trim
去掉空格
按键修饰符:
enter
.space
.delete
深入响应式原理的表现:
数组: 利用索引直接设置一个数组项时、修改数组的长度时,是没有响应式效果的
对象: 新增、删除对象属性时没有双向绑定效果
解决办法:
$set
二次封装的数组/对象方法
强制更新$forceUpdate
//数组:
methods: {add() {
this.hero[3] = "囧囧侠";
// 1. $set
this.$set(this.hero, 3, "囧囧侠");
// 2.vue二次封装的数组方法
// 可以使用 vue二次封装的变更方法:push() pop() shift() unshift() splice() sort() reverse()
// 可以使用 vue二次封装的非变更方法: filter()、concat() 和 slice()
this.hero.push('囧囧侠');
// 3.强制更新 $forceUpdate
this.hero[3] = "囧囧侠";
this.$forceUpdate();},
del() {this.hero.length = 2;},
edit() {this.hero[2] = "大神";}
}
//对象:
methods: {add() {
// 新增对象属性时没有双向绑定效果
this.hero.sex = "男";
// 1. $set
this.$set(this.hero, 'sex', '男');
// 2. 二次封装的对象方法
this.hero = Object.assign({}, this.hero, { 'sex': "男" });
// 3. 强制更新
this.hero.sex = "男";
this.$forceUpdate();},
del() {delete this.hero.age;},
edit() {//修改有双向绑定的效果
this.hero.name = "小花";}
}
全局自定义指令:
//全局自定义指令
Vue.directive('base', {
inserted(el) {//inserted
console.log(el);//dom
}
})
局部自定义指令, 定义在 new Vue的对象中的:
var app = new Vue({
el: "#app",
data: { },
//局部的自定义指令
directives: {
//所有的自定义指令都放在这里
mycolor(el, binding) {
//设置了该dom节点里面的内容的颜色
console.log(el, binding);
el.style.color = binding.value;}}
})
应用:搜索结果加粗标红
// 在Vue实例化之前定义自定义指令 Vue.directive('highlight', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el, binding) { // 获取传入的搜索关键词 let keyword = binding.value; // 使用正则表达式替换匹配的文本,加上标签实现加粗标红 //new RegExp(keyword, 'gi')创建一个全局、不区分大小写的正则表达式对象,用于搜索指定关键词 el.innerHTML = el.innerHTML.replace(new RegExp(keyword, 'gi'), '$&'); } });
定义了一个名为
highlight
的自定义指令,其中包含一个inserted
钩子函数。当元素被插入到DOM中时,这个钩子函数会被调用。获取了传入的搜索关键词,然后使用正则表达式替换匹配的文本,将其用标签包裹起来并添加样式,实现了加粗标红的效果。
在模板中使用这个自定义指令可以这样做:
这是包含关键词的搜索结果
使用方式:与使用data中的数据是一模一样的,依赖项可以是多个,返回一个结果
注意:计算属性的名字和前面的data中的数据、methods中的方法都不能重名
优点:计算属性会缓存计算的结果,当结果不发生变化时,不管调用几次,计算属性对应的函数都只执行一次
计算属性和普通函数的区别:
计算属性有缓存,当结果不变时,计算属性不管调用多少次都只执行一次;函数是调用几次就执行几次
计算属性不用手动调用,它对应的函数,直接写计算属性名就可以了,函数调用必须加 小括号
想要修改计算属性的值,需要使用 get、 set
computed: {
fullN: {
get() {
return this.firstN + '-' + this.lastN;},
set(newV) {
console.log('set触发了', newV);
var arr = newV.split('-');
this.firstN = arr[0];
this.lastN = arr[1];}}
}
计算属性computed和监听器 watch的区别:
var app = new Vue({
el: "#app",
data: {
firstN: "yin",
lastN: "laura",
fullN: "yin-laura"
},
watch: {//监听器、侦听器
firstN(newV, oldV) {
console.log(newV, oldV);
this.fullN = newV + "-" + this.lastN;
},
lastN(newV, oldV) {
console.log(newV, oldV);
this.fullN = this.firstN + "-" + newV;
},
},
watch深度监听的写法:
watch: {
userInfo: {
handler(newV) {
console.log(newV);
this.userInfo.fullN = newV.firstN + '.' + newV.lastN;},
deep: true //深度监听
}}
全局过滤器
Vue.filter('setUpper', function (value) {
console.log(value);
return value.toUpperCase();
})
局部过滤器
var app = new Vue({
el: "#app",
// 局部过滤器
filters: {
sexType(value) {
return value ? "男" : "女"},
findStr(value, num) {
console.log(num);
return value.substring(num);}}
})
过滤器可以传递参数 ,过滤器调用时使用 <