Vue2基本操作
基本指令
-
插入:双大括号,放在标签内容
-
v-text="text":底层用的的innerText来写入页面
-
v-html="div":底层使用的是innerHTML写入页面
-
v-pre:想将双大括号静默(跳过编译)不写默认为true
<div v-pre="djai"></div>
判断为true -
v-cloak:隐藏
-
v-bind:绑定属性,属性里面的字符串动态改变,简写为:
<img v-bind:src="text">
案例练习
-
v-model:双向数据绑定,常用与表单元素,
v-model
本质上不过是语法糖。 -
v-once:只执行一次,后来数据改变,不改变页面
vm对象
-
$parent:父组件
-
$on:定义自定义事件
-
$emit:调用自定义事件运行
-
$children:子组件们,不会按照写代码的顺序
-
$root:根组件
-
$refs:是个对象,属性名就是绑定在模板中的reff
-
$attrs:将父组件传递给子组件的属性往下一层孙组件传递
-
$nextTick(calllbak):下一次运行模板
使用条件:当数据改变后,基于更新后的DOM进行某些操作
methods
<div id='box'>
<!-- 调用函数可以写括号也可可以不写 -->
<button v-on:click="fn">chang</button>
</div>
<script>
// vue框架提供了dom封装,不建议我们使用dom直接操作
new Vue({
el: '#box',
methods: {
fn() {
console.log(6666)
}
}
})
</script>
方法参数
- 普通参数
- 事件参数:使用特殊变量$event来获取事件对象
方法中的this
this是vm对象,利用this可以在方法中运行其他方法
<div id='box'>
<button v-on:click="fn3">chang</button>
</div>
<script>
// vue框架提供了dom封装,不建议我们使用dom直接操作
new Vue({
el: '#box',
data: {
text:'',
flag: true,
},
methods: {
fn3() {
console.log(6666)
},
fn31() {},
fn32() {}
},
})
</script>
注意:
- vue范围的方法尽量不要使用箭头函数,使用箭头函数后this指向的是window对象
- 计时器写在方法且数据源改变的时候,不要写在模板里面,会有指数级别的开启计时器
事件
- v-on:click='' 简写为@click=''
切换效果技术
- 样式绑定
- 组件或者模块切换-动态组件 v-if/v-show
- 路由切换-router
事件修饰符
-
self:自己是目标对象才可以触发
<div id='app' @click="fn"> <div class="box" @click.self="fn1"> <div class="box1" @click="fn2"> <a href="http://www.baidu.com" @click.prevent="gobaidu">gobaidu</a> </div> </div> </div> <script> new Vue({ el: '#app', methods: { fn() { console.log("app") }, fn1() { console.log("box") }, fn2() { console.log("box1") }, gobaidu() { console.log('gobaidu') } } }) </script>
-
stop:阻止冒泡
<div id='app' @click="fn"> <div class="box" @click="fn1"> <div class="box1" @click.stop="fn2"></div> </div> </div> <script> new Vue({ el: '#app', methods: { fn() { console.log("app") }, fn1() { console.log("box") }, fn2() { console.log("box1") } } }) </script>
-
prevent:阻止默认事件
分析:a标签本身有默认的点击跳转事件,加上prevent后会阻止自身的跳转事件,只执行定义的点击事件
<div id='app' @click.once="fn"> <a href="http://www.baidu.com" @click="gobaidu">gobaidu</a> </div> <script> new Vue({ el: '#app', methods: { gobaidu() { console.log('gobaidu') } } }) </script>
-
capture:捕获事件触发
-
once:只能触发一次,触发后就解绑
<div id='app' @click.once="fn"> <div class="box" @click="fn1"> <div class="box1" @click="fn2"></div> </div> </div> <script> new Vue({ el: '#app', methods: { fn() { console.log("app") }, fn1() { console.log("box") }, fn2() { console.log("box1") } } }) </script>
样式绑定
style
样式绑定,改变标签的属性
-
直接写在标签里
<h3 :style="{color: 'red'}">今天天气{{text}} </div> <script> // vue框架提供了dom封装,不建议我们使用dom直接操作 new Vue({ el: '#box', })
-
写在对象中
```<div id='box'> <h3 :style="styleobj">今天天气{{text}}</h3> <button v-on:click="cangetianqi">chang</button> </div> <script> // vue框架提供了dom封装,不建议我们使用dom直接操作 new Vue({ el: '#box', data: { text: 'good', flag: false, styleobj: { display: 'block', backgroundColor: 'pink' } }, })
-
写在数组中
<div id='box'> <h3 :style="[styel1,style2]">今天天气{{text}}</h3> <script> // vue框架提供了dom封装,不建议我们使用dom直接操作 new Vue({ el: '#box', data: { text: 'good', flag: false, styleobj: { display: 'block', backgroundColor: 'pink' }, styel1: { backgroundColor: 'pink' }, style2: { color: "red" }, }, }) </script>
class
-
变量
<style> .mianbox { width: 200px; height: 200px; } .baitian { background-color: gray; color: black !important; } .heiye { background-color: black; color: white !important; } </style> <div id='box'> <div class="mianbox" :class="classname" @click="change1"> </div> </div> <script> new Vue({ el: '#box', data: { classname: 'heiye' }, }) </script>
-
数组
<div class="mianbox" :class="[classname,mode]" @click="change1"> <script> new Vue({ el: '#box', data: { title: '状态', classname: 'baitian', mode: 'mode' }, }) </script>
数组里的从vm对象中取出的类名
-
对象
<div class="mianbox" :class="{heiye:true,mode:true}">dhsaf
对象里面是类的是否显示
条件渲染
-
v-if='':条件成立,正常显示,否则就将节点从文档树中移除
v-else-if=''和v-else
<div id='box1'> <div v-if="type=='a'">a</div> <div v-else-if="type=='b'">b</div> <div v-else>ohter</div> </div> <script> new Vue({ el: '#box1', data: { type: 'b' } }) </script>
注意:用上面进行判断,中间不能有间段
-
v-show:和v-if用法相同,用css的display:none来移除
区别:使用v-show节点不会从文档树中移除,只是隐藏起来,还会占据位置,v-if会将节点从文档树中移除,释放内存。所以对于频繁切换,具有更高的渲染消耗的使用v-show,不常用的使用v-if
循环渲染
-
v-for='item in obj'
还可以使用v-for='item for obj'
,v-for可以接受整数,手动限制运行次数<script src="./sina.js"></script> <!-- 使用v-for --> <div id='box1'> <ul class="bigbox"> <li class="box" v-for="item in obj" :key="item.id">{{item.text}}</li> </ul> </div> <script> console.log(sinadata.statuses) new Vue({ el: '#box1', data: { obj: sinadata.statuses } }) </script>
注意:在vue2.0中,如果v-for与v-if一起, v-if先执行 后执行v-for,在vue3.0中,不能将v-for和v-if写在一起。
解决方案:写成嵌套关系,写<template></template>
标签,此标签不会到文档树中
key
优点
- 让数据和真实的dom一一关联,使之不发生渲染混乱的好处
- 提高渲染效率
进行diff算法时,根据key来进行比对
计算属性
new Vue({
computed: {
// 简写
age(){
//逻辑
},
// 全写 简写相当于只有set函数
x: {
set(){},
get() {}
}
}
})
//
处理数据源中的数据,当属性数据源改变,会重新计算,刷新缓存,如果没有改变会使用已有的缓存
缺点:如果简单的运行也用计算属性,反而会增加资源消耗,计算属性会监听值。
案例:购物车计算总价
Vue.config.productionTip = false
let vm = new Vue({
el: '#box',
data: {
total: '',
order: [
{ id: '001', title: '鱼香肉丝', price: 22, count: 0 },
{ id: '002', title: '青椒肉丝', price: 20, count: 0 },
{ id: '003', title: '蔬菜', price: 12, count: 0 }
]
},
methods: {
jjisuan(flag, index) {
if (flag) {
// 加一
console.log('加一')
this.order[index].count++
} else {
// 减一
if (this.order[index].count > 0) {
console.log('减一')
this.order[index].count--
}
}
},
},
// 计算属性不需要区调用,数据改变,自然就会调用数据
computed: {
totals() {
// 获取 price count ++
let alls = 0
for (let i = 0; i < this.order.length; i++) {
alls += this.order[i].price * this.order[i].count
}
this.total = alls
}
}
})
样式穿透
使用场景,我们引入了一些第三方的库,想要修改里面的默认样式,直接修改可能不起效果,这时候就要用到样式穿透
直接修改不起作用的原因:因为一些第三方库在写的时候,会给style
标签中加上scoped
属性,避免取名重复造成的样式污染
css
可以使用>>>
,/deep/
,::v-deep
less
和node-sass
可以使用/deep/
,::v-deep
dart-sass
可以使用::v-deep
过滤器
参数,如果有多个参数
注意
- 只能写在{{}}和v-bind里面
- 全局过滤器和局部过滤器重名时,会采用局部过滤器。
往往用于数据渲染前的数据处理,没有被劫持(不能用this),其余的和方法的一致
侦听器
watch: {
obj: {
// 深度监听
deep:true,
handler: ()=> {}
}
}
注意:
- 必须是data里的数据
当侦听的属性发生变化,会重新调
例子
<div id='box'>
<input type="text" v-model="money">
<input type="text" v-model="dollar">
</div>
<script>
Vue.config.productionTip = false
new Vue({
el: '#box',
data: {
money: 0,
dollar: 0
},
watch: {
money() {
this.dollar = this.money * 0.77
}
}
})
自定义指令
定义
-
局部定义
//new Vue({ // directive:{指令名:配置对象} //}) new Vue({ directives: { red: { //el为绑定的这个属性 inserted(el) {} } }, color: { //el为绑定的这个属性,value代表外部传入的值 inserted(el,value) {} } }, })
-
全局定义
//Vue.directive(指令名,配置对象) Vue.directives(dj,{ red: { //el为绑定的这个属性 inserted(el) {} } }, color: { //el为绑定的这个属性,value代表外部传入的值 inserted(el,value) {} } }, }))
三个回调
- bind:指令与元素成功绑定时调用
- inserted:指令所在元素被插入页面时调用
- updata:指令所在模板结构被重新解析时调用
注意
- 指令定义不加v-
- 指令如果是多个单词,要使用kebab-cass命名方式,而不是kebabCass命名
生命周期
钩子函数:生命周期函数(c语言中有有一类系统回调函数然后执行业务,叫做钩子)
- 在某一种条件成立的时刻,系统会区调用vue中设定的函数,这些函数叫做生命周期函数
- 生命周期函数名字不可更改,但函数的具体内容是程序员编写的
- 生命周期中的this指向是vm或是组件实例对象
生命周期函数
- beforeCreate:此时,无法通过vm访问到data中的数据,methods中的方法
- created:此时可以通过vm访问到data中的数据,methods中配置方法
- beforeMount:此阶段Vue开始解析模板,生成虚拟DOM(内存中),页面还无法显示解析好的内容
- mounted:Vue完成模板的解析并把初始的真是DOM元素放入页面后,调用mounted
- beforeUpdate:此时,数据是新的,但页面是旧的,页面尚未和数据保持同步
- updated:此时数据是新的,页面也是新的,页面和数据保持同步
销毁Vue实例
注意:销毁后借助Vue开发工具看不见任何消息;销毁后自定义事件会失效,但原生的DOM事件依然有效,比如@click事件;一般不会在beforeDestroy操作数据,因为即使操作了数据,也不会触发流程
- beforeDestroy:vm中所有的data,methods,指令等等,都处于可用状态,马上要执行销毁。一般在此阶段:关闭定时器,,取消订阅消息,解绑自定义事件等收尾操作
- destroyed:已近销毁
常用的生命周期钩子
- mounted(发送网络请求启动定时器,绑定自定义属性,订阅消息等等);
- beforeDestroy(清楚定时器,绑定自定义事件,取消订阅消息等等)