A: hi! ~ Hello everyone, I am YK bacteria 🐷, a microsystem front-end ✨, love to think, love to summarize, love to record, love to share 🏹, welcome to follow me 😘 ~ [wechat account: Yk2012Yk2012, wechat public account: ykyk2012]

“This is the 12th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

The address of the project: https://gitee.com/ykang2020/vue_shop

Today, WE continue to use Vue and Element to do the project of background management system and the function of classification parameters of commodity management module.

1. Introduction

Commodity parameters are used to display the fixed feature information of commodities, which can be seen visually on the commodity details page of e-commerce platform. They are divided into dynamic parameters and static attributes, which are completed in turn

1.1 Dynamic Parameters

The display effect is shown in the figure

1.2 Static Attributes

The display effect is shown in the figure

2. Create git branches

Create a Git branch for the classification parameters

git checkout -b goods_params
Copy the code
git push -u origin goods_params
Copy the code

3. Initialize the category parameter component page

  1. New file components/goods/Params. Vue
  2. Mount to the page through the routing component

Component code

<template>
  <div>
    <! Breadcrumb navigation area -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">Home page</el-breadcrumb-item>
      <el-breadcrumb-item>Commodity management</el-breadcrumb-item>
      <el-breadcrumb-item>The list of parameters</el-breadcrumb-item>
    </el-breadcrumb>

    <! -- Card view -->
    <el-card>
      <! -- Head warning area -->
      <el-alert show-icon title="Note: only third level classification parameters are allowed!" type="warning" :closable="false"></el-alert>

      <! -- Select product category region -->
      <el-row class="cat_opt">
        <el-col>
          <span>Select goods by category:</span>
          <! -- Select items from the cascading selection box -->
        </el-col>
      </el-row>
    </el-card>
  </div>
</template>

<style scoped>
.cat_opt {
  margin: 15px 0;
}
</style>
Copy the code

4. Select the product category module

4.1 Obtaining commodity Classification list data

Interface documentation

Basic code

export default {
  data() {
    return {
      // List of goods by category
      cateList: []}},created() {
    this.getCateList()
  },
  methods: {
    // Get a list of all categories
    async getCateList(){
      const { data: result } = await this.$http.get('categories')
      if(result.meta.status ! = =200) {
        return this.$message.error('Failed to get item category list! ')}this.cateList = result.data
    }
  }
}
Copy the code

4.2 Cascading Selection Box for Product Categoriescascader

A cascading selection box for selecting items

  <! -- Select items from the cascading selection box -->
  <el-cascader
    v-model="selectedCateKeys"
    :options="cateList"
    :props="cascaderProps"
    @change="handleChange"
    clearable
  ></el-cascader> 
Copy the code

Specifies the configuration object for the cascade selector and the array to which the cascade selector box is bidirectionally bound

// Specify the configuration object for the cascade selector
cascaderProps: {
  expandTrigger: 'hover'.value: 'cat_id'.label: 'cat_name'.children: 'children'.checkStrictly: true
},
// The array to which the cascaded selection boxes are bidirectionally bound
selectedCateKeys: []
Copy the code

Controls the selection range of the cascade selection box

