Vue.js计算属性和样式

可以通过这个属性来计算得出另外一个值,并且当原属性改变它也会相应改变

通篇读下来有两个属性:computed和watch 。一个方法:methods

  1. 计算属性:基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。这就意味着只要 message 没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
  2. 方法:每当重新渲染的时候,method 调用总会执行函数。
  3. 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>

自己要注意的一些地方:

  1. 放在methods属性下面的方法调用要加():如reserveMessage()
  2. 放在computed对象下的属性具有缓存,调用直接调用属性:reversedMessage
  3. computed还可以设置
  4. watch观并察适合监控某些mustache的变化,并对其操作。

演示

发现样式这一段很少内容,就一起加在这里了。

  1. 样式class可以通过一个表达式、对象、计算属性或者数组来添加
  2. 内嵌样式可以通过一个对象或者数组对象来添加
  3. 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',
            }
        }
    }
})

演示


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流