vue computed watch区别和应用

vue computed watch区别

1:computed 是计算一个新的属性(不能监听data已有属性,,会报错),并将该属性挂载到 vm(Vue 实例)上,而 watch 是监听已经存在且已挂载到 vm上的数据,所以用 watch 同样可以监听 computed 计算属性的变化(其它还有 data props)

2:computed 本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值,而watch 则是当数据发生变化便会调用执行函数

3:从使用场景上说,computed 适用一个数据被多个数据影响,而 watch 适用一个数据影响多个数据;

vue computed watch应用

  1. 常应用:
{{fullName}}
			new Vue({
		    data: {
		        firstName: 'Xiao',
		        lastName: 'Ming'
		    },
		    computed: {
		        fullName: function () {
		            return this.firstName + ' ' + this.lastName
		        }
		    }
		})
	
	注意:fullName是新的属
  1. 解决vue 子组件改变父组件的值报错:
父组件:

<level-select :level="form.level" @change="changeValue" />
<script>
import LevelSelect from '@/components/LevelSelect'

export default {
  components: { LevelSelect },
  data() {
    return {
      form: {
        level: 1
      }
    }
  },
  methods: {
    changeValue(val) {
      this.form.level = val
    }
  }
}
</script>
子组件:

<template>
  <div>
    <label style="display: inherit;">权限</label>
    <el-select v-model="levelSelected" placeholder="请选择" style="width:100%" size="medium">
      <el-option
        v-for="item in levels"
        :key="item.level"
        :label="item.name"
        :value="item.level"
      />
    </el-select>
  </div>
</template>

<script>
export default {
  props: { 
    level: { 
      type: Number,
      default: 0 
    }
  },
  data() {
    return {
      levels: [
        { name: '公开', level: 0 },
        { name: '会员可见', level: 1 },
        { name: '需要密码', level: 2 },
      ]
    }
  },
  computed: {
    levelSelected: {
      get() {
        return this.level
      },
      set(val) {
        this.$emit('change', val)
      }
    }
  } 
</script>

<style>

</style>

3:解决父子组件传值,子组件未接受到值:
问题:当父组件传值给子组件echarts时,发现子组件获取的props为空,刚开始以为是钩子函数放错了地方,后来发现从mounted和created都不行。当在父组件data定义传递的数据的时候子组件显示正常

原因:父组件还没渲染完,子组件已经更新.

//父组件
   <div class="chart-wrapper">
    <pie-chart v-if="flag" :pie-data="piedata"></pie-chart>
  </div>
  ...
  import {getPie} from '@/api/status'
  export default {
  name: 'device',
  data() {
    return {
      flag:false,
      piedata:{},
      ...
  },
  created(){
    this.init()
  },
 methods:{
   init(){  
        getPie().then(this.getInfoSucc)
   },
   getInfoSucc(res){
      res = res.data;
       if(res.code ==0){
         const values = res.values; 
         this.piedata = values.piedata; 
         this.flag = true
       }
     }
//子组件
<template>
  <div :class="className" :style="{height:height,width:width}"></div>
</template>
 
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
 
export default {
  props: {
    pieData: {
      type: Object
    },
    msg: {
      type:Number
    },
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '300px'
    }
  },
  data() {
    return {
      chart: null
    }
  },
   watch: {
     piedata: {
       deep: true,
       handler(val) {
         console.log(val)
         this.setOptions(val)
       }
     }
  },
  mounted() {
    console.log("pieData:"+JSON.stringify(this.pieData))
    this.initChart()
    this.__resizeHanlder = debounce(() => {
      if (this.chart) {
        this.chart.resize()
      }
    }, 100)
    window.addEventListener('resize', this.__resizeHanlder)
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    window.removeEventListener('resize', this.__resizeHanlder)
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    setOptions({ text, arrtype, arrdata } = {}) { 
      this.chart.setOption({
        title: {
          text: text
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
          left: 'center',
          bottom: '10',
          data: arrtype
        },
        calculable: true,
        series: [
          {
            name: '',
            type: 'pie',
            roseType: 'radius',
            radius: [15, 95],
            center: ['50%', '42%'],
            data: arrdata,
            animationEasing: 'cubicInOut',
            animationDuration: 2600
          }
        ]
      })
    },
    initChart() {
      this.chart = echarts.init(this.$el, 'macarons')
      this.setOptions(this.pieData);
    }
  }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值