在自学vue过程中,使用elemet-ui布局进行时,编写商品分类参数中商品分类区域时,按照视频将<span>选择商品分类:</span>与<el-cascader>包裹在同一个<el-col></el-col>中没有并排显示,而是上下显示,目前是通过分别包裹<el-col></el-col>中设置:span显示,为什么会出现这个问题呢?是不是element-ui版本发生变化所造成的呢?还望知道的解答下……
另外,大家如果有什么讲的比较详细的博客或文章,也可以推给我~十分感谢~
<template>
<div>
<!-- 面包屑导航区 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>参数列表</el-breadcrumb-item>
</el-breadcrumb>
<el-card>
<!-- 警告区域 -->
<el-alert title="注意:只允许为第三级分类设置相关参数!" type="warning" show-icon :closable="false"></el-alert>
<!-- 选择商品分类区域 -->
<el-row class="cat_opt">
<el-col>
<span>选择商品分类:</span>
<!-- 商品分类的级联选择框 -->
<el-cascader
v-model="selectedCateKeys"
:options="cateList"
:props="cateProps"
@change="handleChange"
></el-cascader>
</el-col>
</el-row>
<el-tabs v-model="activeName" @tab-click="handleTabsClick">
<el-tab-pane label="动态参数" name="many">
<el-button
type="primary"
size="mini"
:disabled="isBtnDisabled "
@click="addDialogVisible=true"
>添加参数</el-button>
<el-table :data="manyTableData" border stripe>
<el-table-column type="expand">
<template slot-scope="scope">
<el-tag v-for="(item, i) in scope.row.attr_vals" :key="i" closable
@close="handleClose(i,scope.row)">{<!-- -->{item}}</el-tag>
<!-- 输入Tag文本框 -->
<el-input
class="input-new-tag"
v-if="scope.row.inputVisible"
v-model="scope.row.inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm(scope.row)"
@blur="handleInputConfirm(scope.row)"
></el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
</template>
</el-table-column>
<el-table-column type="index"></el-table-column>
<el-table-column label="参数名称" prop="attr_name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
@click="showEditDialog(scope.row.attr_id)"
size="mini"
>编辑</el-button>
<el-button
type="danger"
icon="el-icon-search"
size="mini"
@click="removeParams(scope.row.attr_id)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="静态属性" name="only">
<el-button
type="primary"
size="mini"
:disabled="isBtnDisabled"
@click="addDialogVisible=true"
>添加属性</el-button>
<el-table :data="onlyTableData" border stripe>
<el-table-column type="expand">
<template slot-scope="scope">
<el-tag v-for="(item, i) in scope.row.attr_vals" :key="i" closable
@close="handleClose(i,scope.row)">{<!-- -->{item}}</el-tag>
<!-- 输入Tag文本框 -->
<el-input
class="input-new-tag"
v-if="scope.row.inputVisible"
v-model="scope.row.inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm(scope.row)"
@blur="handleInputConfirm(scope.row)"
></el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
</template>
</el-table-column>
<el-table-column type="index"></el-table-column>
<el-table-column label="属性名称" prop="attr_name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
size="mini"
@click="showEditDialog(scope.row.attr_id)"
>编辑</el-button>
<el-button
type="danger"
icon="el-icon-search"
size="mini"
@click="removeParams(scope.row.attr_id)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-card>
<el-dialog
:title=" '添加' + getTitleText"
:visible.sync="addDialogVisible"
width="50%"
@close="addDialogClosed"
>
<el-form :model="addFrom" :rules="addFromRules" ref="addFromRef" label-width="100px">
<el-form-item :label="getTitleText" prop="attr_name">
<el-input v-model="addFrom.attr_name"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addParams">确 定</el-button>
</span>
</el-dialog>
<el-dialog
:title=" '修改' + getTitleText"
:visible.sync="editDialogVisible"
width="50%"
@close="editDialogClosed"
>
<el-form :model="editFrom" :rules="editFromRules" ref="editFromRef" label-width="100px">
<el-form-item :label="getTitleText" prop="attr_name">
<el-input v-model="editFrom.attr_name"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogClosed = false">取 消</el-button>
<el-button type="primary" @click="editParams">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
cateList: [],
cateProps: {
value: 'cat_id',
label: 'cat_name',
children: 'children'
},
inputVisible: false,
inputValue: '',
selectedCateKeys: [],
activeName: 'many',
manyTableData: [],
onlyTableData: [],
addDialogVisible: false,
editDialogVisible: false,
// 修改表单数据对象
editFrom: {
attr_name: '',
},
// 修改表单验证规则
editFromRules: {
attr_name: [
{ required: true, message: '请输入参数名称', trigger: 'blur' },
],
},
addFrom: {
attr_name: '',
},
// 添加表单的验证规则
addFromRules: {
attr_name: [
{ required: true, message: '请输入参数名称', trigger: 'blur' },
],
},
}
},
created() {
this.getCateList()
},
computed: {
// 按钮需要被禁用返回true, 否则返回false
isBtnDisabled() {
if (this.selectedCateKeys.length !== 3) {
return true
}
return false
},
cateId() {
if (this.selectedCateKeys.length === 3) {
return this.selectedCateKeys[2]
}
return null
},
getTitleText() {
if (this.activeName === 'many') {
return '动态参数'
}
return '静态属性'
},
},
methods: {
// 获取所有的商品分类列表
async getCateList() {
const { data: res } = await this.$http.get('categories')
if (res.meta.status !== 200) {
return this.$message.error('获取商品数据列表失败!')
}
this.cateList = res.data
console.log(this.cateList)
}, // 级联选择框 选中变化 触发
async handleChange() {
this.getParamsData()
},
handleInputConfirm() {
console.log(ok)
},
// 删除对应的参数可选项
handleClose (i, row) {
row.attr_vals.splice(i, 1)
this.saveAttrVals(row)
},
async getParamsData() {
if (this.selectedCateKeys.length !== 3) {
this.selectedCateKeys = []
this.manyTableData=[]
this.onlyTableData=[]
return
}
console.log(this.selectedCateKeys)
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{
params: { sel: this.activeName },
}
)
if (res.meta.status !== 200) {
return this.$message.error('获取参数列表失败!')
}
res.data.forEach((item) => {
// 通过三元表达式判断attr_vals是否为空
item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
// 控制文本框的显示与隐藏
item.inputVisible = false
// 文本框的输入值
item.inputValue = ''
})
console.log(res.data)
if (this.activeName === 'many') {
this.manyTableData = res.data
} else {
this.onlyTableData = res.data
}
},
handleTabsClick() {
// console.log(this.activeName)
this.getParamsData()
},
addDialogClosed() {
this.$refs.addFromRef.resetFields()
}, // 添加参数
addParams() {
this.$refs.addFromRef.validate(async (valid) => {
if (!valid) return
const { data: res } = await this.$http.post(
`categories/${this.cateId}/attributes`,
{
attr_name: this.addFrom.attr_name,
attr_sel: this.activeName,
}
)
if (res.meta.status !== 201) {
return this.$message.error('添加参数失败!')
}
this.$message.success('添加参数成功!')
this.addDialogVisible = false
this.getParamsData()
})
},
editDialogClosed() {
this.$refs.editFromRef.resetFields()
},
showInput(row) {
row.inputVisible = true
// $nextTick方法的作用:当页面元素被重新渲染之后,才会至指定回调函数中的代码
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
editParams() {
this.$refs.editFromRef.validate(async (valid) => {
if (!valid) return
const { data: res } = await this.$http.put(
`categories/${this.cateId}/attributes/${this.editFrom.attr_id}`,
{
attr_name: this.editFrom.attr_name,
attr_sel: this.activeName,
}
)
if (res.meta.status !== 200) {
return this.$message.error('修改参数失败!')
}
this.$message.success('修改参数成功!')
this.getParamsData()
this.editDialogVisible = false
})
},
async showEditDialog(attr_id) {
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes/${attr_id}`,
{
params: { attr_sel: this.activeName },
}
)
if (res.meta.status !== 200) {
return this.$message.error('获取分类失败!')
}
this.editFrom = res.data
this.editDialogVisible = true
}, // 根据Id删除对应的参数项
async removeParams(attr_id) {
const confirmResult = await this.$confirm(
'此操作将永久删除该参数, 是否继续?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).catch((err) => err)
if (confirmResult !== 'confirm') {
return this.$message.info('已取消删除!')
}
const { data: res } = await this.$http.delete(
`categories/${this.cateId}/attributes/${attr_id}`
)
if (res.meta.status !== 200) {
return this.$message.error('删除参数失败!')
}
this.$message.success('删除参数成功!')
this.getParamsData()
},
// 文本框失去焦点,或者按下Enter触发
handleInputConfirm (row) {
// 输入的内容为空时,清空
if (row.inputValue.trim().length === 0) {
row.inputValue = ''
row.inputVisible = false
return
}
row.attr_vals.push(row.inputValue.trim())
row.inputValue = ''
row.inputVisible = false
// 提交数据库,保存修改
this.saveAttrVals(row)
},// 将对attr_vals(Tag) 的操作 保存到数据库
async saveAttrVals (row) {
const { data: res } = await this.$http.put(
`categories/${this.cateId}/attributes/${row.attr_id}`,
{
attr_name: row.attr_name,
attr_sel: row.attr_sel,
attr_vals: row.attr_vals.join(' ')
}
)
if (res.meta.status !== 200) {
return this.$message.error('修改参数项失败!')
}
this.$message.success('修改参数项成功!')
},
},
}
</script>
<style lang="less" scoped>
.cat_opt {
margin: 15px 0px;
}
.el-cascader {
width: 25%;
}
.el-tag {
margin: 8px;
}
.input-new-tag {
width: 90px;
}
</style>
<!-- 选择商品分类区域 -->
<el-row class="cat_opt">
<el-col>
<span>选择商品分类:</span>
<!-- 商品分类的级联选择框 -->
<el-cascader
v-model="selectedCateKeys"
:options="cateList"
:props="cateProps"
@change="handleChange"
></el-cascader>
</el-col>
</el-row>
演示案例:
自己实施结果:
目前的解决方案:
<!-- 选择商品分类区域 -->
<el-row class="cat_opt">
<el-col :span="3">
<span>选择商品分类:</span>
</el-col>
<!-- 选择商品分类的级联选择框 -->
<el-col :span="6">
<el-cascader
:options="catelist"
:props="cateProps"
v-model="selectedCateKeys"
@change="cateChange"
label="选择商品分类:"
>
</el-cascader>
</el-col>
</el-row>