Vue + ElementUI的電商管理系統實例12 分類參數


1、創建商品分類分支goods_params並push到遠程

創建分支goods_params,並切換到當前:

git checkout -b goods_params

推送到遠程:(以前碼雲中沒有該分支,所以要加-u,如果碼雲中有該分支,則不需要加-u)

git push -u origin goods_params

2、通過路由加載分類參數組件

在goods文件夾和Params.vue文件:

<template>
<div>
  <h3>分類參數組件</h3>
</div>
</template>

<script>
export default {

}
</script>

<style lang="less" scoped>

</style>

添加路由:

import Params from '../components/goods/Params.vue'

const routes = [
  { path: '/', redirect: '/login' }, // 重定向
  { path: '/login', component: Login },
  {
    path: '/home',
    component: Home,
    redirect: '/welcome', // 重定向
    children: [ // 子路由
      { path: '/welcome', component: Welcome },
      { path: '/users', component: Users }, // 用戶列表
      { path: '/rights', component: Rights }, // 權限列表
      { path: '/roles', component: Roles }, // 角色列表
      { path: '/categories', component: Cate }, // 商品分類
      { path: '/params', component: Params } // 分類參數
    ]
  }
]

點擊左側菜單的分類參數的效果如圖:

3、渲染分類參數頁面的基本UI布局

還是面包屑和card視圖:

<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>
      123
    </el-card>
</div>
</template>

然后是頭部警告區域,需要用到Alert 警告組件,導入element.js里

在 Alert 組件中,你可以設置是否可關閉,關閉按鈕的文本以及關閉時的回調函數。closable屬性決定是否可關閉,接受boolean,默認為true。你可以設置close-text屬性來代替右側的關閉圖標,注意:close-text必須為文本。設置close事件來設置關閉時的回調。通過設置show-icon屬性來顯示 Alert 的 icon。

<!--卡片視圖區域-->
<el-card>
      <!--警告區域-->
      <el-alert title="注意:只允許為第三季分類設置相關參數!" type="warning" show-icon :closable="false"></el-alert>
      <!--選擇商品分類區域-->
      <el-row class="cat_opt">
        <el-col>
          <span>選擇商品分類:</span>
          <!--選擇商品分類的級聯選擇框-->
        </el-col>
      </el-row>
</el-card>

<style lang="less" scoped>
.cat_opt{margin:15px 0;}
</style>

此時效果圖:

4、獲取商品分類列表數據

調用api的商品分類數據列表接口,請求路徑:categories,請求方法:get,不需要傳遞參數。
<script>
export default {
  data() {
    return {
      cateList: [], // 商品分類列表數據
    }
  },
  created() {
    this.getCateList()
  },
  methods: {
    // 獲取所有的商品分類列表
    async getCateList() {
      const { data: res } = await this.$http.get('categories')
      if (res.meta.status !== 200) {
        return this.$message.error('獲取商品分類失敗!')
      }
      this.cateList = res.data
    }
  }
}
</script>

5、渲染商品分類的級聯選擇框

添加級聯選擇框代碼:

<!--選擇商品分類的級聯選擇框-->
<!-- options用來指定數據源  props用來指定配置對象-->
<el-cascader v-model="selectedCateKeys" :options="cateList" :props="cateProps"
            @change="cateChanged" clearable></el-cascader>

<script>
export default {
  data() {
    return {
      // 指定級聯選擇框的配置對象
      cateProps: {
        expandTrigger: 'hover', // 次級菜單的展開方式 click / hover
        value: 'cat_id', // 指定選中值的屬性
        label: 'cat_name', // 指定選中標簽的名稱
        children: 'children' // 指定父子嵌套的屬性
      },
      selectedCateKeys: [] // 級聯選擇框雙向綁定 選中的商品分類的ID數組
    }
  },
  methods: {
    // 級聯選擇框選中項變化,會觸發這個函數
    cateChanged() {
      console.log(this.selectedCateKeys)
    }
  }
}
</script>

此時點擊級聯選擇框,選中商品效果圖:

6、控制級聯選擇框的選中范圍

以為警告框寫了只允許為第三級分類設置相關參數,所以分類也應該只能選中三級分類:

