https://cn.vuejs.org/v2/guide/computed.html
一、企业提高开发效率的发展历程
原生JS->jquery之类的库->前端模板引擎->Vue.js/Angular.js/React.js(能够帮助我们减少不必要的DOM模板——虚拟DOM;提高渲染效率)
二、框架和库的区别
- 框架:
框架是一套完整的解决方案
对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。但是优点也很明显,其功能完善,提供了一整套的解决方案 - 库(插件)
只是提供某一个小功能
对项目入侵性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求
三、Vue和React的相同点
- 利用虚拟DOM实现快速渲染
- 轻量级
- 响应式组件
- 支持服务器端渲染
- 易于集成路由工具、打包工具以及状态管理工具
四、什么是虚拟DOM
传统的web开发是利用jQuery操作DOM,这是非常耗费资源的。我们可以在JS的内存里构建类似于DOM的对象,去拼装数据,拼装完毕后,把数据整体解析,一次性插入到html里去,这就形成了虚拟DOM
五、Vue渲染
条件渲染
v-if
和v-else
中间不能有其他的元素,否则会报错v-if
不显示时,第一次就直接不渲染,如果内容已经显示将其改为不显示,则将内容从DOM上删除;v-show
不显示时就会改为display:none
,但是会渲染在DOM上,反复使用的话建议用v-show
,性能消耗小
列表渲染
v-for="item in lists" :key="唯一值"
,先循环再进行判断
六、模板语法
<h1>{{msg}}</h1>
可反复插入<h1 v-once>{{msg}}</h1>
只插入一次,修改msg无法修改里面的值。但请留心这会影响到该节点上的其它数据绑定v-html
可以插入html代码
注意:你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
<p>{{ rawHtml }}</p>
<p><span v-html="rawHtml"></span></p>
v-bind
绑定一个变量,可以缩写为<div :id="dynamicId"></div>
- 模板中还可以写JS表达式,但每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
v-on
指令,用于监听 DOM 事件,<a v-on:click="doSomething"></a>
可缩写为:<a @click="doSomething"></a>
动态参数
<a v-bind:[attributeName]="url"> ... </a>
这里的attributeName
会被作为一个JS 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个data property attributeName
,其值为"href"
,那么这个绑定将等价于v-bind:href
。- 对动态参数的值的约束:动态参数预期会求出一个字符串,异常情况下值为
null
。这个特殊的null
值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告
修饰符
<form v-on:submit.prevent="onSubmit">...</form>
,.prevent
修饰符告诉v-on
指令对于触发的事件调用event.preventDefault()
七、计算属性
<div id="app">
<!-- 一般写法 -->
<h1>{{firstname+lastname}}</h1>
<!-- 计算属性,反复使用效果好 -->
<h1>{{fullname}}</h1>
</div>
<script type="text/javascript">
let app = new Vue({
el:"#app",
data:{
firstname:"z",
lastname:"jj",
},
computed:{
fullname:function(){
// 将计算结果弄进缓存,只有修改之后才会再次运行
return this.firstname + this.lastname
}
}
})
</script>
缓存和方法
- 我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
- 我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
计算属性的setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
现在再运行
vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和vm.lastName
也会相应地被更新。
八、侦听器(尽量少用)
- Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用
watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的watch
回调。
<div id="demo">{{ fullName }}</div>
// 使用watch
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
// 使用computed
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
通过比较,计算属性比watch好很多。但是当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
九、Class 与 Style 绑定
Class绑定
-v-bind:class
指令可以与普通的 class attribute 共存。当有如下模板:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data: {
isActive: true,
hasError: false
}
// 渲染为:
<div class="static active"></div>
- 我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
- 我们可以把一个数组传给
v-bind:class
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
- 用于组件上:当在一个自定义组件上使用 class property 时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
<my-component class="baz boo"></my-component>
// 渲染为:
<p class="foo bar baz boo">Hi</p>
Style绑定
v-bind:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JS对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
v-bind:style
的数组语法可以将多个样式对象应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>
- 从 2.3.0 起你可以为
style
绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染
display: flex
。