前一节已经讲过vuex如何实现优惠券的赠删改,本章就不再赘述了。如需查看请回到上一节!
1.直接利用element-ui表格布局搭建问卷详情页面
这里与优惠券页面不同的是:点击问卷名称可以进去详情页面,与删除问卷操作在store.js中进行封装。
<template>
<div class="wrapper">
<header>
<el-button size="small"
icon="el-icon-circle-plus-outline"
@click="$router.push('/questionnaire/handle')">
新增
</el-button>
</header>
<el-table :data="questData">
<el-table-column label="问卷名称">
<template slot-scope="scope">
<el-button type="text" @click="cellClick(scope.$index)">
{{scope.row.name}}
</el-button>
</template>
</el-table-column>
<el-table-column prop="value" label="题目总数"></el-table-column>
<el-table-column prop="date" label="创建时间"></el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.$index)" type="text" size="small">修改</el-button>
<el-button @click="deleteClick(scope.$index)" type="text" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
computed:{
questData() {
return this.$store.state.questData
}
},
methods:{
handleClick(row) {
this.$router.push({path: '/questionnaire/handle', query: {index: row}});
},
deleteClick(row) {
this.$store.commit('setData', {
type: 'delete',
class: 'questData',
index: row
})
},
cellClick(row) {
this.$router.push({path: '/questionnaire/details', query: {index: row}});
}
},
}
</script>
2.store.js问卷改动,setData()函数中data参数中
type:为对数据具体操作类型(add增,handle改,delete删)
class:为需要操作的数组(couponData,questDat)
index: 要对数组中第几个元素进行操作
data: 新增的数据或者修改好的数据
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
couponData: [
{
name: '中秋浓情购',
value: 100,
date1: '2018-9-20',
date2: '14:20'
},
{
name: '国庆大优惠',
value: 200,
date1: '2018-9-25',
date2: '14:20'
},
{
name: '双11购物狂欢',
value: 1000,
date1: '2018-11-11',
date2: '14:20'
},
],
questData: [
{
name: '如何有效保持身材',
value: 3,
date: '2018-11-1',
questList: [
{
name: '锻炼方式',
type: 2,
answerList: []
}
]
}
]
},
mutations: {
setData(state, data) {
switch (data.type) {
case 'add':
state[data.class].push(data.data)
break;
case 'handle':
state[data.class].splice(data.index, 1, data.data);
break;
case 'delete':
state[data.class].splice(data.index, 1)
default:
console.log('此函数未被定义 !')
break;
}
}
}
})
3.新增问卷页面(利用父子组件传值)
最终页面显示如下,我们需要添加选项封装成一个组件
1)先实现添加选项子组件QuestionnaireAnswer.vue
<template>
<el-form :model="ruleForm" ref="ruleFormChild" label-width="100px" class="demo-ruleFrom">
<div class="form-add">
<div class="answer-title">题目{{index + 1}}</div>
<el-form-item label="问题名称" style="width:310px" prop="name"
:rules="[{ required: true, message: '请输入题目名称', trigger: 'blur' }]" >
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item class="from-inline" label="答案方式">
<el-select v-model="ruleForm.type" placeholder="请选择答案方式">
<el-option label="单选" value="1"></el-option>
<el-option label="多选" value="2"></el-option>
<el-option label="问答" value="3"></el-option>
</el-select>
</el-form-item>
<el-button class="detal-button" type="primary" size="small" icon="el-icon-delete" @click="deleteAnswer">删除</el-button>
</div>
</el-form>
</template>
<script>
export default {
props: {
ruleForm: Object,
index: Number
},
methods:{
deleteAnswer() {
this.$emit("index", this.index)
},
},
}
</script>
当点击删除按钮时,我们需要告诉父级组件。幸好 Vue 实例提供了一个自定义事件的系统来解决这个问题。我们可以调用内建的 $emit
方法并传入事件的名字,来向父级组件触发一个事件:
this.$emit("index", this.index)
然后我们可以用 v-on
在在父组件中上监听这个事件,就像监听一个原生 DOM 事件一样:
<app-answer ... @index="deleteFrom"></app-answer>
父组件QuestionnaireHandle.vue完整代码如下:
<template>
<div class="wrapper">
<div class="questHandle">
<header>
<el-form :model="ruleForm" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<div class="form-title">{{titText}}</div>
<el-form-item class="inputWidth" label="问卷名称" prop="name"
:rules="[{ required: true, message: '请输入问卷名称', trigger: 'blur' }]">
<el-input v-model="ruleForm.name"></el-input>
<span class="el-input-msg">(不能超过20个字)</span>
</el-form-item>
</el-form>
</header>
<div class="main">
<app-answer v-for="(item,index) in ruleFormChild" :key="index" :index="index" :ruleForm="item" @index="deleteFrom"></app-answer>
<el-button icon="el-icon-circle-plus-outline" @click="addAnswer">继续添加</el-button>
</div>
</div>
<div style="text-align: center;">
<el-button @click="submitForm">{{submitText}}</el-button>
<el-button @click="$router.back(-1)">关闭</el-button>
</div>
</div>
</template>
<script>
import Answer from './QuestionnaireAnswer'
import {formatDate} from '../../tools/tools.js'
export default {
components:{
'app-answer': Answer
},
data(){
return {
titText: '新增问卷',
submitText: '立即创建',
ruleForm: {},
ruleFormChild: [
{
name: '',
type: '',
}
],
}
},
methods: {
submitForm() {
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
let length = this.ruleFormChild.length;
this.ruleForm.value = length;
this.ruleForm.date = formatDate(new Date(), 'yyyy-mm-dd');
this.ruleForm.questList = this.ruleFormChild;
this.$store.commit('setData', {
type: 'add',
class: 'questData',
data: this.ruleForm
})
this.$router.push('/questionnaire')
}else {
this.$message('请填写相应必填信息!!!');
}
})
},
addAnswer() {
this.ruleFormChild.push({
name: '',
type: ''
})
},
deleteFrom(index) {
this.ruleFormChild.splice(index, 1);
},
},
}
</script>
这样就实现了父子组件的相互通信了!