VUE2
文章目录
模板语法
标签体内容用差值语法,属性用:(v-bind:)也就是指令语法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G8COcV8F-1662560470884)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220825203807795.png)]
Vue实例化中语法
数据绑定的两种方法
-
v-bind单项数据绑定
简写为 :value=“name”
-
v-model双项数据绑定
只能应用在表单类元素上(输入类,有value值)
简写为 v-model=“name”
绑定容器el的两种方法
-
在一开始new的时候就指定
new vue({ el:"#root", data:{ } })
-
一开始不知道,后加
扫描二维码关注公众号,回复: 14808521 查看本文章const x = new vue({ data:{ } }) x.$mount("#root")
data的两种写法
-
对象式(咱就不说了)
-
函数式(组件的时候必须用这个)
data:function(){ //不能用箭头函数 return{ name:"sss" }//返回值是我需要的函数 } //可以简写 data(){ //不能用箭头函数 return{ name:"sss" }//返回值是我需要的函数 }
Vue实例中方法
new vue({
el:"#root",
data:{
},
methods:{
xxx(e){
...
}
}
})
- methods中的this指向vm或者组件实例对象
数据代理(Object.defineProperty())
let num = 18;
let person={
name:"55",
sex:"男"
}
//数据代理雏形
Object.defineProperty(person,"age",{
// value = 18,
//enumerable:false,
//configurable:false,
//writable:false,
//以上三个默认值都是false
get(){
log(...)
return num //把这个变量当做值
},
set(value){
log(...)
num=value //!!!!!!!没有这一步可是没法绑定着一起改值
}
})
指令语法
数据绑定的两种方法
-
v-bind单项数据绑定
简写为 :value=“name”
-
v-model双项数据绑定
只能应用在表单类元素上(输入类,有value值)
简写为 v-model=“name”
事件处理
####1. 点击事件绑定
<button v-on:click="show">点我</button>
简写形式:
<button @click="show">点我</button>
如果其中函数要传参
<button @click="show($event,66)">点我</button>
//$event代表e 如果要用=>就这样占个位
不用的话=>可以省略
2. 事件修饰符
- 可以连续写
- 例1:@click.stop.prevent=“show”
- 例2:检测组合键:@keyup.ctrl.y=“show”
//阻止默认行为(常用)
<button @click.prevent="show($event,66)">点我</button>
//阻止冒泡(常用)
<button @click.stop="show($event,66)">点我</button>
//事件只触发一次(一次性事件)(常用)
<button @click.once="show($event,66)">点我</button>
//事件捕获模式
<button @click.capture="show($event,66)">点我</button>
//只有e.target是当前操作的元素才触发事件
<button @click.self="show($event,66)">点我</button>
//事件默认行为立即执行,无需等待事件回调执行完毕
<button @click.passive="show($event,66)">点我</button>
####3. 滚动条事件绑定
<div @scroll="show">滚我</div>
####4. 鼠标滚轮事件绑定
<div @wheel="show">滚我</div>
####5. 键盘事件绑定
<input @keyup="show">输入</input>
<input @keydown="show">输入</input>
//按下某按键触发(别名)
<input @keyup.enter="show">输入</input>
监视属性
//第一种监视属性写法(适用于一开始就确定要监视什么)
const vm = new vue({
el:"#root",
data:{
},
methods:{
},
watch:{
xxx:{
deep:true,//开启多层级监测所有属性
immediate:false,
handler(newvalue,oldvalue){
log...
}
"num.a":{
}//监视多级结构某个属性的变化
}
}
})
//第二种监视属性写法(适用于一开始不确定要监视什么)
vm.$watch("xxx",{
immediate:false,
handler(newvalue,oldvalue){
...
}
})
###监视属性简写
(不需要其他配置项就可以简写,只有handler)
watch:{
isHot(newValue,oldValue){
...
}
}
//第二种
vm.$watch("...",function(newValue,oldValue){
...
})
条件渲染
“布尔值/能转为布尔值的表达式”
1. v-show=“”
2. v-if=“”
v-else-if=“”
v-else>
- 且不允许被打断
- 可以和template配合,不影响最后的结构
列表渲染
v-for=“(value,index in xxx)”
- 列表
- 对象
- 字符串
- 指定次数循环
key的原理
面试题:vue中key有什么作用?
Vue监视原理
后添加可监视的数据
Vue.set()
vm.$set()
内置指令(重要)
###1. v-text
不支持结构解析 约等于innerText
2. v-html
支持结构解析 约等于innerHtml
3. v-cloak
-
是一个特殊属性 没有值
-
在vue接管时会被删除
-
可以配合css
[v-cloak]{ display:none }
4. v-once
- 初次动态渲染后,就视为静态数据,不再改变
5. v-pre
- vue不去进行编译
- 可跳过无需编译的代码,提高性能
6. 自定义指令
-
自定义指令里的this时window
-
自定义指令何时会被调用?
-
- 指令与元素成功绑定的时候(一开始)
- 指令所在的模板被重新解析的时候
-
函数式
-
new Vue({ el:"#root", data:{ name:"hhh", n:1 }, directives:{ big(ele,bingding){ ele.innerText = bingding.value*10 } } })
-
对象式
-
new Vue({ el:"#root", data:{ name:"hhh", n:1 }, directives:{ big:{ bind(ele,binding){ //元素绑定时 }, inserted(ele,binding){ //元素放入页面时 }, update(ele,binding){ //绑定元素更新时 } } } })
-
-
总结
生命周期(重要)
1.图示
- 总结
组件重要属性
render函数
-
在脚手架中使用,因为引入的vue是精简版,没有模板编译器
-
render:h=>h(App) //用来代替以下两行 //<template><App></App></template> //components:{App}
修改脚手架默认配置
- 入口文件,语法检查等配置
- 可通过查询官方文档 用vue.config.js文件修改
ref属性
-
用于当作id的替代者拿到元素
-
用在html元素上拿到的是真实dom元素,用在组件元素上拿到的就是组件实例对象(vc)
-
使用方法:先打标识,后获取
-
<h1 ref="title"> 你好 </h1>
-
console.log(this.$refs.title)
-
props配置
-
功能:让组件接受外部传来的数据
-
使用:
-
传递数据
<SchoolMsg name="xxx" age="18"></SchoolMsg> //传递的都是字符型,要传递数字型,则:加冒号 <SchoolMsg name="xxx" :age:"18"></SchoolMsg>
-
接收数据,方式有三:
-
-
只简单接受,不限制
methods:{ }, props:["name","age"]
-
-
-
限制类型
props:{ name:String, age:Number }
-
-
-
完整写法,限制类型,限制必要性,指定默认值
props:{ name:{ type:String, requirea:true }, age:{ type:Number, default:99 } }
-
-
-
-
注意:props属性是只读的,vue底层会检测不让你修改。如果要修改可以把要修改的数据备份到data中,然后去修改data的数据
//备份 data(){ return{ myName:this.name } }
mixin混入
-
本质:其实就是代码复用,把多个组件公用的代码配置提取成一个混入对象
-
使用方法:
-
定义混合
-
新建mixin.js
-
写入公用配置
export const mixin = { data(){ }, methods:{ } } export const mixin2 = { data(){ }, methods:{ } }
-
-
引入使用
-
全局混入:
import { mixin,mixin2} from './xxx/mixin.js' Vue.mixin(xxx)
-
局部混入:
import { mixin} from './xxx/mixin.js' mixins:[xxx]
-
-
vue插件(Plugins.js)
-
本质:一个包含install方法的对象,第一个参数是Vue,第二个参数是插件使用者传递的数据
export default{ install(Vue){ ... //1. 添加全局过滤器 Vue.filter("过滤器名字",function(val){ return val.xxxxxx }) //2. 添加全局指令 Vue.derective("指令名",{ bind(ele,bingding){ ... ele.value = bingding.value }, inserted(ele,binding){ ... }, updata(ele,binding){ ... ele.value = bingding.value } }) //3.配置全局混合 Vue.mixin({ //例: data(){ return{ ... } } }) //4.添加实例方法 Vue.prototype.$myMethods=function(){ ...} Vue.prototype.$myPrototype = xxx Vue.prototype.hello=()=>{ alert("555")} } }
-
使用:
import Plugins from './.../Plugins.js' Vue.use(插件名)
scoped
-
功能:防止多组件类名冲突
-
使用:
<style scoped>....</style>
组件自定义事件(用于 子传父)
绑定
-
第一种 @/v-on法
<student @zidingyi="demo(这个就是你要回调的函数)"/>
methods:{ demo(name){ console.log("我收到了某个数据:" +name) } }
student组件
//<button @click="chufa">点击触发自定义事件</button> methods:{ chufa(){ this.$emit("zidingyi",this.name)//this.name就是我要传的参数,可传递多个,实现子传父 } }
-
第二种 ref法
<student ref="student"/>
mounted(){ this.$refs.student.$on("zidingyi",this.demo) //this.$refs.student.$once("zidingyi",this.demo) //this.demo 要么在父组件中配置好,要么直接回调使用箭头函数,否则this指向会出问题(指向emit他的组件) }
student组件
//<button @click="chufa">点击触发自定义事件</button> methods:{ chufa(){ this.$emit("zidingyi",this.name)//this.name就是我要传的参数,可传递多个,实现子传父 } }
解绑
jiebang(){
this.$off("zidingyi")//解绑zidingyi
this.$off(["zidingyi","zidingyi"])//解绑两个
this.$off()//全部解绑
this.$destroy()//销毁this组件,与之相关的自定义事件全部解绑
}
组件绑定原生dom事件
需要native修饰符,否则组件会把它认为是自定义事件
<demo @click.native="show"></demo>
组件全局事件总线(重要)
-
适用于任意组件间通信
-
安装全局时间总线
new Vue({ ... beforeCreate(){ Vue.prototype.$bus=this }, ... })
-
使用事件总线
-
接受数据,a想接收数据,则a给bus绑定自定义事件
methods:{ demo(data){ console.log("我收到了:"+data) } }, mounted(){ this.$bus.$on("zidingyi",this.demo) }
-
提供数据的组件,触发自定义事件,同时传送要发的数据
//在某个函数中可写 this.$bus.$emit("zidingyi",要传的数据xxx)
-
-
解绑事件
-
最好在绑定了自定义事件的组件a里,用beforeCreate钩子解绑事件
... beforeCreate(){ this.$bus.$off("zidingyi") } ...
-
消息订阅与发布(pubsub-js)
-
安装:npm i pubsub-js
-
使用:
- 接收数据(订阅消息),a想接收数据,则a给bus订阅一个消息
import pubsub from 'pubsub-js' methods:{ demo(msgName,data){ console.log("我收到了:"+data) } }, mounted(){ this.pubId=pubsub.subscribe("hello",this.demo) this.pubId=pubsub.subscribe("hello",(msgName,data)=>{ ... }) }
-
提供数据的组件,触发自定义事件,同时传送要发的数据
import pubsub from 'pubsub-js' //在某个函数中可写 pubsub.publish("hello",要传的数据xxx)
-
取消订阅
最好在订阅了消息的组件a里,用beforeCreate钩子解绑事件
... beforeCreate(){ pubsub.unsubscribe(this.pubId) } ...
$nextTick钩子(重要)
-
语法:
this.$nextTick(function(){ ... })
-
作用:在下一次的dom更新后再去执行回调
-
什么时候用:当改变数据后,要基于更新后的新dom做些操作,那就在这个钩子里执行那些操作
动画
使用方法
单个元素
-
把要使用动画的元素用包裹起来
<transition name="hello" appear> <h1 (v-show..条件)> 你好 </h1> </transition> <!--appear 用于一开始直接有动画,不用触发-->
-
准备样式
//准备动画 @keyframe animate{ 0%{ transform:translateX(-100%) } 100%{ transform:translateX(0px) } } //进入动画 name/v-enter-active .hello-enter-active{ animation:animate 1s linear } //退出动画 name/v-leave-active .hello-leave-active{ animation:animate 1s linear reverse }
多个元素
- 用包裹,里面的每个元素加key标识
animate.css库
使用:
import 'animate.css'
<transition
name="animate__animated animate__bounce"
enter-active-class="xxx"
leave-active-class="xxx"
>
<h1 (v-show..条件)>
你好
</h1>
</transition>
插槽slot
单个插槽
-
基本使用
- 组件student
<template> <div> <p></p> <slot></slot> </div> </template>
2.父组件app
可以用同一组件显示出两种效果
<template> <div> <student><button></button></student> <student><p></p></student> </div> </template>
-
默认显示
-
子组件放插槽的地方…
<slot><button></button></slot>
-
父组件使用子组件时
<!-- 什么都没写默认插入button--> <student></student> <student></student> <!-- 写了p,那就把butto替换成p--> <student><p></p></student>
-
使用多个插槽
-
具名插槽(只适用于template)
子组件student
<template> <div> <slot name="left"></slot> <slot name="center"></slot> <slot name="right"></slot> </div> </template>
父组件(只替换中间的slot)(同时替换两个用template包裹)
<template> <student v-slot="center"> <p >哈哈哈哈</p> </student> </template> <template> <student > <template v-slot="center"> <p >哈哈哈哈</p> </template> <template v-slot="right"> <p >哈哈哈哈</p> </template> </student> </template>
子组件的数据通过插槽子传父
子组件student
<template>
<div>
<slot :data="data" name="default">
{
{data.name}}
</slot>
</div>
</template>
父组件
<template>
<student>
<template v-slot:default="data">//当只有一个slot时,defalut可以省略
{
{data.sex}}
</template>
</student>
</template>