<div id="example">
{{message.split('').reverse().join('')}}
div>
在这里,模版不再是简单的声明式逻辑
对于任何复杂逻辑,都应当使用计算属性
<div id="example">
<p>Original message:"{{message}}"p>
<p>Computed reversed message:"{{reversedMessage}}"p>
div>
var vm = new Vue({
el:"#example",
data:{
message:"Hello"
},
computed:{
//计算属性的getter
reverseMessage:function(){
//'this'指向VM实例
return this.message.split('').reverse.join('')
}
}
});
这里我们声明了一个计算属性 ++reversedMessage++。我们提供的函数将作用属性++vm.reversedMessage++的++getter++函数
console.log(vm.reverseMessage) //=>"olleH"
vm.message = "Goodbye"
console.log(vm.reversedMessage) //=>"eybdoG"
注:vm.reversedMessage的值始终取决于vm.message
可以通过在表达式中调用方法来达到同样的效果:
Reversed message:"{{reversedMessage()}}"
//在组件中
methods:{
reversedMessage:function(){
return this.message.split('').reverse().join('')
}
}
可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
例:下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:
computed:{
now:function(){
return Date.now()
}
}
每当触发重新渲染时,调用方法将总会再次执行函数。
侦听属性:来观察和响应 Vue 实例上的数据变动。
当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。
"demo">{{fullName}}
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.flrstName + ' ' + val
},
}
});
将它与计算属性的版本进行比较:
var vm = new Vue({
el:'#demo',
data:{
firstName:'foo',
lastName:'Bar'
},
computed:{
fullName:function(){
return this.firstName + ' ' + this.lastName
}
}
});
现在再运行vm.fullName = “John Doe” 时,setter会被调用,vm.firstName和vm.lastName也会相应的被更新
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
例:
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
p>
<p>{{answer}}p>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js">script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js">script>
<script>
var watchExampleVM = new Vue({
el:'#watch-example',
data:{
question:'',
answer:'123abc'
},
watch:{
//如果 `question` 发生改变,这个函数就运行
question:function(newQuestion,oldQuestion){
this.answer = "456efg",
this.getAnswer()
}
},
methods:{
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
getAnswer: _.debounce(
function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
},
// 这是我们为判定用户停止输入等待的毫秒数
500
)
}
});
script>
结果:
Ask a yes/no question:
I cannot give you an answer until you ask a question!
在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
除了 watch 选项之外,您还可以使用命令式的 vm.$watch API。
<html>
<head>
<meta charset="utf-8" />
<title>title>
head>
<body>
<div id="app1">
{{ message.split('').reverse().join("") }}
div>
<div id="app2">
<p>原始字符串:{{message}}p>
<p>计算后反转字符串:{{reversedMessage}}p>
div>
<div id="app3">
<p>原始字符串 :{{message}}p>
<p>计算后反转字符串:{{reversedMessage}}p>
<p>使用方法后反转字符串:{{reversedMessage2()}}p>
div>
<div id="app4">
<p>{{site}}p>
div>
<div id="computed_props">
千米:<input type="text" v-model="kilometers">
米:<input type="text" v-model="meters">
div>
<p id="info">p>
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
p>
<p>{{ answer }}p>
div>
body>
html>
<script src="https://cdn.jsdelivr.net/npm/vue">script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js">script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js">script>
<script type="text/javascript">
new Vue({
el:"#app1",
data:{
message:'Runoob!'
}
});
new Vue({
el:'#app2',
data:{
message:'Runoob!'
},
//计算属性
computed:{
//计算属性的getter
reversedMessage:function(){
//this指向Vm实例
return this.message.split('').reverse().join("")
}
}
});
new Vue({
el:'#app3',
data:{
message:'Runoob!'
},
computed:{
reversedMessage:function(){
return this.message.split("").reverse().join('')
}
},
methods:{
reversedMessage2:function(){
return this.message.split('').reverse().join('')
}
}
});
var vm = new Vue({
el:'#app4',
data:{
name:"Google",
url:"http://www.google.com"
},
computed:{
site:{
//getter
get:function(){
return this.name + " " + this.url
},
//setter
set:function(newValue){
var names = newValue.split(' ');
this.name = name[0];
this.url = names[names.length - 1]
}
}
}
});
// //调用setter,vm.name 和vm.url 也会被对应更新
// vm.site = '菜鸟教程 http://www.runoob.com';
// document.write('name:' + vm.name);
// document.write('
');
// document.write('url:'+vm.url);
// var vm = new Vue({
// el:'#computed_props',
// data:{
// kilometers:0,
// meters:0
// },
// methods:{},
// computed:{},
// watch:{
// kilometers:function(val){
// this.kilometers = val;
// this.meters = val * 1000;
// },
// meters:function(val){
// this.kilometers= val/ 1000;
// this.meters = val;
// }
// }
// });
// //$watch是一个实例方法
// vm.$watch('kilometers',function(newValue,oldValue){
// //这个回调函数将在vm.kilometers改变后调用
// document.getElementById('info').innerHTML = '修改前值为:' + oldValue +"修改后的值:" + newValue;
// })
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.getAnswer()
}
},
methods: {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
getAnswer: _.debounce(
function () {
//indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
},
// 这是我们为判定用户停止输入等待的毫秒数
500
)
}
})
script>