VUE Element-ui父组件与子组件相互调用

1. 父组件代码

<template>
    <div>
        <!-- 栏目树状结构 -->
        <el-container>

        <el-aside width="200px">
        <el-tree :data="columnTree" :props="defaultProps" node-key="id" show-checkbox ref="tree" accordion default-expand-all @node-click="handleNodeClick"></el-tree>
        </el-aside>

        <el-main>
        <!-- 搜索条件 -->
        <div>
	  <!-- 引入子组件 -->
	  <!-- ref='edit' 定义子组件名称,用于父组件调用子组件的方法 -->
	  <!-- @reload="getColumnTree" 用于子组件调用父组件的方法 reload是子组件调用函数名,getColumnTree是实际被调用的函数 -->
          <edit ref='edit' @reload="getColumnTree"></edit> 
        </div>
        </el-main>
        </el-container>
        <!-- 博客的展示 -->
    </div>
</template>
<script>
// 引入marked
// import marked from 'marked'

import $edit from '@/components/communal/markdown/columnEdit.vue'

import 'mavon-editor/dist/css/index.css'
export default {
  components: {
    'edit': $edit // 引入子组件
  },
  created () {
    // 获取博客栏目的树状数据
    this.getColumnTree()
  },
  data () {
    return {
      columnTree: [
      ],
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    }
  },
  methods: {
    handleNodeClick (data) {
      this.$refs.edit.changeParentAndSort(data) // 调用子组件的changeParentAndSort 方法
    },
    /**
     * 获取栏目信息
     */
    getColumnTree () {
      const _this = this
      _this.$column.tree(nul```l, function (data) {
        _this.columnTree = data.list
      })
    }
  }
}

说明
ref='edit':ref是固定的,用于调用子组件,edit是子组件的别名
@reload="getColumnTree" :用于子组件调用父组件的方法,reload是子组件调用函数名(可自定义),getColumnTree是实际被调用的父组件函数,可定义多个
this.$refs.edit.changeParentAndSort(data):在js中调用子组件的函数,或是修改子组件的数据

2. 子组件代码

<template>
  <div>
    <el-form ref="column" :model="column" label-width="80px">
      <el-form-item label="栏目名称">
        <el-input v-model="column.name"></el-input>
      </el-form-item>
      <el-form-item label="上级栏目">
        <el-select v-model="column.parentName" collapse-tags>
          <el-option :value="column.parentName" style="height: auto">
            <el-tree
              :data="columnTree"
              default-expand-all
              show-checkbox
              check-strictly
              node-key="id"
              ref="tree"
              highlight-current
              :props="defaultProps"
              @check-change="handleCheckChange"
            ></el-tree>
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="排序">
        <el-select v-model="column.sort" filterable placeholder="选择在哪个栏目之前">
          <el-option
            v-for="sort in sorts"
            :key="sort.id"
            :label="sort.name"
            :value="sort.sort">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item>

        <el-button type="primary" @click="onSubmit">保存</el-button>
        <el-button>取消</el-button>
        <el-button type="danger" @click="clear">清空</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  created () {
    this.getColumnTree()
  },
  data () {
    return {
      column: {
        name: '',
        level: 1, // 层级,父级 +1
        parentId: '0', // 父级id
        parentName: '根目录',
        sort: 2 // 获取指定的,后台重新排序
      },
      sortNum: [], // 先保存,再展示?
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      columnTree: [
        {
          id: 0,
          name: '根目录',
          children: []
        }
      ], // 用于选择父级
      sorts: [] // 排序使用
    }
  },
  methods: {
    handleCheckChange (data, checked, node) {
      let res = this.$refs.tree.getCheckedNodes(false, true) // true,1. 是否只是叶子节点 2.选择的时候不包含父节点)
      if (checked) {
        this.$refs.tree.setCheckedNodes([data])
      }
      res.forEach(item => {
        this.changeParentAndSort(data)
      })
    },
    changeParentAndSort (data) {
      this.column.parentId = data.id
      this.column.parentName = data.name
      this.column.level = data.level + 1
      // 排序相关的更新
      this.sorts = data.children
      this.column.sort = 1
    },
    getColumnTree () {
      const _this = this
      _this.$column.tree(null, function (data) {
        _this.columnTree[0].children = data.list
        console.log(data)
        // 排序默认使用第一级
        _this.sorts = data.list
      })
    },
    onSubmit () {
      const _this = this
      if (_this.column.id) {
        _this.$column.update(_this.column, function (data) {
          _this.$message({
            message: '编辑成功',
            type: 'success'
          })
          _this.clear()
          // 回调父组件,刷新数据
          // _this.$emit.childCallback()
          _this.$emit('reload')
        })
      } else {
        _this.$column.save(_this.column, function (data) {
          _this.$message({
            message: '添加成功',
            type: 'success'
          })
          _this.clear()
          // 回调父组件,刷新数据
          _this.$emit('reload')
        })
      }
    },
    clear () {
      Object.assign(this.$data, this.$options.data()) // 重置数据?
    }
  }
}
</script>

3. 父组件调用子组件函数或修改子组件数据

  • 1.引入子组件并定义子组件
  • 2.在页面使用子组件
  • 3.调用子组件的方法或修改数据
<template>
<!-- 在页面使用子组件 -->
<edit ref='edit' @reload="getColumnTree"></edit>
</template>
<script>
// 1.引入子组件
import $edit from '@/components/communal/markdown/columnEdit.vue'
export default {
  components: {
    'edit': $edit // 1.定义子组件
  },
  methods: {
    handleNodeClick (data) {
      // 3.调用子组件的函数
      this.$refs.edit.changeParentAndSort(data)
      // 3.修改子组件的名为abc数据
      this.$refs.edit.abc = 1
    }
  }
}
</script>

4. 子组件回调父组件方法

4.1 父组件定义可被子组件回调的方法

在子组件标签里添加对应的@xx=父组件函数的代码


4.2 子组件回调

<script>
export default {
  methods: {
    onSubmit () {
      _this.$emit('reload')
    }
  }
}
script>

你可能感兴趣的:(前端)