1、Once
v-once指令:让界面不要跟着数据变化, 只渲染一次
<p v-once>原始数据: {{ name }}</p>
2、v-cloak
① Vue数据绑定过程
vue会先将未绑定数据的界面展示给用户,然后再根据模型中的数据和控制的区域生成绑定数据之后的HTML代码,最后再将绑定数据之后的HTML渲染到界面上。
正是在最终的HTML被生成渲染之前会先显示模板内容,所以如果用户网络比较慢或者网页性能比较差, 那么用户会看到模板内容。
② v-cloak
利用v-cloak配合 [v-cloak]:{display: none}默认先隐藏未渲染的界面,等到生成HTML渲染之后再重新显示。
v-cloak指令作用:数据渲染之后自动显示元素。
[v-cloak] {
display: none
}
<p v-cloak>{{ name }}</p>
3、v-text和v-html
v-text就相当于过去学习的innerText
v-text会覆盖原来的html,但不会自动解析html
<p v-text="name">++++++++</p>
v-html就相当于过去学习的innerHTML
v-html会覆盖原来的html,会自动解析html
<p v-html="name">++++++++</p>
4、v-if
如果v-if取值是true就渲染元素, 如果不是就不渲染元素。
特点:如果条件不满足根本就不会创建这个元素。
v-if可以从模型中获取数据,也可以直接赋值一个表达式。
<p v-if="hidden">我是false</p>
<p v-if="true">我是true</p>
<p v-if="age >= 18">我是true</p>
v-else指令可以和v-if指令配合使用, 当v-if不满足条件时就执行v-else就显示v-else中的内容。v-else不能单独出现,v-if和v-else中间不能出现其它内容。
v-else-if可以和v-if指令配合使用, 当v-if不满足条件时就依次执行后续v-else-if, 哪个满足就显示哪个。
<p v-if="score >= 80">优秀</p>
<p v-else-if="score >= 60">良好</p>
<p v-else>差</p>
5、v-show
v-show和v-if的能够一样都是条件渲染, 取值为true就显示, 取值为false就不显示。
<p v-show="hidden">我是false</p>
<p v-show="true">我是true</p>
<p v-show="age >= 18">我是true</p>
① v-if和v-show区别:
v-if: 只要取值为false就不会创建元素。
v-show: 哪怕取值为false也会创建元素, 只是会设置元素的display为none。
② v-if和v-show应用场景:
v-if切换元素的显示和隐藏, 每都会创建和删除元素。
v-show会创建元素,取值为false时设置display为none, 不会反复创建和删除。
所以: 如果需要频繁切换元素显示隐藏, 那么推荐使用v-show, 否则使用v-if。
6、v-for
相当于JS中的for in循环, 可以根据数据多次渲染元素
可以遍历 数组, 字符, 数字, 对象。
<li v-for="(value, key) in obj">{{key}}---{{value}}</li>
v-for-key:
问题:v-for为了提升性能, 在更新已渲染过的元素列表时,会采用“就地复用”策略。
也正是因为这个策略, 在某些时刻会导致我们的数据混乱。
解决方法:在渲染列表的时候给每一个元素加上一个独一无二的key,v-for在更新已经渲染过的元素列表时, 会先判断key是否相同, 如果相同则复用, 如果不同则重新创建。
Key:必须为独一无二的值。
<ul>
<li v-for="(person,index) in persons" :key="index">
<input type="checkbox">
<span>{{index}} --- {{person.name}}</span>
</li>
</ul>
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
persons: [
{ name: "zs", id: 1 },
{ name: "ls", id: 2 },
{ name: "ww", id: 3 }
],
name: ""
},
// 专门用于存储监听事件回调函数
methods: {},
// 专门用于定义计算属性的
computed: {}
});
7、v-bind
① 绑定数据:
给元素绑定数据:{{}},v-text,v-html
给元素的属性绑定数据:v-bind,v-model
② 格式:
v-bind:属性名称=“绑定的数据”
:属性名称=“绑定的数据”
③ 绑定类名:
默认去model中查找类名,
只有类名用’’括起来然后放到数组中才会去style中查找类名。
格式一:动态绑定一个class
:class=“[需要绑定类名]”
<p :class="['size']">我是段落</p>
格式二:动态绑定多个class
:class=“[‘需要绑定类名’, …]”
<p :class="['size', 'color', 'active']">我是段落</p>
格式三:根据状态判断是否绑定class或者绑定哪个class
:class=“[flag?‘active’:‘’]”
<p :class="['size', 'color', flag ? 'active' : '']">我是段落</p>
格式四:
:class=“[{‘active’: true}]”
<p :class="['size', 'color',{'active' : false}]">我是段落</p>
格式五:
obj: {
'color': true,
'size': true,
'active': false,
}
<p :class="obj">我是段落</p>
④ 绑定样式:
只需要将样式代码放到对象中赋值给style即可,如果属性名称包含-, 那么必须用引号括起来,取值必须用引号括起来。
如果需要绑定Model中的多个对象, 可以放到一个数组中赋值
格式一:将数据放到对象中
:style=“{color:‘red’,‘font-size’:‘50px’}”
<p :style="{color: 'red', 'font-size': '100px'}">我是段落</p>
格式二:将数据放到Model对象中
obj: {
color: 'red',
'font-size': '80px',
}
<p :style="obj">我是段落</p>
<p :style="[obj1, obj2]">我是段落</p>
⑤ V-bind与v-model:
V-bind:单向数据绑定,可绑定一个表达式。
v-model:给输入框的value属性绑定数据,是双向数据绑定。
<input type="text" v-model="name">
<input type="text" v-bind:value="name">
<input type="text" :value="name">
<input type="text" :value="age + 1">
8、V-on
① v-on指令专门用于给元素绑定监听事件。
v-on绑定的事件被触发后, 会去Vue实例对象的methods中查找对应的回调函数。
如果是通过v-on来绑定监听事件, 那么在指定事件名称的时候不需要写on,而且在赋值的时候必须赋值一个回调函数的名称。
绑定回调函数名称的时候, 后面可以写()也可以不写。
② v-on指令格式
v-on:事件名称=“回调函数名称”
@事件名称=“回调函数名称”
可以给绑定的回调函数传递参数:
v-on:click="myFn('lnj', 33)"
③ 示例:
<button @click="myFn">我是按钮</button>
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
name:'xhl'
},
methods: {
myFn(){
//如果在绑定的函数中需要用到data中的数据必须加上this
alert(this.name);
}
}
});
④ v-on修饰符
.once - 只触发一次回调。
.prevent - 阻止元素的默认行为,调用 event.preventDefault()。
.stop - 阻止事件冒泡,调用 event.stopPropagation()。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.capture - 添加事件侦听器时使用 capture 模式, 默认情况下是事件冒泡, 如果想变成事件捕获, 那么就需要使用.capture修饰符。
<button v-on:click.once ="myFn">我是按钮</button>
<a href="http://www.it666.com" v-on:click.prevent="myFn">
我是A标签
</a>
<div class="a" @click="myFn1">
<div class="b" @click.stop="myFn2">
<div class="c" @click="myFn3"></div>
<div class="a" @click="myFn1">
<div class="b" @click.self="myFn2">
<div class="c" @click="myFn3"></div>
<div class="a" @click.capture="myFn1">
<div class="b" @click.capture="myFn2">
<div class="c" @click.capture="myFn3"></div>
⑤ v-on按键修饰符
系统预定义修饰符:
<input type="text" @keyup.enter="myFn">
自定义修饰符:
<input type="text" @keyup.f2="myFn">
Vue.config.keyCodes.f2 = 113;
⑥ .sync
9、自定义全局指令
① 自定义全局指令语法:
vue.directive('自定义指令名称', {
生命周期名称: function (el) {
指令业务逻辑代码
}
});
② directive方法接收两个参数:
第一个参数: 指令的名称
第二个参数: 对象
③ 注意点:
自定义指令,使用时需要加上v-, 而在自定义时不需要加上v-
指令可以在不同的生命周期阶段执行:
bind: 指令被绑定到元素上的时候执行(指令业务逻辑代码中没有用到元素事件)。
inserted: 绑定指令的元素被添加到父元素上的时候执行(指令业务逻辑代码中用到了元素事件)。
Vue.directive("color", {
// 这里的el就是被绑定指令的那个元素
bind: function (el) {
el.style.color = "red";
}
});
Vue.directive("focus", {
// 这里的el就是被绑定指令的那个元素
inserted: function (el) {
el.focus();
}
});
④ 自定义指令参数:
<p v-color="curColor">我是段落</p>
Vue.directive("color", {
// 这里的el就是被绑定指令的那个元素
bind: function (el, obj) {
// el.style.color = "red";
el.style.color = obj.value;
}
});
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
curColor: 'green'
},
// 专门用于存储监听事件回调函数
methods: {}
});
(10)自定义局部指令
只能在自定义的那个Vue实例中使用
<div id="app2">
<p v-color="'red'">我是段落</p>
</div>
let vue2 = new Vue({
el: '#app2',
// 这里就是MVVM中的Model
data: {},
// 专门用于存储监听事件回调函数
methods: {},
// 专门用于定义局部指令的
directives: {
"color": {
// 这里的el就是被绑定指令的那个元素
bind: function (el, obj) {
el.style.color = obj.value;
}
}
}
});
(11)计算属性
① 是属性不是方法
虽然在定义计算属性的时候是通过一个函数返回的数据,但是在使用计算属性的时候不能在计算属性名称后面加上(),因为它是一个属性不是一个函数(方法)。
<p>{{msg2}}</p>
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
name: "lnj",
age: 18,
msg: "abcdef"
},
// 专门用于存储监听事件回调函数
methods: {},
// 专门用于定义计算属性的
computed: {
msg2: function () {
let res = "abcdef".split("").reverse().join("");
return res;
}
}
});
② 计算属性和函数
相同点:
通过计算属性我们能拿到处理后的数据, 但是通过函数我们也能拿到处理后的数据。
不同点:
函数"不会"将计算的结果缓存起来, 每次调用都会执行,每一次访问都会重新求值;
计算属性"会"将计算的结果缓存起来, 只要数据没有发生变化, 就不会重新求值。
③ 计算属性应用场景
由于计算属性会将返回的结果缓存起来,所以如果返回的数据不经常发生变化,
那么使用计算属性的性能会比使用函数的性能高。所以计算属性比较适合用于计算不会频繁发生变化的的数据。
(12)Data为什么是函数返回
如果你不用函数,只用对象保存数据时,所有组件将引用一个公共的obj。一个属性改动,其他组件上全部都更改了。
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。
(13)自定义全局过滤器
① 过滤器:
过滤器和函数和计算属性一样都是用来处理数据的,但是过滤器一般用于格式化插入的文本数据。
② 如何自定义全局过滤器
Vue.filter(“过滤器名称”, 过滤器处理函数):
③ 如何使用全局过滤器
{{msg | 过滤器名称}}
:value="msg | 过滤器名称"
在使用过滤器的时候, 可以在过滤器名称后面加上()。
如果给过滤器的名称后面加上了(), 那么就可以给过滤器的函数传递参数。
{{time | dateFormart("yyyy-MM-dd")}}
④ 过滤器注意点:
只能在插值语法和v-bind中使用
过滤器可以连续使用
⑤ 示例:
示例一:(无参数)
<div id="app">
<!--Vue会把name交给指定的过滤器处理之后,
再把处理之后的结果插入到指定的元素中-->
<p>{{name | formartStr1 | formartStr2}}</p>
</div>
Vue.filter("formartStr1", function (value) {
// console.log(value);
value = value.replace(/学院/g, "大学");
console.log(value);
return value;
});
Vue.filter("formartStr2", function (value) {
// console.log(value);
value = value.replace(/大学/g, "幼儿园");
console.log(value);
return value;
});
示例二:(有参数)
<div id="app">
<p>{{time | dateFormart("yyyy-MM-dd")}}</p>
</div>
Vue.filter("dateFormart", function (value, fmStr) {
// console.log(fmStr);
let date = new Date(value);
let year = date.getFullYear();
let month = date.getMonth() + 1 + "";
let day = date.getDate() + "";
let hour = date.getHours() + "";
let minute = date.getMinutes() + "";
let second = date.getSeconds() + "";
if(fmStr && fmStr === "yyyy-MM-dd"){
return `${year}-${month.padStart(2, "0")}-
${day.padStart(2, "0")}`;
}
return `${year}-${month.padStart(2, "0")}-
${day.padStart(2, "0")} ${hour.padStart(2, "0")}:
${minute.padStart(2, "0")}:
${second.padStart(2, "0")}`;
});
(14)自定义局部指令
只能在自定义的那个Vue实例中使用。
<div id="app2">
<p>{{name | formartStr}}</p>
</div>
let vue2 = new Vue({
el: '#app2',
// 这里就是MVVM中的Model
data: {
name: "知播渔学院, 指趣学院, 前端学院, 区块链学院"
},
// 专门用于存储监听事件回调函数
methods: {},
// 专门用于定义计算属性的
computed: {},
// 专门用于定义局部过滤器的
filters: {
"formartStr": function (value) {
// console.log(value);
value = value.replace(/学院/g, "大学");
// console.log(value);
return value;
}
}
});
(15)ref:获取Dom元素
① ref用于元素
在需要获取的元素上添加ref属性,使用时通过 this.$refs.xxx获取
<p ref="myppp">我是原生的DOM</p>
console.log(this.$refs.myppp);
② ref用于组件
如果是添加给自定义的组件, 那么拿到的就是自定义的组件。
<template id="one">
<div>
<p>我是组件</p>
</div>
</template>
Vue.component("one", {
template: "#one",
data: function () {
return {
msg: "zby"
}
},
methods: {
say() {
console.log("say");
}
},
});
<one id="myOne" ref="myOne"></one>
console.log(this.$refs.myOne);
console.log(this.$refs.myOne.msg)
(16)组件的渲染方式
① 方式一:通过标签
先定义注册组件, 然后在Vue实例中当做标签来使用。
定义组件:
<template id="one">
<div>
<p>我是组件222</p>
</div>
</template>
注册组件:
Vue.component("one", {
template: "#one"
});
把注册名称当标签使用:
<div id="app">
<one></one>
</div>
② 方式二:通过render
先定义注册组件, 然后通过Vue实例的render方法来渲染。
定义组件:
<template id="one">
<div>
<p>我是组件222</p>
</div>
</template>
注册组件:
Vue.component("one", {
template: "#one"
});
在创建vue实例中,添加一个render的key,对应的vue是一个函数,在函数中渲染组件。
let vue = new Vue({
el: '#app',
render: function (createElement) {
let html = createElement("one");
return html;
}
});
③ 方式一和方式二的区别:
方式一:通过标签渲染组件,把组件渲染在vue实例控制区域中,不会覆盖Vue实例控制区域
方式二:通过render渲染组件,组件直接覆盖掉vue实例控制区域。