1. 程式人生 > 實用技巧 >商品分類管理和引數管理(五)

商品分類管理和引數管理(五)

實現的功能

功能 詳述
商品分類管理 渲染元件和子路由;佈局;渲染樹形表格渲染級聯選擇器重置表單
分類引數_分類 渲染元件和子路由;佈局,警告;獲取和渲染商品分類到級聯選擇器;渲染Tab分割槽面板計算屬性控制按鈕禁用
分類引數_引數 獲取渲染分類引數資料列表;新增引數(動態渲染對話方塊文字,控制級聯選擇器只能選一級和二級);重置表單;表單預校驗發起請求;修改引數;刪除引數
引數下可選項 渲染可選項(按鈕和文字框動態切換);新增可選項;刪除可選項

使用到的Element-ui元件

元件名稱_EN 註冊 備註
Cascader Vue.use(Cascader) 級聯選擇器
Alert Vue.use(Alert) 警告
Tabs Vue.use(Tabs) 標籤頁
TabPane Vue.use(TabPane)

使用到的依賴

執行依賴:vue-table-with-tree-grid

// [main.js]
// 匯入樹形佈局
import TreeTable from 'vue-table-with-tree-grid'
// 註冊為全域性可用元件
Vue.component('tree-table', TreeTable)

商品分類管理

1.渲染元件和子路由

2.佈局

①麵包屑導航

②卡片檢視

③分頁

3.獲取渲染商品分類列表

①獲取許可權商品分類列表

②渲染許可權商品分類列表

1️⃣樹形表格

:data:資料來源

:columns:表格各列配置

​ label:列標題名稱

​ prop:列內容的屬性名

​ type:自定義模板列template

:selection-type="false":去除複選框

:expand-type="false":去除展開行

show-index:資料索引列

index-text="#":資料索引列標題

:show-row-hover="false":高亮效果

<!-- [Cate.vue] -->
<!-- 表格區域 -->
<tree-table :data="catelist" :columns="columns":selection-type="false" :expand-type="false" show-index index-text="#" border :show-row-hover="false>
   <!-- ...... --> 
   <!-- 模板列 --> 
    <template slot="opt">
        <el-button type="primary" icon="el-icon-edit" size="mini">編輯</el-button>
        <el-button type="danger" icon="el-icon-delete" size="mini">刪除</el-button>
    </template>
</tree-table>
// [Cate.vue -> data]
// 為table指定列的定義
columns: [
    {
        label: '分類名稱',
        prop: 'cat_name',
    },
    // ......
    {
        label: '操作',
        // 將當前列定義為模板列
        type: 'template',
        // 表示當前這一列使用模板名稱
        template: 'opt',
    },
],

4、新增分類

①展示新增分類對話方塊

②獲取父級分類列表

③渲染新增分類表單

1️⃣父級分類級聯選擇器

options:資料來源

props:配置物件

<!-- [Cate.vue] -->
<!-- options指定資料來源 props指定配置物件 -->
<el-cascader
             :options="parentCateList"
             :props="cascaderProps"
             v-model="selectedKeys"
             @change="parentCateChanged"
             clearable
             ></el-cascader>
// [Cate.vue -> data]
// 父級分類列表
parentCateList: [],
// 指定級聯選擇器的配置物件
cascaderProps: {
    value: 'cat_id',
    label: 'cat_name',
    children: 'children',
    checkStrictly: true,
    expandTrigger: 'hover',
},
// 選中的父級分類的id陣列
selectedKeys: []
/* [assets/css/global.css] */
.el-cascader-panel{ 
    height: 300px; 
}

④新增分類

1️⃣根據父級分類的變化處理資料

// [Cate.vue -> data]
// 新增分類的表單資料物件
addCateForm: {
    // 分類名稱
    cat_name: '',
    // 父級分類的id
    cat_pid: 0,
    // 分類等級,預設1級分類
    cat_level: 0,
}
    
// [Cate.vue -> methods]       
// 選擇項發生變化觸發這個函式
parentCateChanged() {
	// 如果selectedKeys 陣列中>0 證明選中了父級分類
	if (this.selectedKeys.length > 0) {
        // 父級分類的id
    	this.addCateForm.cat_pid = this.selectedKeys[
            this.selectedKeys.length - 1
        ]
        // 當前分類的等級
        this.addCateForm.cat_level = this.selectedKeys.length
        return
    } else {
        this.addCateForm.cat_pid = 0
        this.addCateForm.cat_level = 0
    }
}
          

2️⃣點選按鈕新增新的分類 預校驗

⑤重置表單

// [Cate.vue -> methods]
// 監聽對話方塊關閉 重置表單
addCateDialogClosed() {
    this.$refs.addCateFormRef.resetFields()
    // 級聯選擇器
    this.selectedKeys = []
    this.addCateForm.cat_pid = 0
    this.addCateForm.cat_level = 0
}

分類引數管理

動態引數,靜態屬性

1.渲染元件和子路由

2.佈局

①麵包屑導航

②卡片檢視

③警告

<!-- [Params.vue] -->
<!-- 警告 -->
<el-alert title="注意:只允許為第三級分類設定相關引數!" type="warning" :closable="false" show-icon></el-alert>

3.獲取渲染商品【分類】資料列表

①獲取商品分類資料列表

②渲染商品分類資料列表

1️⃣級聯選擇器

2️⃣Tab分割槽面板

name:啟用的面板name

@tab-click="handleTabClick":點選時觸發

<!-- [Params.vue] -->
<!-- tab頁 -->
<el-tabs v-model="activeName" @tab-click="handleTabClick">
    <!-- 新增動態引數 -->
    <el-tab-pane label="動態引數" name="many"></el-tab-pane>
    <!-- 新增靜態屬性 -->
    <el-tab-pane label="靜態屬性" name="only"></el-tab-pane>
</el-tabs>

3️⃣計算屬性控制按鈕禁用

級聯選擇器未選中三級分類

<!-- [Params.vue] -->
<el-button
           type="primary"
           size="mini"
           :disabled="isBtnDisable"
           @click="addDialogVisible=true"
           >新增引數</el-button>
// [Params.vue -> computed]
computed: {
    // 按鈕是否禁用,是true 否false
    isBtnDisable() {
        if (this.selectedCateKeys.length !== 3) {
            return true
        }
        return false
    }
}

4、獲取渲染分類【引數】資料列表

①獲取分類引數資料列表

1️⃣計算屬性,三級分類Id

// [Params.vue -> computed]
// 當前選中的三級分類的id
cateId() {
    if (this.selectedCateKeys.length === 3) {
        return this.selectedCateKeys[2]
    }
    return null
}

2️⃣在級聯選擇器發生變化時發起請求

3️⃣在Tab分割槽面板發生變化時發起請求

4️⃣處理獲取的資料,分為兩個陣列儲存

// [Params.vue -> methods]
if (this.activeName === 'many') {
    this.manyTableData = res.data
} else {
    this.onlyTableData = res.data
}

②渲染商品分類資料列表

1️⃣表格

2️⃣展開行

5、新增引數

①展示新增對話方塊

②渲染新增對話方塊和表單

1️⃣對話方塊標題文字

// [Params.vue -> computed]
// 動態計算標題文字
titleText() {
    if (this.activeName === 'many') {
        return '動態引數'
    } else {
        return '靜態屬性'
    }
}
<!-- [Params.vue] -->
<el-dialog :title="'新增'+titleText"></el-dialog>

2️⃣級聯選擇器只能選一級和二級

// [Params.vue -> methods]
// 級聯選中項,變化會觸發
handleChange() {
    this.getParamsData()
},
// 獲取引數列表資料
async getParamsData() {
    // 選中的不是三級分類
    if (this.selectedCateKeys.length !== 3) {
        this.selectedCateKeys = []
        // 清空表格資料 避免級聯選擇器和tab分割槽資料衝突
        this.manyTableData = []
        this.onlyTableData = []
        return
    }
    // ......
}

③重置表單

④表單預校驗,校驗通過發起請求

請求結束,再重新整理列表,this.getParamsData()

6、修改引數

①展示修改對話方塊

②渲染修改表單

根據id查詢引數,並渲染到修改表單中

③表單驗證規則editFormRules

④表單重置

⑤表單預校驗,校驗通過發起請求

7、刪除引數

①彈框詢問 刪除使用者

8、渲染引數下可選項

①處理可選項

// [Params.vue -> methods]
res.data.forEach((item) => {
    item.attr_vals = item.attr_vals ? item.attr_vals.split(',') : []
    // ......
})

②渲染可選項

1️⃣展開行+作用域插槽

2️⃣動態編輯標籤,解決共用引數

每一行使用自己的引數inputVisible

// [Params.vue -> data]
// 文字框 按鈕切換
inputVisible: false,
// 文字框輸入內容
inputValue: []

// [Params.vue -> methods]
async getParamsData() {
    // ......
    res.data.forEach((item) => {
        // ......
        // 控制文字框顯示和隱藏
        item.inputVisible = false
        // 文字框輸入值
        item.inputValue = ''
    })
    // ......
}
<!-- [Params.vue] -->
<!-- 輸入文字框 -->
<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>
// [Params.vue -> methods]
// 文字框失去焦點或按下enter
async handleInputConfirm(row) {
    // ......
    row.inputVisible = false
},
// 點選按鈕展示
showInput(row) {
    row.inputiVisible = true
    // ......
}

3️⃣文字框自動獲取焦點

$nextTick:當頁面上元素被重新渲染之後,才會執行回撥函式中的程式碼

inputiVisible置為true時,input可能還沒被渲染出來

// [Params.vue -> methods]
// 點選按鈕展示
showInput(row) {
    // ......
    // 文字框自動獲得焦點
    this.$nextTick((_) => {
        this.$refs.saveTagInput.$refs.input.focus()
    })
},

③新增可選項

文字框​失去焦點時,判斷合法,處理輸入

// [Params.vue -> methods]
// 文字框失去焦點或按下enter
async 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)
}
// [Params.vue -> methods]
// 發起請求 儲存操作
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('修改引數項成功')
},

④刪除可選項

<!-- [Params.vue] -->
<el-tag
        v-for="(item,i) in scope.row.attr_vals"
        :key="i"
        closable
        @close="handleClose(i,scope.row)"
        >{{item}}</el-tag>
// [Params.vue -> methods]
// 刪除對應引數可選項
handleClose(i, row) {
    row.attr_vals.splice(i, 1)
    this.saveAttrVals(row)
},