watch、computed和method的区别以及与props,data的加载顺序

  • computed

  • 当页面中有某些数据 依赖 其他数据 进行变动的时候,可以使用计算属性。

  • 需要注意的是,就算在 data中没有直接声明 出要计算的变量,也可以直接在computed中写入。

  • 计算属性默认只有getter,可以在需要的时候自己设定setter:

  • 使用场景:computed擅于处理:一个数据受多个数据影响

  • 即在这多个依赖数据中,任何一个改变都会导致 受影响的数据的改变

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]
      }
    }
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
  • watch
  • data中没有相应的属性的话,是不能watch
  • watch:类似于监听机制+事件机制:一个数据影响多个数据。
  • 适合监控场景,某【一个】变量改变时需要做什么操作;
  • 在数据变化的同时进行异步操作或者是比较大的开销,
  • watch为一个对象,键是需要观察的表达式,
    值是对应回调函数。值也可以是方法名,或者包含选项的对象。
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  },

vue组件props,methods,data,computed,watch的加载顺序

在这里插入图片描述

props - > methods - > data - > computed - > watch

父组件向子组件通过props传值,props是一个只读属性,
如果要改变props的值,需要在data中进行定义,
所以props在前,data在后
computed计算属性要使用data里面的数据,
所以data在前,computed在后

vue的props,data,computed的加载顺序的影响
1.因为加载顺序: props->methods->data->computed->watch

2.computed与watch只能作为变化监听,千万不能做初始化!!!

3.所有的init方法必须直接调用数据库或者直接this.$store.getters读取内存而不是通过computed去获取

<template> <div class="custom-tree-container"> <!-- 搜索框 --> <el-input v-if="showSearch" v-model="filterText" placeholder="输入关键字过滤" clearable class="tree-search" /> <!-- 树形组件 --> <el-tree ref="treeRef" :data="processedData" :props="mergedProps" :node-key="nodeKey" :lazy="lazy" :load="loadNode" :show-checkbox="showCheckbox" :highlight-current="highlightCurrent" :default-expand-all="defaultExpandAll" :expand-on-click-node="expandOnClickNode" :filter-node-method="filterNode" @node-click="handleNodeClick" @check-change="handleCheckChange" > <!-- 自定义节点内容 --> <template #default="{ node, data }"> <span class="custom-node"> <slot name="prefix-icon" :node="node"> <el-icon v-if="showDefaultIcon"><FolderOpened /></el-icon> </slot> <span class="node-label">{{ node.label }}</span> <slot name="suffix-content" :node="node" :data="data" /> </span> </template> </el-tree> </div> </template> <script setup> import { ref, computed, watch } from 'vue' import { FolderOpened } from '@element-plus/icons-vue' const props = defineProps({ // 原始数据 data: { type: Array, required: true }, // 树形配置项 treeProps: { type: Object, default: () => ({ label: 'label', children: 'children', disabled: 'disabled', isLeaf: 'isLeaf' }) }, nodeKey: { type: String, default: 'id' }, showSearch: Boolean, showCheckbox: Boolean, showDefaultIcon: { type: Boolean, default: true }, highlightCurrent: { type: Boolean, default: true }, defaultExpandAll: Boolean, expandOnClickNode: Boolean, lazy: Boolean, loadFn: Function // 异步加载函数 }) const emit = defineEmits(['node-click', 'check-change', 'data-filtered']) const filterText = ref('') const treeRef = ref(null) // 合并默认配置自定义配置 const mergedProps = computed(() => ({ ...props.treeProps })) // 数据处理(可根据需要添加转换逻辑) const processedData = computed(() => { // 这里可以添加数据转换逻辑 return props.data }) // 过滤方法 const filterNode = (value, data) => { return data[mergedProps.value.label].includes(value) } // 节点点击事件 const handleNodeClick = (data, node) => { emit('node-click', { data, node }) } // 复选框变化事件 const handleCheckChange = (data, checked, indeterminate) => { emit('check-change', { data, checked, indeterminate }) } // 异步加载节点 const loadNode = async (node, resolve) => { // console.log(node); if (typeof props.loadFn === 'function') { console.log(props.loadFn); const children = await props.loadFn(node) console.log(children); // console.log(resolve); // console.log(resolve(children || [])); resolve(children || []) } } // 监听搜索过滤 watch(filterText, (val) => { treeRef.value?.filter(val) emit('data-filtered', val) }) // 暴露方法 defineExpose({ getCheckedNodes: () => treeRef.value?.getCheckedNodes(), setCheckedKeys: (keys) => treeRef.value?.setCheckedKeys(keys), filter: (value) => treeRef.value?.filter(value) }) </script> <style scoped> .custom-tree-container { padding: 10px; background: #fff; border-radius: 4px; } .tree-search { margin-bottom: 10px; } .custom-node { display: flex; align-items: center; padding: 5px 0; } .node-label { margin-left: 6px; } :deep(.el-tree-node__content) { height: 36px; } </style> 解析代码
最新发布
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值