// 級聯選擇框選中項變化,會觸發這個函數
cateChanged() {
      // 證明選中的不是三級分類
      if (this.selectedCateKeys.length !== 3) {
        this.selectedCateKeys = []
        return
      }
      // 證明選中的是三級分類
      console.log(this.selectedCateKeys)
}

7、渲染分類參數的Tabs標簽組件

v-model實現雙向數據綁定,tab-click點擊事件
label指定標題,name頁簽名稱,自動綁定到v-model的屬性上

Tabs 和 TabPane 需要導入element.js中,然后添加代碼:

<!--Tabs標簽區域-->
<el-tabs v-model="activeName" @tab-click="handleTabClick">
      <el-tab-pane label="動態參數" name="first">動態參數</el-tab-pane>
      <el-tab-pane label="靜態屬性" name="second">靜態屬性</el-tab-pane>
</el-tabs>

<script>
export default {
  data() {
    return {
      // 被激活的標簽的名稱,默認為first
      activeName: 'first'
    }
  },
  methods: {
    // tab標簽的點擊事件處理函數
    handleTabClick() {
      console.log(this.activeName)
    }
  }
}
</script>

點擊切換tab標簽效果圖:

8、渲染添加參數按鈕並控制按鈕的禁用狀態

可以使用disabled屬性來定義按鈕是否可用,它接受一個Boolean值。

需要添加一個計算屬性,判斷selectedCateKeys的長度不等於3時返回一個布爾值,綁定到按鈕來禁用

<!--添加參數的按鈕-->
<el-button type="primary" size="mini" :disabled="isBtnDisabled">添加參數</el-button>
<!--添加屬性的按鈕-->
<el-button type="primary" size="mini" :disabled="isBtnDisabled">添加屬性</el-button>

<script>
export default {
  computed: { // 計算屬性
    // 如果按鈕需要被禁用 則返回true,否則返回false
    isBtnDisabled() {
      if (this.selectedCateKeys.length !== 3) {
        return true
      }
      return false
    }
  }
}
</script>

效果圖:

 

9、獲取分類參數列表數據

調用api的分類參數列表接口,請求路徑:categories/:id/attributes,請求方法:get,請求參數:sel    [only,many]   不能為空,通過 only 或 many 來獲取分類靜態參數還是動態參數 

因為請求參數sel  需要傳遞動態或者靜態,所以把Tabs標簽的name值改為相對應的many 和 only

<!--添加動態參數的面板-->
<el-tab-pane label="動態參數" name="many">

<!--添加靜態屬性的面板-->
<el-tab-pane label="靜態屬性" name="only">

// 被激活的標簽的名稱,默認為many
activeName: 'many'

在級聯選擇框選中三級分類時,請求獲取分類參數列表數據,所以在cateChanged函數中添加代碼:

// 級聯選擇框選中項變化,會觸發這個函數
async cateChanged() {
      // 證明選中的不是三級分類
      if (this.selectedCateKeys.length !== 3) {
        this.selectedCateKeys = []
        return
      }
      // 證明選中的是三級分類
      console.log(this.selectedCateKeys)
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
},

10、切換Tabs面板后,重新獲取參數列表數據

把根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表這些操作單獨為一個函數,然后級聯選擇框選中項變化和切換tabs標簽時都調用這個函數

// 級聯選擇框選中項變化,會觸發這個函數
cateChanged() {
      // 證明選中的不是三級分類
      if (this.selectedCateKeys.length !== 3) {
        this.selectedCateKeys = []
        return
      }
      // 證明選中的是三級分類
      console.log(this.selectedCateKeys)
      this.getParamsList()
},
// tab標簽的點擊事件處理函數
handleTabClick() {
      // console.log(this.activeName)
      this.getParamsList()
},
// 獲取參數的列表數據
async getParamsList() {
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
}

11、將獲取到的參數列表數據掛載到對應的數據源上

在獲取到參數列表數據后,還要判斷是動態參數還是靜態屬性的,然后賦值給對應的數組:

manyTableData: [], // 動態參數的數據列表
onlyTableData: [] // 靜態屬性的數據列表

// 獲取參數的列表數據
async getParamsList() {
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
      if (this.activeName === 'many') {
        this.manyTableData = res.data
      } else {
        this.onlyTableData = res.data
      }
}

