可以通过这个属性来计算得出另外一个值,并且当原属性改变它也会相应改变
通篇读下来有两个属性:computed和watch 。一个方法:methods
- 计算属性:基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。这就意味着只要 message 没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
- 方法:每当重新渲染的时候,method 调用总会执行函数。
- watch:观察某个mustache改变时,作出相应变化
<div id="app"> <p v-once>v-once这里只会更新一次:{{message}}</p> <p>下面输入会直接同步这里:{{message}}</p> v-modle:双向更新:<input type="text" v-model="message"> <p>反转message计算属性computed:{{reversedMessage}}</p> <p>使用method中定义一个函数:{{ reverseMessage() }}</p> <p>使用$watch方法fistName:<input v-model="firstName"></p> <p>使用$watch方法lastName:<input type="text" v-model="lastName"/> <p>这里是fullName:{{fullName}},注意观察变化</p> <p>使用method中定义一个函数getName:{{ getName() }}</p> <p>使用computed计算getName:{{ computedName }}</p> </div>
var vm = new Vue({ el:'#app', data:{ message:'qdkfweb.cn', firstName:'Baojian', lastName:'Cai', fullName:'Baojian Cai' }, //计算属性 //计算属性是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。这就意味着只要 message 没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。 computed:{ reversedMessage:function(){ var msg = this.message; var msg2 = msg; return msg2.split('').reverse().join(''); }, computedName:function(){ return this.firstName + ' ' + this.lastName; } }, //方法函数, //每当重新渲染的时候,method 调用总会执行函数。 methods:{ reverseMessage:function(){ return this.message.split('').reverse().join(''); }, getName:function(){ return this.firstName + ' ' + this.lastName; } }, //$watch方法 watch:{ //观察fistName发生变化,fullName相应变化 firstName:function(newVal,oldVal){ console.log('newVal:'+newVal, 'oldVal:'+oldVal); this.fullName= newVal + ' ' + this.lastName; }, //观察lastName是否发生改变,fullName相应变化 lastName:function(newVal,oldVal){ console.log('newVal:'+newVal, 'oldVal:'+oldVal); this.fullName = this.firstName + ' ' + newVal; } } })
另外computed还提供一个设置的方法
computed: { fullName: { set: function(newVal) { var names = newVal.split(' '); this.firstName = names[0]; this.lastName = names[names.length - 1]; } }, } vm.fullName = 'Jack Cai';
随着fullName的改变,同时设置了其它值。
下面是一个比较完整的例子应用。
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div> <!-- Since there is already a rich ecosystem of ajax libraries --> <!-- and collections of general-purpose utility methods, Vue core --> <!-- is able to remain small by not reinventing them. This also --> <!-- gives you the freedom to just use what you're familiar with. --> <script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js"></script> <script src="https://unpkg.com/lodash@4.13.1/lodash.min.js"></script> <script> 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) { this.answer = 'Waiting for you to stop typing...' this.getAnswer() } }, methods: { // _.debounce 是一个通过 lodash 限制操作频率的函数。 // 在这个例子中,我们希望限制访问yesno.wtf/api的频率 // ajax请求直到用户输入完毕才会发出 // 学习更多关于 _.debounce function (and its cousin // _.throttle), 参考: https://lodash.com/docs#debounce getAnswer: _.debounce( function () { var vm = this if (this.question.indexOf('?') === -1) { vm.answer = 'Questions usually contain a question mark. ;-)' return } vm.answer = 'Thinking...' 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>
自己要注意的一些地方:
- 放在methods属性下面的方法调用要加():如reserveMessage()
- 放在computed对象下的属性具有缓存,调用直接调用属性:reversedMessage
- computed还可以设置
- watch观并察适合监控某些mustache的变化,并对其操作。
发现样式这一段很少内容,就一起加在这里了。
- 样式class可以通过一个表达式、对象、计算属性或者数组来添加
- 内嵌样式可以通过一个对象或者数组对象来添加
- css3前缀会自动补全,不需要关注各个浏览器不同的浏览器前缀。
<div id="app-1"> <div v-bind:class="{'active':isActive,'text-danger':hasError}">测试这里的class表达式</div> <div v-bind:class="classObject">测试这里的class Object</div> <div v-bind:class="classComputed">测试用computed属性来得到class</div> <div v-bind:class="[activeClass, errorClass]">这里用数组表示class</div> <div v-bind:class="[isActive ? activeClass : '', errorClass]">三元表达式</div> <div v-bind:class="[{active:isActive}, errorClass]">数组里加对象</div> <div v-bind:style="{color:activeColor, fontSize:fontSize + 'px' }">内嵌样式</div> <div v-bind:style="styleObject">内嵌对象样式</div> <div v-bind:style="[baseStyle, layoutStyle]">内嵌数组对象样式</div> </div>
var app1 = new Vue({ el: "#app-1", data: { activeColor: 'blue', fontSize: 12, styleObject: { color: 'red', fontSize: '12px' }, baseStyle: { color: 'red', fontSize: '12px' }, layoutStyle: { 'font-size': '19px', 'transform': 'rotate(30deg)', 'transition': 'transform .3 ease', }, activeClass: 'active', errorClass: 'text-danger', isActive: true, hasError: false, classObject: { 'active': true, 'text-danger': true } }, computed: { classComputed: function() { return { 'active': this.isActive && !this.hasError, 'text-danger': this.hasError && this.hasError.type === 'fatal', } } } })