Vue 模板语法的插值操作
- v-html ---> 可以解析标签
- v-text ---> 不可以解析标签,只可以解析纯文本内容
- v-pre ---> 屏蔽 {{ }}(胡子语法) 的功能(跳过该标签的及其子元素的编译),标签里面的内容是什么就打印什么
- v-cloak ---> 将数据请求到的时候才将视图显示出来(当数据量足够庞大的时候,请求和渲染都需要时间,这个时候可能会出现延迟)
<!-- v-html 如果文本中包含标签,会将标签一起解析出来 -->
<div v-html="txtHtml"></div>
<!-- v-text 如果文本中没有包含标签,那么既可以使用 v-html 也可以使用 v-text -->
<div v-text="txt"></div>
<!-- v-pre 会屏蔽掉胡子语法的功能,直接打印出 "{{txt}}" -->
<div v-pre>{{txt}}</div>
<!-- 因为数据请求和渲染需要时间,所以可能会出现延迟,这时候视图上就会直接渲染
出 "{{txt}}" 这个文本内容 -->
<!-- v-cloak 可以让数据成功渲染到视图上再让视图显示出来 -->
<!-- 需要在 style 里面添加一个样式 <style> [v-cloak]{ display:none; }</style> -->
<div v-cloak>{{txt}}</div>
<script>
setTimeout(function () {
var vm = new Vue({
el: "#app",
data: {
txtHtml: "<p><strong>KoBe Bryant</strong> is very play basketball</p>",
txt: "Vue",
}
})
},2000)
</script>
v-for 中的key属性(了解)
-
为什么需要这个 key 属性呢?
-
其实这个和 Vue 的虚拟DOM的Diff算法有关
-
什么是 Diff 算法呢?
- Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。
-
-
不使用 key 属性的情况下:
- 当某一个层有很多个相同的节点的时候(例如列表),我们想在列表中添加一个新的节点时,如果是使用
push往最后一个添加,不会出现什么情况,但是如果使用unshift往第一个列表添加的时候,默认新增加的节点会占据原先的第一个节点元素,原先的第一个节点元素会占据第二个节点元素,第三个节点元素会占据第四个节点元素...以此类推,最后一个节点元素的位置被上一个节点元素占据,这时浏览器会重新给它渲染一个节点,这样子的效率太低了,也大大损耗了服务器的性能(当数据量足够大的时候) ---> 由此引出了下面的 key 属性。
- 当某一个层有很多个相同的节点的时候(例如列表),我们想在列表中添加一个新的节点时,如果是使用
-
使用 key 属性的情况下:
- 当我们使用 key 来为每一个节点做唯一标识的,Diff算法会以 key 作为标识来识别此节点,下一次添加新的节点的时候,会找到正确的位置插入新的节点,这样子大大节省了浏览器的性能损耗问题(当数据量足够大的时候)。
- 但是这里 key 的值只能使用每一次循环的
元素,而不能使用下标来做标识,因为使用下标的话,下标是从0开始的,如果往第一个列表添加新的节点,新增加的节点的下标就会变成0,原先的节点下标依次往后面退一位,这样子又出现了跟上面一样的情况。
-
数组的 reduce 方法
- reduce 是数组里面的一个方法,可以用来遍历数组中的每一个元素,reduce()调用结果最后返回一个最终值(就是最后一次 return 的值)
<script>
var arr = [
{name: 'Vuejs入门', price: 99, count: 3},
{name: 'Vuejs底层', price: 89, count: 1},
{name: 'Vuejs从入门到放弃', price: 19, count: 5},
];
// reduce(参数1,参数2) 有两个参数
// 参数1:回调函数,回调函数里面还有两个参数
// 参数1:pre 上一个遍历的返回值
// 参数2:current 当前遍历的这个元素
// 参数2:pre 的默认初始值
var ret = arr.reduce(function(pre,current){
console.log(pre, current);
var total = pre + (current.price * current.count);
return total;
},0)
alert(ret);
</script>
Vue 中的计算属性 computed
- computed 是 Vue 中的一个计算属性,主要作用是把数据存储到内存中,减少不必要的请求,还可以利用computed给子组件的data赋值。
<div id="app">
<p>总价:{{ total }}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
arr = [
{name: 'Vuejs入门', price: 99, count: 3},
{name: 'Vuejs底层', price: 89, count: 1},
{name: 'Vuejs从入门到放弃', price: 19, count: 5},
];
},
// Vue 中的计算
computed: {
// 直接当做普通属性调用不加括号
// 任何data中数据变化立即重新计算
// 计算属性会缓存
total() {
var ret = this.arr.reduce(function (pre, current) {
var total = pre + (current.price * current.count);
return total;
},0)
return ret;
}
},
})
</script>
methods 方法和 computed 计算属性的区别
-
methods 方法每调用一次就重新执行代码,这样子大大损耗了服务器的性能
-
computed 计算属性的内部方法会缓存,只要执行过一次,后面再执行,就不会重新执行代码,而是直接将前面缓存过的数据拿来使用哪个。
- 如果直接拿来当做属性调用则不需要加括号
- 任何 data 中的数据只要一发生改变就会重新计算
- 计算属性会自动进行缓存,以便以后的重复调用
-
注意:当不需要缓存的时候,就可以使用 methods ,如果需要缓存,则 computed 更优。
computed 内部方法的另一种写法 get() 和 set()
-
get()方法是取,相当于我们可以在get中给计算属性的变量赋值
-
set()方法是改变时触发,这里的改变是指当我们定义在 computed 中的变量发生改变时,会触发 set 方法
- 例如:vm.需要返回的变量名 = '重新定义的值' (我们的返回值都存储在
vm中)
- 例如:vm.需要返回的变量名 = '重新定义的值' (我们的返回值都存储在
v-model 的原理
-
v-model 的原理本质上包含了两点:
- v-bind:绑定
input标签的value属性 - v-on:绑定
input标签的input事件
- v-bind:绑定
-
v-on:input 事件只要用户一输入内容就会触发 input 事件的执行.
<div id="app">
<!-- <input type="text" v-model="txtVal"> --> // 双向数据绑定
// v-model 的原理就是这样子来的
<input type="text" v-bind:value="txtVal" v-on:input="handelInput">
<p>{{ txtVal }}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
txtVal: "",
},
methods:{
handelInput(e){ // 一输入内容就触发一次事件对象
// e.target.value 里面存放着用户输入的文本内容
this.txtVal = e.target.value
}
}
})
</script>
Vue 的过滤器的使用
- Vue 过滤器的语法即格式 ---> Vue 过滤器用来对数据展示前做的一些处理
<div id="app">
<!-- 格式 {{ 变量名 | 过滤器名 }} -->
<p>{{ num | formatNum}}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
num: 10
},
filters:{
formatNum(val){ // 这个形参接收的 | 符号前面的变量数据
return val + 50;
// return 后面的返回值就是将来要展示在页面上的值(即过滤后的值)
}
}
)
</script>
- 过滤器的使用 ---> 过滤一个时间戳(当我们获取到一个时间戳的时候,就要使用过滤器对它进行过滤转化为标准的时间格式 YYYY-MM-DD HH:mm:ss)
<div id="app">
<p>{{ timestamp | formatDate }}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
timestamp: new Data().getTime(),
},
filters:{
formatDate(val){ // 获取到的是 timestamp 的数据
var now = new Date(val)
var year=now.getFullYear();
var month=now.getMonth()+1;
var date=now.getDate();
var hour=now.getHours();
var minute=now.getMinutes();
var second=now.getSeconds();
return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
}
}
})
</script>
Vue 全局过滤器的使用
- 当出现多个 app 共用一个过滤器的时候,可以将这个过滤器设置成全局的,以便可以重复使用
<!-- 两个标签都是共用同一个过滤器,如果为每一个标签都设置一个过滤器,过于浪费服务器资源 -->
<div id="app1">
<p>{{ timestamp | formatDate }}</p>
</div>
<div id="app2">
<p>{{ timestamp | formatDate }}</p>
</div>
<script>
<!-- 全局过滤器书写格式 Vue.filter("过滤器名称",(val) => {}) -->
Vue.filter("formatDate",(val) => { // 切记 全局过滤器filter是不用加 s 的
var now = new Date(val)
var year=now.getFullYear();
var month=now.getMonth()+1;
var date=now.getDate();
var hour=now.getHours();
var minute=now.getMinutes();
var second=now.getSeconds();
return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
})
<!-- 将两个Vue构造函数的过滤器提取出来设置成全局过滤器 -->
var vm1 = new Vue({
el: "#app1",
data: {
timestamp: new Date().getTime();
}
})
var vm2 = new Vue({
el: "#app2",
data: {
timestamp: new Date().getTime();
}
})
</script>