12、渲染動態參數和靜態屬性的Table表格

添加代碼:

<!--動態參數表格-->
<el-table :data="manyTableData" border stripe>
            <!--展開列-->
            <el-table-column type="expand">
            </el-table-column>
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column label="參數名稱" prop="attr_name"></el-table-column>
            <el-table-column label="操作">
              <!-- 作用域插槽 -->
              <template slot-scope="scope">
                <el-button size="mini" type="primary" icon="el-icon-edit">編輯</el-button>
                <el-button size="mini" type="danger" icon="el-icon-delete">刪除</el-button>
              </template>
            </el-table-column>
</el-table>

<!--靜態屬性表格-->
<el-table :data="onlyTableData" border stripe>
            <!--展開列-->
            <el-table-column type="expand">
            </el-table-column>
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column label="屬性名稱" prop="attr_name"></el-table-column>
            <el-table-column label="操作">
              <!-- 作用域插槽 -->
              <template slot-scope="scope">
                <el-button size="mini" type="primary" icon="el-icon-edit">編輯</el-button>
                <el-button size="mini" type="danger" icon="el-icon-delete">刪除</el-button>
              </template>
            </el-table-column>
</el-table>

此時效果圖:

13、渲染添加參數的對話框

添加動態參數和靜態屬性,共用一個對話框,就需要添加計算屬性做一些判斷

先添加一個計算屬性函數:

// 動態計算添加參數對話框標題的文本
titleText() {
      if (this.activeName === 'many') {
        return '動態參數'
      } else {
        return '靜態屬性'
      }
}

添加對話框代碼:

<!--參加參數的對話框-->
<el-dialog :title="'添加' + titleText" :visible.sync="addDialogVisible"
      width="50%" @close="addDialogClosed">
      <!--內容主體區域-->
      <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="90px">
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="addForm.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="addDialogVisible = false">確 定</el-button>
      </span>
</el-dialog>

