账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    vue 父子组件传数组, computed与watch都无法触发
    • 东京的樱花在巴黎飘落2020-01-01 00:00
    47
    0

    问题描述

    1. 分类树状表格, 异步加载数据; 子组件向父组件发送事件, 父组件中请求数据并推入相应的数组对象中, 会出现无法触发子组件计算属性的情况

    问题出现的环境背景及自己尝试过哪些方法

    1. 创建三级分类的时候无法触发computed, watch无法监听到,试着用JSON.parase(JSON.stringify())深度拷贝,创建三级分类,computed时可以触发,四级分类可以创建,切换打开其他的一级分类,二级,三级都可以正常展开,四级分类可以加载到,但是无法触发Computed;watch也无法监听到

    相关代码

    // 请把代码文本粘贴到下方(请勿用图片代替代码)
    子组件:

    computed: {
        // 格式化数据源
        formatData: function () {
          let tmp
          if (!Array.isArray(this.data)) {
            tmp = [this.data]
          } else {
            tmp = this.data
          }
          const func = this.evalFunc || treeToArray
          const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]
          return func.apply(null, args)
        }
      },
    watch: {
        'data': {
          handler: function (newValue, oldValue) {
            console.log(newValue)
          },
          deep: true
        }
      },
    methods: {
        // 切换下级是否展开
        toggleExpanded: function (trIndex, row) {
          if (row.children === undefined || row.children.length === 0) { // 是否异步请求数据
            this.$emit('tree-load', row)
            this.timer = setInterval(() => {
              if (this.isLoading) {
                const record = this.formatData[trIndex]
                record._expanded = !record._expanded
                clearInterval(this.timer)
              }
            }, 100)
          } else {
            const record = this.formatData[trIndex]
            record._expanded = !record._expanded
          }
          // this.selectedId = trIndex
        },
    }

    父组件:

    methods: {
        onTreeLoad (row) {
          this.isLoading = false
          this.getSubClassifyList(row)
        },
        getSubClassifyList (params) {
          this.httpGet(apiUrl.category + params.code).then(res => {
            if (res.code === 0) {
              if (res.data) {
                // console.log(this.classifyList)
                this.insertArray(this.classifyList, res.data, params.code)
                // console.log(this.classifyList)
                this.classifyList = JSON.parse(JSON.stringify(this.classifyList))
              }
            }
            this.errorMessage(res)
          }).catch((err) => {
            this.errorCode(err)
          })
        },
        insertArray (Array, data, code) {
          let arr = Array
          for (let i = 0; i < arr.length; i++) {
            if (arr[i].children && arr[i].children.length > 0) {
              this.insertArray(arr[i].children, data, code)
            } else {
              if (arr[i].code === code) {
                arr[i]['children'] = JSON.parse(JSON.stringify(data))
                this.$set(arr, i, arr[i])
                this.isLoading = true
              }
            }
          }
        }
    }
    

    你期待的结果是什么?实际看到的错误信息又是什么?

    1. 现在可以创建正常的四级分类,
    
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 到站、请上车 普通会员 1楼

      在Vue中,父组件通过传递数组作为属性或者数据源的方式,子组件可以获取到这个数组的内容。如果子组件没有监听到这个数组的更改,那么在computed和watch属性中,无法触发更新或更新请求。

      在Vue中,父组件和子组件可以通过props属性来传递数组。在父组件中,可以通过props的getter或setter函数来获取或设置数组的值:

      ```html

      ```

      在这个例子中,data是子组件的数据源,子组件可以通过this.data获取到这个数组的值。在ChildComponent.vue中,我们定义了一个名为@data的 computed属性,并通过@data=[]来初始化它,表示这是一个数组数组。当子组件的getData方法被调用时,@data属性的值将被赋值为当前的数组内容。

      在子组件的watch方法中,如果子组件的@data属性发生变化,Vue会自动触发一个watch钩子。watch钩子会监听@data属性的更新,并在数据发生变化时触发updateupdateEffect方法。

      以下是一个简单的示例:

      ```html

      ```

      在这个例子中,当子组件的data属性发生变化时,@data属性的值会被设置为当前的数组内容。在ChildComponent.vue中,我们定义了一个名为@data的watch钩子,这个钩子会监听@data属性的更新,并在数据发生变化时触发update方法。在这个方法中,我们打印出子组件的data数组。

      注意,deep参数是一个布尔值,如果设置为true,那么watch钩子会监听到@data属性的深度变化,即子组件的@data属性可能包含了父组件的子组件。这通常在需要子组件完全依赖于父组件的情况下使用。如果子组件不需要完全依赖于父组件,或者希望保持子组件的独立性,那么应该将deep参数设置为false

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部