vue基础
- vue是一个渐进式框架
vue (视图渲染)
components(路由机制)
vue-router(路由管理)
vuex (状态管理)
vuecli (构建工具)
- 库和框架
库如jQuery,是调用它的函数实现功能,
框架如vue, 是在指定的地方写代码,框架帮我们调用,是库的升级版
- 声明式(如forEach,不必关注里面实现) vs 命令式(for等具体语句)
vue响应式数据变化
Object.defineProperty用法,重新赋值会触发set方法
obj = {};
Object.defineProperty(obj, 'name', {
get(){
return value
},
set(val){
console.log("111111");
value = val
}
});
obj.name = "maomao";
console.log(obj.name);
Object.defineProperty实现数据劫持
vue中data都被代理到了vm实例上,例如vm.name
只要模版中用到的变量,必须先在vm上定义,用之前先声明.
知道vue中哪些修改会触发template更新
- 数组
数组类型的push等,是ok的(不能触发template重新渲染)
操作value类型是数组长度或者下标索引,是不ok的。arr.length--
- 对象
value是对象类型,重新给该key赋值为对象,是ok的
value是对象类型,给该对象新增属性,是不ok的,不符合使用前先定义原则
vue属性
vm.$el
获取dom
指的是template被渲染后的该id的html
vm.$options
components: {}
data: ƒ mergedInstanceDataFn()
directives: {}
el: "#app"
filters: {}
render: ƒ anonymous( )
staticRenderFns: []
vm.$nextTick(): vm上数据修改后,template渲染是异步的,因此可能获取到老的值
vm.arr = [4,5,6];
console.log(vm.$el.innerHTML); //template渲染的arr依旧是老的
获取dom
vm.$nextTick实现
vm.msg = "maotai";
vm.arr = [4, 5, 6];
vm.$nextTick(() => {console.log(vm.$el.innerHTML)});
vm.$set() 给value是对象类型的添加属性
data: {info: {name: "maotai"},}
vm.$set(vm.info,'age','22'); //vm提供的动态添加属性
前面说了,默认vm.info.age = 22方式添加属性是不会触发数据劫持的。
vue提供了vue.$set动态添加属性,也可以劫持
vm.$watch
监听数据变化,一旦数据变化,会触发函数执行
多次修改执行会只会触发1次,因为有缓存
vm.$watch('msg', function (newVal, oldVal) { console.log(newVal,oldVal); });
vm.msg = 'xxx';
vm.msg = '12';
template渲染{{}}取之表达式
取值
假如中间是对象,用空格隔开即可: {{ {name:1} }}
运算
{{1+1}}
{{'hello'+'world'}}
三元
{{flag?''ok':'no'}}
vue指令
v-once: 只触发template渲染一次
{{msg}}
vm.msg = '' //修改值,不会触发重新渲染
v-html
被转为innerHtml插入div
⚠️防止xss攻击,这样做有危险
v-if
是操作dom的增删
- 规则(中间不能有其他元素)
a
b
c
如果2个标签,可以使用div包裹, 如果不想多一层div标签,则使用template关键字
如果条件有2个标签,可以使用template关键字
hello
hello world
bb
eg:
name:
age:
v-if内置了属性绑定, 直接调用i就可以访问到属性了
:key绑定,也可以直接绑定属性, 但是 如果需要字符串拼接,则需要反引号标注
v-show
是操作css样式
不支持template关键字
v-for
vue2.5后v-for必须要带key属性: dom中不会被显示,如果其他属性名,则显示.
{{fruit}} - {{index}}
如果不想有div标签,可以使用template
想把这坨代码显示3次
- 存在的问题 包裹div优化
{{i}}
{{i}}
弊端: 被包了一层div
- 使用template标签解决
{{i}}
{{i}}
体现key的作用
vue在切换时候对比结构,如果标签一样,
如果没有key
切换dom时候, vue检测dom结构,如果相同的结构就会被复用,
input框被复用了,所以修改条件,切换失败,
如span一样,则直接修改innerText,但是input框一样,就不会被更新了
如果下面需要绑定key则可以使用拼接字符串方法,防止key冲突
name
age
⚠️{{i}} //不能使用这种方式来取,会报错,必须使用v-bind方式来取值
尽量不要使用index作为key,如果有唯一标示,尽量使用唯一标示
更改橘子苹果的位置,需要渲染2次
如果使用固定的,移动dom位置即可,节约性能
v-model
input双向绑定data
自己实现数据双向绑定
绑定数据到input
绑定方法到input,使得输入动作触发这件事
fn为什么不能放在data里, 因为this的问题,放data里this是window
input绑定事件时候要不要加括号
vue中input @click绑定可加也可以不加,情况不一样,加了必须要传个参数$event才能获取事件
data: {
msg: "hello",
fn: function (e) {
console.log(e); //e.target.value
}
}
如果绑定事件时加括号,必须给传一个参数$event
data: {
msg: "hello",
fn: function (e, name) {
console.log(e); //e.target.value
}
}
如果加了括号,无$event,则e会丢失.
data: {
msg: "hello",
fn: function (name) {
console.log(name);
}
}
v-model是:value+@input的语法糖
data: {
msg: "hello",
fn: function (e) {
this.msg=e.target.value
}
}
select
data: {
selectValue:"0",
menu:[
{name:"m1",id:1},
{name:"m2",id:2},
{name:"m3",id:3},
]
},
如果是multipule的select则要改成数组
data: {
selectValue:[],
menu:[
{name:"m1",id:1},
{name:"m2",id:2},
{name:"m3",id:3},
]
},
radio: 根据v-model分组
男:
女:
{{radioValue}}
checkbox单选,多选
修饰符
.number
.number.lazy
不加lazy是实时更新数据的
使得产生的类型是数字
如果不加产生的是字符串
.trim
删除首尾空白
键盘修饰符
.enter.ctrl.keyCode
@keyup.enter.esc
@keyup.13
@keyup.f1
事件修饰符
@事件.stop
stopPropagation,cancelBubble=true;
@事件.capture
xxx.addEventListener('click',fn,true)
@事件.prevent
preventDefault,returnValue=false
@事件.once
on('click') off('click')
@事件.self
e.srcElement&&e.target 判断事件源绑定事件
事件汇总(事件绑定)
@click
点击时候触发
@input
自己实现v-mode(:value+@input的语法糖)时候用过
@change
针对select下拉框改变
@keyup
@keyup
键盘抬起后触发
@keyup.13
输入后,按回车键
@keyup.esc
输入后,按esc触发