// This function is triggered by changes in the cascaded selection boxes
handleChange() {
  // console.log(this.selectedCateKeys)
  // If the selected category is not tertiary, reset the array
  if (this.selectedCateKeys.length ! = =3) {
    this.selectedCateKeys = []
}
Copy the code

5. Classification parametersTabsTAB.

5.1 apply colours to a drawingTabsTAB.

<! -- TAB TAB area -->
<el-tabs v-model="activeName" @tab-click="handleTabClick">
  <! Add dynamic parameters panel -->
  <el-tab-pane label="Dynamic parameter" name="first">The dynamic parameters</el-tab-pane>
  <! Add static properties panel -->
  <el-tab-pane label="Static properties" name="second">Static attributes</el-tab-pane>
</el-tabs>
Copy the code
// Name of the activated page signature
activeName: 'first'
Copy the code
// Tab click event handler
handleTabClick() {
  console.log(this.activeName)
}
Copy the code

5.2 Buttons for Adding Parameters and Attributes

<! Add dynamic parameters panel -->
<el-tab-pane label="Dynamic parameter" name="first">
  <! -- Add parameter button -->
  <el-button type="primary" size="mini" :disabled="isBtnDisabled">Add parameters</el-button>
</el-tab-pane>
<! Add static properties panel -->
<el-tab-pane label="Static properties" name="second">
  <! Add properties button -->
  <el-button type="primary" size="mini" :disabled="isBtnDisabled">Add attributes</el-button>
</el-tab-pane>
Copy the code
computed: {
  // Return true if the button needs to be disabled, false otherwise
  isBtnDisabled() {
    if (this.selectedCateKeys.length ! = =3) {
      return true
    }
    return false}}Copy the code

5.3 Obtaining Parameter List Data

Interface documentation

<el-tab-pane label="Dynamic parameter" name="many">
<el-tab-pane label="Static properties" name="only">
Copy the code
// Name of the activated page signature
activeName: 'many'
Copy the code
computed: {
  // Id of the currently selected tertiary category
  cateId() {
    if (this.selectedCateKeys.length === 3) {
      return this.selectedCateKeys[2]}return null}}Copy the code
// This function is triggered by changes in the cascaded selection boxes
async handleChange() {
  // console.log(this.selectedCateKeys)
  // If the selected category is not tertiary, reset the array
  if (this.selectedCateKeys.length ! = =3) {
    this.selectedCateKeys = []
  }
  // Select the level 3 category
  console.log(this.selectedCateKeys)
  // Based on the id of the selected category and the current panel, get the corresponding parameters
  const { data: result } = await this.$http.get(`categories/The ${this.cateId}/attributes`, { 
    params: { sel: this.activeName } 
  })
  if(result.meta.status ! = =200) {
    return this.$message.error('Failed to get parameter list')}console.log(result.data)
}
Copy the code

5.4 Switching panel Obtain the parameter list data again

// This function is triggered by changes in the cascaded selection boxes
handleChange() {
  this.getParamsData()
},
// Tab click event handler
handleTabClick() {
  console.log(this.activeName)
  this.getParamsData()
},
// Get the list of parameters
async getParamsData() {
  // console.log(this.selectedCateKeys)
  // If the selected category is not tertiary, reset the array
  if (this.selectedCateKeys.length ! = =3) {
    this.selectedCateKeys = []
  }
  // Select the level 3 category
  console.log(this.selectedCateKeys)
  // Based on the id of the selected category and the current panel, get the corresponding parameters
  const { data: result } = await this.$http.get(`categories/The ${this.cateId}/attributes`, { 
    params: { sel: this.activeName } 
  })
  if(result.meta.status ! = =200) {
    return this.$message.error('Failed to get parameter list')}console.log(result.data)
}
Copy the code

5.5 Parameter Data Mounted to Different Data

// Dynamic parameter data
manyTableData: [].// Static attribute data
onlyTableData: []
Copy the code
async getParamsData() {
  // console.log(result.data)
  if(this.activeName === 'many') {
    this.manyTableData = result.data
  } else {
    this.onlyTableData = result.data
  }
}
Copy the code

5.6 Dynamic Parameters and Static AttributesTableform

<! Add dynamic parameters panel -->
<el-tab-pane label="Dynamic parameter" name="many">
  <! -- Add parameter button -->
  <el-button type="primary" size="mini" :disabled="isBtnDisabled">Add parameters</el-button>
  <! -- Dynamic parameter table -->
  <el-table :data="manyTableData" border stripe>
    <! -- Expand row -->
    <el-table-column type="expand"></el-table-column>
    <! -- index column -->
    <el-table-column type="index"></el-table-column>
    <el-table-column label="Parameter Name" prop="attr_name"></el-table-column>
    <el-table-column label="Operation">
      <template slot-scope="scope">
        <el-button type="primary" icon="el-icon-edit" size="mini">The editor</el-button>
        <el-button type="danger" icon="el-icon-delete" size="mini">delete</el-button>
      </template>
    </el-table-column>
  </el-table>
</el-tab-pane>
Copy the code
<! Add static properties panel -->
<el-tab-pane label="Static properties" name="only">
  <! Add properties button -->
  <el-button type="primary" size="mini" :disabled="isBtnDisabled">Add attributes</el-button>
  <! -- Dynamic parameter table -->
  <el-table :data="onlyTableData" border stripe>
    <! -- Expand row -->
    <el-table-column type="expand"></el-table-column>
    <! -- index column -->
    <el-table-column type="index"></el-table-column>
    <el-table-column label="Attribute Name" prop="attr_name"></el-table-column>
    <el-table-column label="Operation">
      <template slot-scope="scope">
        <el-button type="primary" icon="el-icon-edit" size="mini">The editor</el-button>
        <el-button type="danger" icon="el-icon-delete" size="mini">delete</el-button>
      </template>
    </el-table-column>
  </el-table>
</el-tab-pane>
Copy the code

6. Add a parameter module

6.1 Dialog box for Adding Parametersdialog

<el-button type="primary" size="mini" :disabled="isBtnDisabled" @click="addDialogVisible=true">Add parameters</el-button>
<el-button type="primary" size="mini" :disabled="isBtnDisabled" @click="addDialogVisible=true">Add attributes</el-button>
Copy the code
<! Add parameters dialog box -->
<el-dialog
  :title="` add ${titleText} `"
  :visible.sync="addDialogVisible"
  width="50%"
  @close="addDialogClosed"
>
  <! Content body area -->
  <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
    <el-form-item :label="titleText" prop="attr_name">
      <el-input v-model="addForm.attr_name"></el-input>
    </el-form-item>
  </el-form>
  <! -- Bottom area -->
  <span slot="footer" class="dialog-footer">
    <el-button @click="addDialogVisible = false">Take away</el-button>
    <el-button type="primary" @click="addParams">determine</el-button>
  </span>
</el-dialog>
Copy the code

Calculate attribute

// Dynamically evaluates the text of the title
titleText() {
  if (this.activeName === 'many') {
    return 'Dynamic parameter'
  }
  return 'Static properties'
}
Copy the code
// Controls the display and hide of the add dialog box
addDialogVisible: false.// Add parameters to the form data object
addForm: {
  attr_name: ' '
},
// Add a validation object for the form
addFormRules: {
  attr_name: [{required: true.message: 'Please enter a parameter name'.trigger: 'blur'}}]Copy the code
// Listen for the close event of the add dialog box
addDialogClosed() {
  this.$refs.addFormRef.resetFields()
}
Copy the code

6.2 Adding a Vm

<el-button type="primary" @click="addParams">determine</el-button>
Copy the code
// Click the button to add parameters
addParams() {
  this.$refs.addFormRef.validate(async valid => {
    if(! valid)return 
    const { data: result } = await this.$http.post(`categories/The ${this.cateId}/attributes`, {
      attr_name: this.addForm.attr_name,
      attr_sel: this.activeName
    })
    if(result.meta.status ! = =201) {
      return this.$message.error('Failed to add parameters')}this.$message.success('Parameter added successfully! ')
    this.addDialogVisible = false
    this.getParamsData()
  })
}
Copy the code

7. Modify the parameter module

7.1 Modifying Parametersdialog

<template slot-scope="scope">
  <el-button
    type="primary"
    icon="el-icon-edit"
    size="mini"
    @click="showEditDialog(scope.row.attr_id)"
    >The editor</el-button>
</template>
Copy the code
<! -- Modify parameters dialog box -->
<el-dialog
  :title="` modify ${titleText} `"
  :visible.sync="editDialogVisible"
  width="50%"
  @close="editDialogClosed"
>
  <! Content body area -->
  <el-form :model="editForm" :rules="addFormRules" ref="editFormRef" label-width="100px">
    <el-form-item :label="`${titleText}`" prop="attr_name">
      <el-input v-model="editForm.attr_name"></el-input>
    </el-form-item>
  </el-form>
  <! -- Bottom area -->
  <span slot="footer" class="dialog-footer">
    <el-button @click="editDialogVisible = false">Take away</el-button>
    <el-button type="primary" @click="editParams">determine</el-button>
  </span>
</el-dialog>
Copy the code
// Control the display and hide of the modify dialog box
editDialogVisible: false.// The modified form data object
editForm: {}
Copy the code

7.2 Modifying Parameters

// Click the button to display the modification dialog box
async showEditDialog(id) {
  const { data: result } = await this.$http.get(`categories/The ${this.cateId}/attributes/${id}`, {
    params: { attr_sel: this.activeName }
  })
  if(result.meta.status ! = =200) {
    return this.$message.error('Failed to get parameters! ')}this.editForm = result.data
  this.editDialogVisible = true
},
// Listen for the close event of the modify dialog box
editDialogClosed() {
  this.$refs.editFormRef.resetFields()
}, 
// Click the button to modify the parameters
editParams() {
  this.$refs.editFormRef.validate(async valid => {
    if(! valid)return 
    const { data: result } = await this.$http.put(`categories/The ${this.cateId}/attributes/The ${this.editForm.attr_id}`, { 
      attr_name: this.editForm.attr_name,
      attr_sel: this.activeName
    })
    if(result.meta.status ! = =200) {
      return this.$message.error('Failed to modify parameters! ')}this.$message.success('Parameter modification succeeded! ')
    this.getParamsData()
    this.editDialogVisible = false})}Copy the code

8. Delete the parameter module

<el-button
  type="danger"
  icon="el-icon-delete"
  size="mini"
  @click="removeParams(scope.row.attr_id)"
  >delete</el-button>
Copy the code
// Delete parameters based on id
async removeParams(id) {
  const confirmResut = await this.$confirm('This operation will delete this parameter forever. Do you want to continue? '.'tip', {
    confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
  }).catch(err= > err)

  if(confirmResut ! = ='confirm') {
    return this.$message.info('Cancelled delete')}/ / delete
  const { data: result } = await this.$http.delete(`categories/The ${this.cateId}/attributes/${id}`)
  if(result.meta.status ! = =200) {
    return this.$message.error('Delete attribute failed! ')}this.$message.success('Attribute deleted successfully! ')
  this.getParamsData()
}
Copy the code

9. Optional under render parameters

9.1 apply colours to a drawingTagThe label

// Get the list of parameters
async getParamsData() {
  // console.log(this.selectedCateKeys)
  // If the selected category is not tertiary, reset the array
  if (this.selectedCateKeys.length ! = =3) {
    this.selectedCateKeys = []
  }
  // Select the level 3 category
  // console.log(this.selectedCateKeys)
  // Based on the id of the selected category and the current panel, get the corresponding parameters
  const { data: result } = await this.$http.get(
    `categories/The ${this.cateId}/attributes`,
    {
      params: { sel: this.activeName }
    }
  )
  if(result.meta.status ! = =200) {
    return this.$message.error('Failed to get parameter list')}console.log(result.data)
  result.data.forEach(item= > {
    item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
    // Add a Boolean value that controls the display and hiding of text boxes
    item.inputVisible = false
    // The value entered in the text box
    item.inputValue = ' '
  })
  console.log(result.data)

  if (this.activeName === 'many') {
    this.manyTableData = result.data
  } else {
    this.onlyTableData = result.data
  }
},
Copy the code
<! -- Expand row -->
<el-table-column type="expand">
  <template slot-scope="scope">
    <! -- Loop render Tag Tag -->
    <el-tag
      v-for="(item, index) in scope.row.attr_vals"
      :key="index"
      closable
      >{{ item }}</el-tag>
Copy the code

9.2 Switching display between control buttons and text boxes

  • Provide separate inputVisible and inputValue for each row of data
<! -- Enter text box -->
<el-input
  class="input-new-tag"
  v-if="scope.row.inputVisible"
  v-model="scope.row.inputValue"
  ref="saveTagInput"
  size="small"
  @keyup.enter.native="handleInputConfirm"
  @blur="handleInputConfirm"
>
</el-input>
<! -- Add button -->
<el-button
  v-else
  class="button-new-tag"
  size="small"
  @click="showInput(scope.row)"
  >+ New Tag</el-button
>
Copy the code
// The text box loses focus, or the Enter key is pressed
handleInputConfirm() {
  console.log('ok')},// Click the button to display the text input field
showInput(row) {
  row.inputVisible = true
}
Copy the code

9.3 Let the text Box automatically get focus

// Click the button to display the text input field
showInput(row) {
  row.inputVisible = true
  // Let the text box get focus automatically
  The $nextTick method executes the code in the callback function after the page element has been re-rendered
  this.$nextTick(_= > {
    this.$refs.saveTagInput.$refs.input.focus()
  })
}
Copy the code

9.4 Switch display between text boxes and buttons

The optional parameters are added

<! -- Enter text box -->
<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>
Copy the code

// The text box loses focus, or the Enter key is pressed
async handleInputConfirm(row) {
  // console.log('ok')
  if (row.inputValue.trim().length === 0) {
    row.inputValue = ' '
    row.inputVisible = false
    return
  }
  // If there is no return, there is input and further processing is required
  row.attr_vals.push(row.inputValue.trim())
  row.inputValue = ' '
  row.inputVisible = false
  // The request save operation needs to be initiated
  const { data: result } = await this.$http.put(`categories/The ${this.cateId}/attributes/${row.attr_id}`, {
    attr_name: row.attr_name,
    attr_sel: row.attr_sel,
    attr_vals: row.attr_vals.join(' ')})if(result.meta.status ! = =200) {
    return this.$message.error('Failed to modify parameter entry! ')}this.$message.success('Modify parameter item successfully! ')}Copy the code

9.5 Deleting Parameters Is optional

<! -- Loop render Tag Tag -->
<el-tag
  v-for="(item, index) in scope.row.attr_vals"
  :key="index"
  closable
  @close="handleClose(index, scope.row)"
  >{{ item }}</el-tag
>
Copy the code
// The text box loses focus, or the Enter key is pressed
handleInputConfirm(row) {
  // console.log('ok')
  if (row.inputValue.trim().length === 0) {
    row.inputValue = ' '
    row.inputVisible = false
    return
  }
  // If there is no return, there is input and further processing is required
  row.attr_vals.push(row.inputValue.trim())
  row.inputValue = ' '
  row.inputVisible = false
  this.saveAttrVals(row)
},
    // Deleting corresponding parameters is optional
handleClose(i, row) {
  row.attr_vals.splice(i, 1)
  this.saveAttrVals(row)
},
// Save the attr_VALS operation to the database
async saveAttrVals(row) {
  // The request save operation needs to be initiated
  const { data: result } = await this.$http.put(`categories/The ${this.cateId}/attributes/${row.attr_id}`, {
    attr_name: row.attr_name,
    attr_sel: row.attr_sel,
    attr_vals: row.attr_vals.join(' ')})if(result.meta.status ! = =200) {
    return this.$message.error('Failed to modify parameter entry! ')}this.$message.success('Modify parameter item successfully! ')}Copy the code

10. Clear your table

The selected category is not level 3. Clear the table data

// Get the list of parameters
async getParamsData() {
  // console.log(this.selectedCateKeys)
  // If the selected category is not tertiary, reset the array
  if (this.selectedCateKeys.length ! = =3) {
    this.selectedCateKeys = []
    this.manyTableData = []
    this.onlyTableData = []
  }
}
Copy the code

In static property table, the expanded line effect directly copies the expanded line HTML of the static parameter

11. Complete codeParams.vue

<template>
  <div>
    <! Breadcrumb navigation area -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">Home page</el-breadcrumb-item>
      <el-breadcrumb-item>Commodity management</el-breadcrumb-item>
      <el-breadcrumb-item>The list of parameters</el-breadcrumb-item>
    </el-breadcrumb>

    <! -- Card view -->
    <el-card>
      <! -- Head warning area -->
      <el-alert
        show-icon
        title="Note: only third level classification parameters are allowed!"
        type="warning"
        :closable="false"
      ></el-alert>

      <! -- Select product category region -->
      <el-row class="cat_opt">
        <el-col>
          <span>Select goods by category:</span>
          <! -- Select items from the cascading selection box -->
          <el-cascader
            v-model="selectedCateKeys"
            :options="cateList"
            :props="casteProps"
            @change="handleChange"
            clearable
          ></el-cascader>
        </el-col>
      </el-row>

      <! -- TAB TAB area -->
      <el-tabs v-model="activeName" @tab-click="handleTabClick">
        <! Add dynamic parameters panel -->
        <el-tab-pane label="Dynamic parameter" name="many">
          <! -- Add parameter button -->
          <el-button
            type="primary"
            size="mini"
            :disabled="isBtnDisabled"
            @click="addDialogVisible = true"
            ></el-button ><! -- Dynamic parameter table -->
          <el-table :data="manyTableData" border stripe>
            <! -- Expand row -->
            <el-table-column type="expand">
              <template slot-scope="scope">
                <! -- Loop render Tag Tag -->
                <el-tag
                  v-for="(item, index) in scope.row.attr_vals"
                  :key="index"
                  closable
                  @close="handleClose(index, scope.row)"
                  >{{ item }}</el-tag
                >
                <! -- Enter text box -->
                <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>
                <! -- Add button -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(scope.row)"
                  >+ New Tag</el-button
                >
              </template>
            </el-table-column>
            <! -- index column -->
            <el-table-column type="index"></el-table-column>
            <el-table-column
              label="Parameter Name"
              prop="attr_name"
            ></el-table-column>
            <el-table-column label="Operation">
              <template slot-scope="scope">
                <el-button
                  type="primary"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditDialog(scope.row.attr_id)"
                  >Edit < / el - button ><el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="removeParams(scope.row.attr_id)"
                  >Delete < / el - button ></template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <! Add static properties panel -->
        <el-tab-pane label="Static properties" name="only">
          <! Add properties button -->
          <el-button
            type="primary"
            size="mini"
            :disabled="isBtnDisabled"
            @click="addDialogVisible = true"
            >Add attribute </el-button ><! -- Dynamic parameter table -->
          <el-table :data="onlyTableData" border stripe>
            <! -- Expand row -->
            <el-table-column type="expand">
              <template slot-scope="scope">
                <! -- Loop render Tag Tag -->
                <el-tag
                  v-for="(item, index) in scope.row.attr_vals"
                  :key="index"
                  closable
                  @close="handleClose(index, scope.row)"
                  >{{ item }}</el-tag
                >
                <! -- Enter text box -->
                <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>
                <! -- Add button -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(scope.row)"
                  >+ New Tag</el-button
                >
              </template>
            </el-table-column>
            <! -- index column -->
            <el-table-column type="index"></el-table-column>
            <el-table-column
              label="Attribute Name"
              prop="attr_name"
            ></el-table-column>
            <el-table-column label="Operation">
              <template slot-scope="scope">
                <el-button
                  type="primary"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditDialog(scope.row.attr_id)"
                  >Edit < / el - button ><el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="removeParams(scope.row.attr_id)"
                  >Delete < / el - button ></template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <! Add parameters dialog box -->
    <el-dialog
      :title="` add ${titleText} `"
      :visible.sync="addDialogVisible"
      width="50%"
      @close="addDialogClosed"
    >
      <! Content body area -->
      <el-form
        :model="addForm"
        :rules="addFormRules"
        ref="addFormRef"
        label-width="100px"
      >
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="addForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <! -- Bottom area -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">Take away</el-button>
        <el-button type="primary" @click="addParams">determine</el-button>
      </span>
    </el-dialog>

    <! -- Modify parameters dialog box -->
    <el-dialog
      :title="` modify ${titleText} `"
      :visible.sync="editDialogVisible"
      width="50%"
      @close="editDialogClosed"
    >
      <! Content body area -->
      <el-form
        :model="editForm"
        :rules="addFormRules"
        ref="editFormRef"
        label-width="100px"
      >
        <el-form-item :label="`${titleText}`" prop="attr_name">
          <el-input v-model="editForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <! -- Bottom area -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">Take away</el-button>
        <el-button type="primary" @click="editParams">determine</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // List of goods by category
      cateList: [].// Specify the configuration object for the cascade selector
      casteProps: {
        expandTrigger: 'hover'.value: 'cat_id'.label: 'cat_name'.children: 'children'
      },
      // The array to which the cascaded selection boxes are bidirectionally bound
      selectedCateKeys: [].// Name of the activated page signature
      activeName: 'many'.// Dynamic parameter data
      manyTableData: [].// Static attribute data
      onlyTableData: [].// Controls the display and hide of the add dialog box
      addDialogVisible: false.// Add parameters to the form data object
      addForm: {
        attr_name: ' '
      },
      // Add a validation object for the form
      addFormRules: {
        attr_name: [{required: true.message: 'Please enter a parameter name'.trigger: 'blur'}},// Control the display and hide of the modify dialog box
      editDialogVisible: false.// The modified form data object
      editForm: {}
      // // Control button and text box switching display
      // inputVisible: false,
      // // Enter the content in the text box
      // inputValue: ''}},created() {
    this.getCateList()
  },
  methods: {
    // Get a list of all categories
    async getCateList() {
      const { data: result } = await this.$http.get('categories')
      if(result.meta.status ! = =200) {
        return this.$message.error('Failed to get item category list! ')}this.cateList = result.data
    },
    // This function is triggered by changes in the cascaded selection boxes
    handleChange() {
      this.getParamsData()
    },
    // Tab click event handler
    handleTabClick() {
      console.log(this.activeName)
      this.getParamsData()
    },
    // Get the list of parameters
    async getParamsData() {
      // console.log(this.selectedCateKeys)
      // If the selected category is not tertiary, reset the array
      if (this.selectedCateKeys.length ! = =3) {
        this.selectedCateKeys = []
        this.manyTableData = []
        this.onlyTableData = []
      }
      // Select the level 3 category
      // console.log(this.selectedCateKeys)
      // Based on the id of the selected category and the current panel, get the corresponding parameters
      const { data: result } = await this.$http.get(
        `categories/The ${this.cateId}/attributes`,
        {
          params: { sel: this.activeName }
        }
      )
      if(result.meta.status ! = =200) {
        return this.$message.error('Failed to get parameter list')}console.log(result.data)
      result.data.forEach(item= > {
        item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
        // Add a Boolean value that controls the display and hiding of text boxes
        item.inputVisible = false
        // The value entered in the text box
        item.inputValue = ' '
      })
      console.log(result.data)

      if (this.activeName === 'many') {
        this.manyTableData = result.data
      } else {
        this.onlyTableData = result.data
      }
    },
    // Listen for the close event of the add dialog box
    addDialogClosed() {
      this.$refs.addFormRef.resetFields()
    },
    // Click the button to add parameters
    addParams() {
      this.$refs.addFormRef.validate(async valid => {
        if(! valid)return
        const { data: result } = await this.$http.post(
          `categories/The ${this.cateId}/attributes`,
          {
            attr_name: this.addForm.attr_name,
            attr_sel: this.activeName
          }
        )
        if(result.meta.status ! = =201) {
          return this.$message.error('Failed to add parameters')}this.$message.success('Parameter added successfully! ')
        this.addDialogVisible = false
        this.getParamsData()
      })
    },
    // Click the button to display the modification dialog box
    async showEditDialog(id) {
      const { data: result } = await this.$http.get(
        `categories/The ${this.cateId}/attributes/${id}`,
        {
          params: { attr_sel: this.activeName }
        }
      )
      if(result.meta.status ! = =200) {
        return this.$message.error('Failed to get parameters! ')}this.editForm = result.data
      this.editDialogVisible = true
    },
    // Listen for the close event of the modify dialog box
    editDialogClosed() {
      this.$refs.editFormRef.resetFields()
    },
    // Click the button to modify the parameters
    editParams() {
      this.$refs.editFormRef.validate(async valid => {
        if(! valid)return
        const { data: result } = await this.$http.put(
          `categories/The ${this.cateId}/attributes/The ${this.editForm.attr_id}`,
          {
            attr_name: this.editForm.attr_name,
            attr_sel: this.activeName
          }
        )
        if(result.meta.status ! = =200) {
          return this.$message.error('Failed to modify parameters! ')}this.$message.success('Parameter modification succeeded! ')
        this.getParamsData()
        this.editDialogVisible = false})},// Delete parameters based on id
    async removeParams(id) {
      const confirmResut = await this.$confirm(
        'This operation will delete this parameter forever. Do you want to continue? '.'tip',
        {
          confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
        }
      ).catch(err= > err)

      if(confirmResut ! = ='confirm') {
        return this.$message.info('Cancelled delete')}/ / delete
      const { data: result } = await this.$http.delete(
        `categories/The ${this.cateId}/attributes/${id}`
      )
      if(result.meta.status ! = =200) {
        return this.$message.error('Delete attribute failed! ')}this.$message.success('Attribute deleted successfully! ')
      this.getParamsData()
    },
    // The text box loses focus, or the Enter key is pressed
    handleInputConfirm(row) {
      // console.log('ok')
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ' '
        row.inputVisible = false
        return
      }
      // If there is no return, there is input and further processing is required
      row.attr_vals.push(row.inputValue.trim())
      row.inputValue = ' '
      row.inputVisible = false
      this.saveAttrVals(row)
    },
    // Click the button to display the text input field
    showInput(row) {
      row.inputVisible = true
      // Let the text box get focus automatically
      The $nextTick method executes the code in the callback function after the page element has been re-rendered
      this.$nextTick(_= > {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },
    // Deleting corresponding parameters is optional
    handleClose(i, row) {
      row.attr_vals.splice(i, 1)
      this.saveAttrVals(row)
    },
    // Save the attr_VALS operation to the database
    async saveAttrVals(row) {
      // The request save operation needs to be initiated
      const { data: result } = await this.$http.put(`categories/The ${this.cateId}/attributes/${row.attr_id}`, {
        attr_name: row.attr_name,
        attr_sel: row.attr_sel,
        attr_vals: row.attr_vals.join(' ')})if(result.meta.status ! = =200) {
        return this.$message.error('Failed to modify parameter entry! ')}this.$message.success('Modify parameter item successfully! ')}},computed: {
    // Return true if the button needs to be disabled, false otherwise
    isBtnDisabled() {
      if (this.selectedCateKeys.length ! = =3) {
        return true
      }
      return false
    },
    // Id of the currently selected tertiary category
    cateId() {
      if (this.selectedCateKeys.length === 3) {
        return this.selectedCateKeys[2]}return null
    },
    // Dynamically evaluates the text of the title
    titleText() {
      if (this.activeName === 'many') {
        return 'Dynamic parameter'
      }
      return 'Static properties'}}}</script>

<style scoped>
.cat_opt {
  margin: 15px 0;
}
.el-tag {
  margin: 10px;
}
.input-new-tag {
  width: 120px;
}
</style>

Copy the code

12. Branch git

git branch
git add .
git commit -m "Completed the development of classification parameters."
git push
git checkout master
git merge goods_params
git push
Copy the code

The address of the project: https://gitee.com/ykang2020/vue_shop

Finally, welcome to my column and make friends with YK bacteria