Vue.config.productionTip = false ;
const vm = new Vue({
el:'#root',
data:{
name:'pshdhx',
}
})
// vm.name == vm._data.name 所以,vm.data是vm._data.name的代理
只有放在data里边的属性,才会做事件代理。通过set和get方法绑定属性值。
<button v-on:click="showInfo($event,'888')">按钮点击事件</button>
<button @click="showInfo($event,'888')">按钮点击事件2</button>
methods:{
showInfo(event,str){
console.log('event',event); //使用$event占位,来保持原生的event
console.log(event.target.innerText)
console.log('str',str);
},
}
<a href="https://www.baidu.com" @click.prevent="alertInfo">点击阻止跳转</a>
//e.preventDefault(); == @click.prevent //阻止跳转
div的click和button中的click事件是同一个,点击按钮之后,div的又触发了一次。
在最内层的添加
// e.stopPropagation() == @click.stop
@click.once
div1里边有div2,点击方法都一样。如果什么都不加,则先触发div2的方法,再触发div1的点击方法。
@click.capture 经过div1的捕获之后,则可以先触发div1的方法,在触发div2的方法。
只有e.target=当前操作的元素时,才会触发事件。
@click.self,div上的@click设置了这个,其就可以不受子元素的冒泡影响了。
@scroll,给滚动条添加的事件。【到末尾了,拖动就不能触发了】
@wheel,鼠标的滚轮滚动一下添加的事件。【到末尾了,滚动还能触发】
wheel滚轮往下滚动的时候,卡住了,执行完了之后,再调整滚动条。
如果加上@click.passive之后,则滚动条立即执行。
@keydown
@keyup
if(e.keyCode != 13) return ;
console.log('@',e.target.value)
@keyup.enter="showInfo" 就不用判断是否是回车了
这个叫做别名。enter delte esc space tab up down left right
如果是由多个单词组成的键盘帽名称,比如说CapsLock,可以写成@keyup.caps-lock=""
tab键,如果是抬起的话,焦点跑了。所以需要keydown
Vue.config.keyCodes.huiche = 13 自己定义别名
@click.prevent.stop
既能阻止冒泡事件,又能阻止默认事件。
@keyup.ctrl.y= 是按下ctrl+y的时候,生效。
Vue中的数值发生了改变,一定会重新解析模板的。
computed与Methods的优势,就是其有缓存,当数据发生改变时,刷新缓存。而method的返回字符串,每次渲染,都会调用methods的方法。
computed:{
fullName:{
get(){
console.log('调用了get的方法');
return this.name +'!!';
},
set(val){
this.name = val;
},
},
//简写,只需要get的时候
simple(){
return this.name;
}
}
@click="isHot = !isHot" 可以写一些简单的语句。
watch:{
address:{
handler(newVal,oldVal){
immediate:true;
console.log('newVal',newVal);
console.log('oldVal',oldVal);
}
}
}
data:{
numbers:{
a:'1',
b:'2'
}
},
'numbers.a':{
handler(){
console.log('a的值被改变了')
}
},
numbers:{
deep:true,
handler(newVal, oldVal) {
console.log('深度监视',this.numbers);
}
}
//简写
'numbers.b'(newValue,oldValue){
console.log('简写',newValue,oldValue);
}
不变的样式正常写,变化的样式动态写
.happy{
width:'',
background:''
}
.pshdhx1{
//.....
}
<div class="basic" :class="changableClass"></div>
data:{
changableClass:'happy',
arr:['pshdhx1','pshdhx2','pshdhx3']
}
changableClass 是一个属性值,属性值对应样式的class值,用作变化使用,最后汇总的时候,页面的dom元素的class=“basic happy”
:class也可以写成数组
:class="arr"
arr:['pshdhx1','pshdhx2','pshdhx3']
arr.shift()移除数组中的第一个元素
3、绑定class的对象写法
:class="classObj"
classObj:{
? pshdhx1:false,
? pshdhx2:false,
}
:class="classObj"
classObj:{
pshdhx1:false,
pshdhx2:false,
}
那么他的样式就是只有basic,如果改为了true,则样式全部都有了。
:style="{fontSize:fSize+'px'}"
data:{
? fSize:40
}
可以当作一个对象 var obj = {fontSize:fSize+'px'};
1、v-if v-else-if 渲染之后,整个DOM都没有了 。
如果执行了v-if之后,v-else-if就不会被解析了。即使下边的条件判断也成立,也不执行了。
v-else后边跟的条件也白跟,跟随着上边的条件走,上边的条件不成立,就执行v-else了。
条件判断,之间的dom元素不能被打断,如果打断了,下边的条件判断就不能生效了。
2、v-show="true/false" ,底层的dom是,display:none;
我们随意包裹div的时候,可能会对dom结构造成一定破坏,影响其余元素。这时我们可以使用<template>来代替div。
想要循环谁,就在谁的上边加上v-for
遍历数组
<ul>
<li v-for="(p,index) in persons">
{{p.name}}-{{p.age}}
</li>
</ul>
加上key :key="p.id" 或者是:key="index"
第二个参数是index
<ul>
<li v-for="(value,key) in car">
{{value}}-{{key}}
</li>
</ul>
data:{
keyWord:'',
persons:[xxxxxxxxxxxxxxxx],
filterPersons:[],
},
watch:{
keyWord:{
immediate:true,
handler(val){
this.filterPersons = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1;
});
}
}
}
加入immediate,一上来就直接进行了一遍过滤。
计算属性实现过滤
computed:{
filterPersons(){
return this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1;
});
}
}
@click="sortType = '0' "
data:{
sortType:'0',//0默认原顺序 1降序 2升序
}
computed:{
filterPersons(){
let arr = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1;
});
if(this.sortType){
arr.sort((p)=>{
return this.sortType == '1' ? p2.age-p1.age :p1.age - p2.age;
})
}
return arr;
}
}
this.persons[0]={id:'001',name:'马老师',age:'58'};//没有监测到
this.persons[0].name="马老师"; //vue可以监测到数据的改变
var data = {
name:'pshdhx'
}
var obs = new Observer(data)
console.log('obs',obs);
let vm = {};
vm._data = data = obj;
function Observer(obj){
//汇总对象中的所有属性,形成一个数组
const keys = Object.keys(obj);
//遍历
keys.forEach((k)=>{
Object.defineProperty(this,k,{
get(){
return obj[k];
},
set(val){
//name的值被改了
console.log(`${k}`被改了,我要去解析模板,生成虚拟DOM)
obj[k] = val;
}
})
})
}
直接操作vm._data.student.sex='男',因其并没有set、get方法,所以不能生成数据响应。
可以使用Vue.set(vm._data.student,'sex','男');
vm.$set(vm._data.student,'sex','女');
局限:
1、Vue.set只能给data里边的一个对象追加属性,但是不能在data里边直接新增一个属性。
2、Vue不能操作里边的数组的,数组里边的元素没有get、set的方法,只能靠Push pop shift unshift splice reverse sort等方法来改变数组,直接vm._data.student.hobby[0]='学习' 是不行的。
也可以Vue.set(vm._data.student.hobby,1,'打台球');
总结:
对数组整个对象进行赋值时,一定要注意,直接赋值对象vue不会添加到响应式。
label的for属性
<label for="demo">账号</label>
<input id="demo" type="input"/>
radio的value属性,要配置上,才能被v-model绑定
<input type="radio" name="sex" v-model="sex" value="female"/>
修饰年龄
v-model.number="userInfo.age"
v-model.lazy="textAreaOther" 不需要Vue实时收集。
v-model.trim=""
bootCDN库。
引入第三方的js库。
BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务
现在是{{time | timeFormatter}}
filters:{
timeFormatter(){
return xxxx;
}
}
Vue.filter('mySlice',function(){
return xxx;
})
1、v-text仅仅渲染字符串
2、v-html可以渲染字符串中含有的html,容易造成xss攻击。
3、html从上往下解析,如果引入的js经过5秒之后,才能回来,那么下边的所有模板渲染,都要等待,js的逻辑也得等待。这叫做js阻塞。
如果引入的js放在下边,则模板不解析,页面直接显示{{name}},等待js加载成功之后,才能解析。
<style>
[v-cloak]{
display:none;
}
</style>
<h2 v-cloak >{{name}}</h2>
v-cloak就是将没有解析的模板给隐藏掉,然后vue加载成功之后,接管dom时,先将v-cloak给删除掉。
4、v-once:当前的值,只加载一次。就是不会随着n值的改变而改变。显示的数据,就约等于静态数据了。但是其他的渲染不受影响。
<h2 v-once>初始化的n值是{{n}}></h2>
5、v-pre:跳过其所在节点的编译过程、可以使用它跳过没有指令语法、没有使用插值语法的节点,会加快编译。
a= <span>元素
console.dir(a)
a instanceof HTMElement
<h2>当前n的值是{{n}}</h2>
<h2>放大10倍后的n的值是:<span v-big="n"></span></h2>
data:{
n:1,
},
directives:{
big(element,binding){
//ele是span元素,v-big所绑定的元素
element.innerText = binding.value * 10;
}
}
v-big何时被调用?
1、指令与元素成功绑定时,模板初次被解析时。
2、页面元素发生改变,再次被解析时。
directives:{
fbind:{
bind(element,binding){
element.value = binding.value;
},
inserted(element,binding){
element.focus();
},
update(element,binding){
element.value = binding.value;
},
}
}
指令回调里边的this,是window
Vue.filter('mySlice',function(val){
? return val.slice(0,4);
});
Vue.directive('fbind',{
bind(element,binding){
element.value = binding.value;
},
inserted(element,binding){
element.focus();
},
update(element,binding){
element.value = binding.value;
},
})
mounted(){//Vue完成模板的解析,并把初始的真实DOM元素,放入到页面后(挂载完毕后),调用mounted
}
?
?
beforeDestory:阶段,能访问到数据和方法,但是进入此阶段,不会触发更新了。