<script>
export default {
  data() {
    return {
      addDialogVisible: false, // 控制添加參數對話框是否顯示
      // 添加參數的表單數據對象
      addForm: {
        attr_name: ''
      },
      // 添加表單的驗證規則對象
      addFormRules: {
        attr_name: [
          { required: true, message: '請輸入參數名稱', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    // 監聽 添加參數對話框的關閉事件
    addDialogClosed() {
      // 表單內容重置為空
      this.$refs.addFormRef.resetFields()
    }
  }
}
</script>

點擊添加參數按鈕的效果圖:

 

14、完成動態參數和靜態屬性的添加操作

調用api的添加動態參數或者靜態屬性接口,請求路徑:categories/:id/attributes,請求方法:post,
請求參數:
attr_name 參數名稱 不能為空
attr_sel [only,many] 不能為空
ttr_vals 如果是 many 就需要填寫值的選項,以逗號分隔 【可選參數】

先填寫要添加的參數名稱,然后點擊確定按鈕做表單的預校驗,當預校驗成功后,發起網絡請求,向服務添加對應的參數

先給確定按鈕添加點擊事件:

<el-button type="primary" @click="addParams">確 定</el-button>

addParams事件函數:

// 點擊確認 添加新的參數
addParams() {
      // console.log(this.addForm)
      this.$refs.addFormRef.validate(async valid => {
        // 預校驗
        if (!valid) return
        const { data: res } = await this.$http.post(
          `categories/${this.cateId}/attributes`,
          { attr_name: this.addForm.attr_name, attr_sel: this.activeName }
        )
        if (res.meta.status !== 201) {
          return this.$message.error('添加參數失敗!')
        }
        this.$message.success('添加參數成功!')
        this.getParamsList()
        this.addDialogVisible = false
      })
}

效果圖:

15、渲染編輯修改參數的對話框

 給編輯按鈕添加點擊事件:

<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog">編輯</el-button>
showEditDialog函數:
// 監聽 展示編輯參數的對話框
showEditDialog(id) {
      this.editDialogVisible = true
}

復制添加參數對話框的代碼,修改為編輯對話框:

<!--編輯參數的對話框-->
<el-dialog
      :title="'編輯' + titleText"
      :visible.sync="editDialogVisible"
      width="50%" @close="editDialogClosed"
    >
      <!--內容主體區域-->
      <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="90px">
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="editForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <!--底部按鈕區域-->
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editParams">確 定</el-button>
      </span>
</el-dialog>

<script>
export default {
  data() {
    return {
      editDialogVisible: false, // 控制編輯參數對話框是否顯示
      // 編輯參數的表單數據對象
      editForm: {}
    }
  },
  methods: {
    // 監聽 展示編輯參數的對話框
    showEditDialog() {
      this.editDialogVisible = true
    },
    // 監聽 編輯參數對話框的關閉事件
    editDialogClosed() {
      // 表單內容重置為空
      this.$refs.editFormRef.resetFields()
    },
    // 點擊確認 編輯修改參數
    editParams() {

    }
  }
}
</script>

16、完成修改參數的操作

先調用api的根據 ID 查詢參數接口,請求路徑:categories/:id/attributes/:attrId,請求方法:get,
請求參數:
attr_sel  [only,many]  不能為空 
attr_vals  如果是 many 就需要填寫值的選項,以逗號分隔

修改編輯按鈕:

<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.attr_id)">編輯</el-button>

完善showEditDialog代碼:

// 監聽 展示編輯參數的對話框
async showEditDialog(attrId) {
      const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${attrId}`, { params: { attr_sel: this.activeName } })
      if (res.meta.status !== 200) {
        return this.$message.error('查詢參數信息失敗')
      }
      this.editForm = res.data
      this.editDialogVisible = true
},

修改參數后,需要調用api的編輯提交參數接口,請求路徑:categories/:id/attributes/:attrId,請求方法:put,
請求參數:
attr_name 新屬性的名字 不能為空,攜帶在`請求體`中
attr_sel 屬性的類型[many或only] 不能為空,攜帶在`請求體`中
attr_vals 參數的屬性值 可選參數,攜帶在`請求體`中

點擊確定按鈕做表單的預校驗,當預校驗成功后,發起網絡請求,向服務提交修改的參數:

// 點擊確認 編輯修改參數
editParams() {
      this.$refs.editFormRef.validate(async valid => {
        if (!valid) return
        // 可以發起修改參數信息的網絡請求
        const { data: res } = await this.$http.put(
          `categories/${this.cateId}/attributes/${this.editForm.attr_id}`,
          { attr_name: this.editForm.attr_name, attr_sel: this.activeName })
        if (res.meta.status !== 200) {
          return this.$message.error('編輯參數信息失敗!')
        }
        this.$message.success('編輯參數信息成功!')
        this.getParamsList()
        this.editDialogVisible = false
      })
}

效果圖:

17、完成刪除參數的操作

給刪除按鈕添加點擊事件:

<el-button size="mini" type="danger" icon="el-icon-delete"
@click="delParamsDialog(scope.row.attr_id)">刪除</el-button>

調用api的刪除參數接口,請求路徑: categories/:id/attributes/:attrid,請求方法:delete

// 根據id刪除參數對話框
async delParamsDialog(arrtId) {
      // console.log(arrtId)
      // 彈框 詢問用戶是否刪除
      const confirmResult = await this.$confirm('此操作將永久刪除該參數, 是否繼續?', '提示', {
        confirmButtonText: '確定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)

      // 如果用戶確認刪除,則返回值為字符串 confirm
      // 如果用戶取消刪除,則返回值為字符串 cancel
      // console.log(confirmResult)
      if (confirmResult !== 'confirm') {
        return this.$message.info('已取消刪除')
      }
      // console.log('確認刪除')
      // 發起刪除參數的網絡請求
      const { data: res } = await this.$http.delete(`categories/${this.cateId}/attributes/${arrtId}`)
      if (res.meta.status !== 200) {
        return this.$message.error('刪除參數信息失敗!')
      }
      this.$message.success('刪除參數信息成功!')
      this.getParamsList()
}

效果圖:

18、渲染參數下的可選項

后台返回的數據中attr_vals字段參數給的是字符串類型,不能進行循環渲染,所以要進行改造:

循環data中的每一項,把attr_vals參數的字符串,重新賦值為attr_vals數組,在進行for循環渲染

修改getParamsList函數,在獲取所有參數項后,以空格分隔attr_vals:

// 獲取參數的列表數據
async getParamsList() {
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
      // 循環data中的每一項,把attr_vals參數的字符串,重新賦值為item.attr_vals數組
      res.data.forEach(item => {
        item.attr_vals = item.attr_vals.split(' ')
      })

      if (this.activeName === 'many') {
        this.manyTableData = res.data
      } else {
        this.onlyTableData = res.data
      }
},

然后在展開列中進行for循環渲染;

<!--展開列-->
<el-table-column type="expand">
           <template slot-scope="scope">
                <el-tag v-for="(item, i) in scope.row.attr_vals" :key="i"
                closable>{{item}}</el-tag>
           </template>
</el-table-column>

此時點擊展開列的效果圖:

19、解決attr_vals字段為空字符時的小bug

當attr_vals字段為空時,會顯示一個帶X的空tag標簽,因為空字符串以空格分割時,會返回一個數組,包含一個空字符串,所以就會渲染出一個空白的tag標簽

還是在getParamsList函數中,加一個判斷:

// 獲取參數的列表數據
async getParamsList() {
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
      // 循環data中的每一項,把attr_vals參數的字符串,重新賦值為item.attr_vals數組
      res.data.forEach(item => {
        // if (item.attr_vals.length === 0) return
        // item.attr_vals = item.attr_vals.split(' ')
        item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
      })

      if (this.activeName === 'many') {
        this.manyTableData = res.data
      } else {
        this.onlyTableData = res.data
      }
},

20、控制按鈕與文本框的切換顯示

添加代碼:

<!--輸入文本框-->
 <el-input class="input-new-tag" v-if="inputVisible"
   v-model="inputValue" ref="saveTagInput" size="small"
   @keyup.enter.native="handleInputConfirm"
   @blur="handleInputConfirm"></el-input>
<!--添加的按鈕-->
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>

<script>
export default {
  data() {
    return {
      inputVisible: false, // 控制按鈕與文本框的切換顯示
      inputValue: '' // 文本框中輸入的內容
    }
  },
  methods: {
    // 文本框失去焦點或按下回車鍵時都會觸發
    handleInputConfirm() {
      console.log('ok')
    },
    // 點擊按鈕展示文本輸入框
    showInput() {
      this.inputVisible = true
    }
  }
}
</script>

<style lang="less" scoped>
.input-new-tag {
    width: 120px;
}
</style>

@keyup.enter.native 表示按下鍵盤的回車鍵

@blur 表示失去焦點的時候

21 、為每一行數據提供單獨的inputVisible和inputValue

在獲取所有參數的getParamsList函數中給每個item單獨添加:

// 獲取參數的列表數據
async getParamsList() {
      // 根據所選分類的id 和當前所處的面板,獲取對應的參數數據列表
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        { params: { sel: this.activeName } }
      )
      if (res.meta.status !== 200) {
        return this.$message.error('獲取參數列表失敗')
      }
      console.log(res.data)
      // 循環data中的每一項,把attr_vals參數的字符串,重新賦值為item.attr_vals數組
      res.data.forEach(item => {
        // if (item.attr_vals.length === 0) return
        // item.attr_vals = item.attr_vals.split(' ')
        item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
        // 控制文本框的顯示與隱藏
        item.inputVisible = false
        // 文本框中輸入的值
        item.inputValue = ''
      })

      if (this.activeName === 'many') {
        this.manyTableData = res.data
      } else {
        this.onlyTableData = res.data
      }
},

記得要把data里定義的inputVisible和inputValue刪除掉,因為這里已經定義了。

然后修改代碼:

<!--輸入文本框-->
<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>
<!--添加的按鈕-->
<el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>

showInput函數修改:

// 點擊按鈕展示文本輸入框
showInput(row) {
      row.inputVisible = true
}

現在就不會聯動了,效果圖:

22、讓文本框自動獲得焦點

在showInput函數里添加代碼:

// 點擊按鈕展示文本輸入框
showInput(row) {
      row.inputVisible = true
      // 讓文本框自動獲得焦點
      // $nextTick 方法的作用:就是當頁面上元素被重新渲染之后,才會執行回調中的代碼
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
}

23、實現文本框與按鈕的切換顯示

修改代碼:

<!--輸入文本框-->
<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>

handleInputConfirm函數添加代碼:

// 文本框失去焦點或按下回車鍵時都會觸發
handleInputConfirm(row) {
      // trim() 去除字符串兩端的空格
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ''
        row.inputVisible = false
        return
      }
      // 如果沒有return,則證明輸入的內容,需要做后續處理
      console.log('ok')
},

24、完成參數可選項的添加操作

先把row.inputValue的值push到row.attr_vals中,然后發起網絡請求

調用api的編輯提交參數接口,請求路徑:categories/:id/attributes/:attrId,請求方法:put
請求參數:
attr_name 新屬性的名字 不能為空,攜帶在`請求體`中
attr_sel 屬性的類型[many或only] 不能為空,攜帶在`請求體`中
attr_vals 參數的屬性值 可選參數,攜帶在`請求體`中

繼續完善handleInputConfirm函數:

// 文本框失去焦點或按下回車鍵時都會觸發
async handleInputConfirm(row) {
      // trim() 去除字符串兩端的空格
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ''
        row.inputVisible = false
        return
      }
      // 如果沒有return,則證明輸入的內容,需要做后續處理
      row.attr_vals.push(row.inputValue.trim())
      row.inputValue = ''
      row.inputVisible = false
      // 發起請求保存操作
      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('添加修改參數項成功!')
},

此時效果圖:

25、刪除參數下的可選項

給el-tag標簽綁定close事件:

<!--循環渲染tag標簽-->
<el-tag v-for="(item, i) in scope.row.attr_vals" :key="i"
                closable @close="handleClosed(scope.row, i)">{{item}}</el-tag>

函數handleClosed:

// 根據索引刪除對應參數的可選項
async handleClosed(row, i) {
      // console.log(row)
      // console.log(i)
      row.attr_vals.splice(i, 1)
      // 發起請求保存操作
      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('添加修改參數項成功!')
}

發現保存操作的代碼重復了,可以單獨提出來寫一個函數,獨立出來后記得把上面的handleInputConfirm函數也修改下:

// 文本框失去焦點或按下回車鍵時都會觸發
handleInputConfirm(row) {
      // trim() 去除字符串兩端的空格
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ''
        row.inputVisible = false
        return
      }
      // 如果沒有return,則證明輸入的內容,需要做后續處理
      row.attr_vals.push(row.inputValue.trim())
      row.inputValue = ''
      row.inputVisible = false
      // 發起請求保存操作
      this.saveAttrVals(row)
},
// 將對 attr_vals 的操作保存到數據庫
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('添加修改參數項成功!')
},
// 根據索引刪除對應參數的可選項
handleClosed(row, i) {
      // console.log(row)
      // console.log(i)
      row.attr_vals.splice(i, 1)
      // 發起請求保存操作
      this.saveAttrVals(row)
}

效果圖:

26、小bug清空表格數據

因為我們設置了只允許選中三級分類,但是當選中三級分類后,又選中二級分類時,下面表格中的三級數據還有顯示。

修改cateChanged函數:

// 級聯選擇框選中項變化,會觸發這個函數
cateChanged() {
      // 證明選中的不是三級分類
      if (this.selectedCateKeys.length !== 3) {
        this.selectedCateKeys = []
        this.manyTableData = []
        this.onlyTableData = []
        return
      }
      // 證明選中的是三級分類
      console.log(this.selectedCateKeys)
      this.getParamsList()
},

27、完成靜態屬性表格中的展開列效果

把動態參數的展開列代碼,復制一份,粘貼到靜態屬性的展開列中就可以了。

<!--展開列-->
<el-table-column type="expand">
           <template slot-scope="scope">
                <!--循環渲染tag標簽-->
                <el-tag v-for="(item, i) in scope.row.attr_vals" :key="i"
                closable @close="handleClosed(scope.row, i)">{{item}}</el-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>

ok,測試可以沒問題。

28、將本地goods_params分支的代碼推送到遠程

查看分支:

git branch

查看狀態:

git status

保存到暫存區:

git add .

提交到本地倉庫:

git commit -m "完成了分類參數的開發"

推送到遠程:

git push

合並到master:

git checkout master
git merge goods_params
git push

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM