赞
踩
父组件:当组件A中嵌套一个组件B时,组件A即为父组件
子组件:当组件A中嵌套一个组件B时,组件B即为子组件
兄弟组件:当组件C中嵌套了两个子组件,组件D和组件E;且组件D和组件E并不存在嵌套关系时,可以称组件D和组件E为兄弟组件
方式一:
父组件 EditCase.vue
<template> <AddAndEditForm :productList="productList" :moduleList="moduleList" :versionList="versionList" pageTitle="编辑用例" ref="addAndEditFormObj" @childCaseFormEdit="childCaseFormEdit"/> </template> <script> import AddAndEditForm from "./common/AddAndEditForm" export default { name: "EditCase", components: { AddAndEditForm }, data(){ return { visible: false, productName: '', modulePath: '', moduleId: -1, productList: [], moduleList: [], versionList: [], rowRecord: {}, stepTableData: [] } }, methods: { showDrawer() { // this.visible = true; console.log("编辑页面的rowRecord:"+JSON.stringify(this.rowRecord)) this.$refs.addAndEditFormObj.rowRecord = this.rowRecord; this.$refs.addAndEditFormObj.showDrawer(); //flag=1 代表添加 flag=2 代表更新/编辑 flag=3 代表添加 this.$refs.addAndEditFormObj.flag = 2; }, getProductListByCurrentProduct(){ var _this = this; this.axios .get('/api/manualcase/findAllProductName',{ params: { product_name: _this.productName} }) .then(function (response) { console.log("Product"+response.data) _this.productList = response.data; }); }, getModuleListByCurrentProduct() { var _this = this; this.axios .get('/api/manualcase/findAllModuleByProductNameAndModulesPath', { params: {product_name: _this.productName, modules_path: _this.modulePath} }) .then(function (response) { console.log("Module:"+response.data) _this.moduleList = response.data; }) }, getVersionListByCurrentProduct(){ var _this = this; this.axios .get('/api/manualcase/findAllVersionByProductName',{ params: { product_name: _this.productName} }) .then(function (response) { console.log(response.data) _this.versionList = response.data; }); }, getAllStepsByManualCaseId(){ console.log("diaoyong;") var _this = this; this.axios .get('/api/manualcase/findAllStepsOfOneCaseByManualCaseId',{ params: { manualcase_id: _this.rowRecord.id} }) .then(function (response) { console.log("用例步骤:"+JSON.stringify(response.data)) _this.stepTableData = response.data.data; _this.$refs.addAndEditFormObj.data = _this.stepTableData; }) }, childCaseFormEdit(flag){ console.log("编辑用例页") this.$emit('childCaseForm', flag) } } } </script> <style scoped> </style>
子组件 AddAndEditForm.vue
在子组件中使用props接收父组件传递的值,props中存在的变量无需再次在data中声明,可直接使用。使用方式:this.props中变量名。
props中变量与data中声明的变量区别:
原则上props中的变量只可读,不可更改(不可写);data中的变量可读可写。
<template> <a-drawer :title="pageTitle" :width="720" @close="onClose" :visible="visible" :wrapStyle="{height: 'calc(100% - 108px)',overflow: 'auto',paddingBottom: '108px'}" > <a-form id="components-form-demo-validate-other" :form="form" layout="vertical" hideRequiredMark v-bind="formItemLayout" @submit="handleSubmit" > <a-row :gutter="16"> <a-col :span="12"> <a-form-item label="所属产品" has-feedback> <a-select v-decorator="['productselect',{initialValue: productList[0], rules: [{ required: true, message: 'Please select product!' }] },]" placeholder="Please select a product" @change="handleSelectChange"> <a-select-option v-for="(item) in productList" :key="item" :value="item">{{ item }} </a-select-option> </a-select> </a-form-item> </a-col> <a-col :span="12"> <a-form-item label="所属模块" has-feedback> <a-select v-decorator="['moduleselect',{initialValue: moduleList[0], rules: [{ required: true, message: 'Please select module!' }] },]" placeholder="Please select a module" @change="handleSelectChange"> <a-select-option v-for="(item) in moduleList" :key="item" :value="item">{{ item }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="16"> <a-col :span="12"> <a-form-item label="版本号" has-feedback> <a-select v-decorator="['version',{initialValue: versionList[0], rules: [{ required: true, message: 'Please select version!' }] },]" placeholder="Please select a version" @change="handleSelectChange"> <a-select-option v-for="(item) in versionList" :key="item" :value="item">{{ item }} </a-select-option> </a-select> </a-form-item> </a-col> <a-col :span="12"> <a-form-item label="用例类型" has-feedback> <a-select v-decorator="['type',{initialValue: rowRecord.type, rules: [{ required: true, message: 'Please select case type!' }] },]" placeholder="Please select a case type" @change="handleSelectChange"> <a-select-option value="功能测试">功能测试</a-select-option> <a-select-option value="UI测试">UI测试</a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="16"> <a-col :span="12"> <a-form-item label="优先级" has-feedback> <a-select v-decorator="['priority',{initialValue: rowRecord.priority, rules: [{ required: true, message: 'Please select priority!' }] },]" placeholder="Please select priority" @change="handleSelectChange"> <a-select-option value="P1">P1</a-select-option> <a-select-option value="P2">P2</a-select-option> <a-select-option value="P3">P3</a-select-option> <a-select-option value="P4">P4</a-select-option> </a-select> </a-form-item> </a-col> <a-col :span="12"> <a-form-item label="自动化"> <a-switch checkedChildren="是" unCheckedChildren="否" v-decorator="['auto', {initialValue: auto, valuePropName: 'checked' }]"/> </a-form-item> </a-col> </a-row> <a-form-item label="前置条件"> <a-textarea :rows="4" v-decorator="['preCondition',{initialValue: rowRecord.preCondition, rules: [{ required: true, message: 'Please select your country!' }] },]"></a-textarea> </a-form-item> <a-form-item label="用例标题"> <a-textarea :rows="4" v-decorator="['title',{initialValue: rowRecord.title, rules: [{ required: true, message: 'Please select your country!' }] },]"></a-textarea> </a-form-item> <a-form-item label="用例步骤"> <div class="table-operations"> <a-button @click="handleAddOneStep">添加一行</a-button> <!-- <a-button>删除一行</a-button>--> </div> <a-table :columns="columns" :dataSource="data" bordered rowKey="number" v-decorator="['steps']"> <template slot="description" slot-scope="text, record"> <editable-cell :text="text" @change="onCellChange(record.number, 'description', $event)"/> </template> <template slot="expect" slot-scope="text, record"> <editable-cell :text="text" @change="onCellChange(record.number, 'expect', $event)"/> </template> <template slot="action" slot-scope="text, record"> <a-popconfirm v-if="data.length" title="Sure to delete?" @confirm="() => onDelete(record.number)"> <a href="javascript:;">Delete</a> </a-popconfirm> </template> </a-table> </a-form-item> <a-form-item :wrapper-col="{ span: 12}"> <a-button type="primary" html-type="submit"> Submit </a-button> </a-form-item> </a-form> </a-drawer> </template> <script> import AFormItem from "ant-design-vue/es/form/FormItem"; import ACol from "ant-design-vue/es/grid/Col"; import EditableCell from '../../table/EditableCell.vue'; var stepId = 0; const columns = [ { title: '编号', dataIndex: 'number', key: 'number', // slots: { title: 'customTitle' }, // scopedSlots: { customRender: 'name' }, }, { title: '步骤', dataIndex: 'description', key: 'description', scopedSlots: { customRender: 'description' }, }, { title: '预期', dataIndex: 'expect', key: 'expect', scopedSlots: { customRender: 'expect' }, }, { title: '操作', key: 'action', scopedSlots: { customRender: 'action' }, } ] export default { name: "AddAndEditForm", components: {ACol, AFormItem, EditableCell}, // 接受父组件的值 props: [ 'productList', 'moduleList', 'versionList', 'pageTitle' ], data: () => ({ visible: false, productName: '', modulePath: '', moduleId: -1, version: '', formItemLayout: { // labelCol: { span: 2 }, // wrapperCol: { span: 6 }, }, columns, stepId, data: [], flag: 1, auto: false, rowRecord: {} }), beforeCreate() { this.form = this.$form.createForm(this, {name: 'validate_other'}); }, methods: { showDrawer() { this.visible = true; // this.data = this.rowRecord.steps; console.log("stepdata:"+this.data) this.moduleId = this.rowRecord.module_id; console.log("record123:"+JSON.stringify(this.rowRecord),"auto: "+this.rowRecord.auto, " version:"+this.rowRecord.version) if(this.rowRecord.auto === "Y"){ this.auto = true; }else { this.auto = false; } this.version = this.rowRecord.version; }, onClose() { this.visible = false; }, onCellChange(key, dataIndex, value) { console.log("编辑单元格:key="+key, " dataIndex="+dataIndex, " value="+value) const data = [...this.data]; const target = data.find(item => item.number === key); console.log("编辑单元格: target:"+JSON.stringify(target)) if (target) { target[dataIndex] = value; console.log("修改后的编辑单元格:"+JSON.stringify(target)) this.data = data; } }, onDelete(key) { const data = [...this.data]; console.log("del before: "+JSON.stringify(this.data)) this.data = data.filter(item => { if(item.number !== key){ if(item.number > key){ item.number -= 1; } return item; } }); console.log("del after: "+JSON.stringify(this.data)) }, updateNewManualCaseAndStep(formData){ console.log("formData: "+JSON.stringify(formData)) var _this = this this.axios .post('/api/manualcase/updateManualCaseAndStep', formData) .then(function (response) { console.log(response.data) _this.$emit('childCaseFormEdit', true) }); }, insertNewManualCaseAndStep(formData){ var _this = this console.log("formData: "+JSON.stringify(formData)) this.axios .post('/api/manualcase/insertNewManualCaseAndStep', formData) .then(function (response) { console.log(response.data) _this.$emit('childCaseFormCopy', true) _this.$emit('childCaseFormAdd', true) }); }, handleAddOneStep(){ console.log("传递过来的data:"+this.data) this.data = this.data || []; this.stepId = this.data.length + 1; var oneStep = {"number":this.stepId, "type": "step", "manualcase_id": 0, "description":" ", "expect":" ", "version":this.rowRecord.version}; this.data.push(oneStep) }, handleSubmit(e) { var _this = this; e.preventDefault(); this.form.validateFields((err, values) => { console.log("提交表单中的值:"+JSON.stringify(values)) if (!err) { console.log('Received values of form: ', values); console.log("_this.moduleID: "+_this.moduleId); values['module_id'] = _this.moduleId; values['id'] = _this.rowRecord.id; values['creater'] = "孙东平" if(values.auto){ values.auto = "Y" }else { values.auto = "N" } values['steps'] = _this.data; // _this.insertNewManualCaseAndStep(values) if(_this.flag === 2){ _this.updateNewManualCaseAndStep(values); }else { _this.insertNewManualCaseAndStep(values); } _this.onClose(); } }); }, normFile(e) { console.log('Upload event:', e); if (Array.isArray(e)) { return e; } return e && e.fileList; }, handleSelectChange(value) { console.log("下拉选择框change:" + value); if(value.indexOf('/') > -1){ console.log("用例模块的下拉列表change:" + value); }else if(value.indexOf('.') > -1){ console.log("版本号的下拉列表change:"+value) this.version = value; } }, }, } </script> <style scoped> #components-form-demo-validate-other .dropbox { height: 180px; line-height: 1.5; } </style>
方式二:
使用ref和$refs,父组件和子组件代码同方式一。其中,addAndEditFormObj代表自定义的子组件对象(名称随意);
<template>
<AddAndEditForm
:productList="productList" :moduleList="moduleList" :versionList="versionList" pageTitle="编辑用例"
ref="addAndEditFormObj"
@childCaseFormEdit="childCaseFormEdit"/>
</template>
接下来,还是在父组件中使用$refs;
showDrawer() {
console.log("编辑页面rowRecord:"+JSON.stringify(this.rowRecord))
this.$refs.addAndEditFormObj.rowRecord = this.rowRecord;
this.$refs.addAndEditFormObj.showDrawer();
//flag=1 代表添加 flag=2 代表更新/编辑 flag=3 代表添加
this.$refs.addAndEditFormObj.flag = 2;
},
父组件 同上(截取代码片段)
<template>
<AddAndEditForm :productList="productList" :moduleList="moduleList" :versionList="versionList" pageTitle="编辑用例" ref="addAndEditFormObj" @childCaseFormEdit="childCaseFormEdit"/>
</template>
##methods中自定义一个监听事件的方法,方法名称同子组件中的@childCaseFormEdit="childCaseFormEdit"。
##注意:=前后的名称必须一致
childCaseFormEdit(flag)
{
console.log("编辑用例页")
}
子组件 同上(截取代码片段)
在子组件需要向父组件传递值的位置使用this.$emit(‘方法名’,参数)
##methods中的方法
updateNewManualCaseAndStep(formData){
console.log("formData: "+JSON.stringify(formData))
var _this = this
this.axios
.post('/api/manualcase/updateManualCaseAndStep', formData)
.then(function (response) {
console.log(response.data)
_this.$emit('childCaseFormEdit', true)
});
},
非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
公共bus.js
//bus.js
import Vue from 'vue'
export default new Vue()
组件A: child1.vue
<template> <div> A组件: <span>{{elementValue}}</span> <input type="button" value="点击触发" @click="elementByValue"> </div> </template> <script> // 引入公共的bug,来做为中间传达的工具 import Bus from '../bus/bus.js' export default { name: "child1", data () { return { elementValue: 4 } }, methods: { elementByValue: function () { //重点代码:A组件将值传给B组件 Bus.$emit('val', this.elementValue) } } } </script> <style scoped> </style>
B组件:child2.vue
<template> <div> B组件: <input type="button" value="点击触发" @click="getData"> <span>{{name}}</span> </div> </template> <script> import Bus from './bus.js' export default { data () { return { name: 0 } }, mounted: function () { var vm = this // 用$on事件来接收A组件传给B组件的参数 Bus.$on('val', (data) => { console.log(data) vm.name = data }) }, methods: { getData: function () { this.name++ } } } </script>
参考链接:https://blog.csdn.net/lander_xiong/article/details/79018737
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。