Vue中实现图标选择器

可选择elementUI中所有的图标和自定义导入的svg图标

效果图:

首先要有这一节的基础:https://blog.csdn.net/qq_40323256/article/details/116950679 

项目gitee代码:https://gitee.com/LiDaJiang/git_vue2_koa2_mongoose_iconpicker

核心代码如下所示:

@/components/IconPicker/eIcon.vue:

<template>
  <div>
    <i v-if="iconName.startsWith('el-icon')" :class="iconName" style="font-size:20px"></i>
    <svg-icon v-else :name="iconName" width="20px" height="20"></svg-icon>
  </div>
</template>

<script>
export default {
  name: "eIcon",
  props: {
    iconName: {
      type: String,
      required: true
    }
  }
};
</script>

@/components/IconPicker/index.vue:

<!--IconPickder-->
<template>
  <div class="IconPickder">
    <el-popover width="600" trigger="click">
      <div style="max-height:400px;overflow-y: scroll;overflow-x:hidden">
        <el-button
          plain
          v-for="(item,index) in iconList"
          :key="index"
          style="margin:2px;"
          @click="iconName=item"
        >
          <eIcon :iconName="item"></eIcon>
        </el-button>
      </div>

      <el-button slot="reference">
        <span v-if="iconName==''">请选择图标</span>
        <span v-else>
          <eIcon :iconName="iconName"></eIcon>
        </span>
      </el-button>
    </el-popover>
    <el-button type="text" v-show="iconName!==''" @click="iconName=''" style="margin-left:5px">清空</el-button>
  </div>
</template>

<script>
import eIcon from "./eIcon";
export default {
  name: "IconPicker",

  components: { eIcon },
  props: {
    icon: String
  },

  data() {
    return {
      iconName: this.icon,
      iconList: [
        "el-icon-platform-eleme",
        "el-icon-eleme",
        "el-icon-delete-solid",
        "el-icon-delete",
        "dashboard",
        "eye"
      ]
    };
  },
  mounted() {
    this.iconList = [...this.$svgIcons, ...this.$elementIcons];
  },
  watch: {
    icon: {
      handler: function(newValue) {
        this.iconName = newValue;
      }
    },
    iconName: {
      handler: function(value) {
        this.$emit("iconName", value);
      }
    }
  }
};
</script>

@/views/icon/iconDialog.vue:

<!--iconDialog   -->
<template>
  <div class="iconDialog">
    <el-dialog :title="dialog.title" width="45%" :visible.sync="dialog.show">
      <el-form ref="ref_form_icon" :model="formData" label-width="100px">
        <el-form-item label="图标" prop="icon">
          <IconPicker v-model="formData.icon" :icon="formData.icon" @iconName="getIconName"></IconPicker>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialog.show = false">取 消</el-button>
        <el-button
          v-if="dialog.option == 'add'"
          @click="addIcon('ref_form_icon')"
          type="primary"
        >确 定</el-button>
        <el-button
          v-if="dialog.option == 'edit'"
          @click="editIcon('ref_form_icon')"
          type="primary"
        >确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
 
<script>
import IconPicker from "@/components/IconPicker";

export default {
  name: "iconDialog",
  components: { IconPicker },
  props: ["dialog", "formData"],
  methods: {
    getIconName(value) {
      this.formData.icon = value;
    },
    addIcon() {
      this.$emit("addIcon");
    },
    editIcon() {
      this.$emit("editIcon");
    }
  }
};
</script>

@/views/icon/index.vue:

<!--icon-->
<template>
  <div class="icon">
    <el-card>
      <div style="margin-bottom: 10px">
        <el-button sizi="mini" @click="handleAdd()" type="primary" icon="el-icon-plus">新增</el-button>
      </div>
      <el-table :data="tableData" border>
        <el-table-column prop="icon" label="图标" align="center" width="70">
          <template slot-scope="scope">
            <div v-if="scope.row.icon">
              <i
                v-if="scope.row.icon.startsWith('el-icon')"
                :class="scope.row.icon"
                style="font-size:20px"
              ></i>
              <svg-icon v-else :name="scope.row.icon" width="20px" height="20"></svg-icon>
            </div>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template slot-scope="scope">
            <el-button size="mini" @click="showEditDialog(scope.row)">
              <i class="el-icon-edit" /> 编辑
            </el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
              <i class="el-icon-delete" /> 删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <iconDialog :dialog="dialog" :formData="formData" @addIcon="addIcon" @editIcon="editIcon"></iconDialog>
  </div>
</template>
 
<script>
import IconDialog from "./iconDialog.vue";
import { addIcon, getIconList, editIcon, deleteIcon } from "@/api/icon/index";
export default {
  name: "icon",
  components: { IconDialog },
  data() {
    return {
      dialog: {
        show: false,
        title: ""
      },
      formData: {},
      tableData: [
        {
          icon: ""
        }
      ]
    };
  },
  mounted() {
    this.getIconList();
  },
  computed: {},
  methods: {
    //获取icon列表
    async getIconList() {
      let { data } = await getIconList();
      this.tableData = data.data;
    },

    //打开新增icon窗口
    handleAdd() {
      this.dialog = {
        show: true,
        title: "新增icon",
        option: "add"
      };
      this.formData = {
        icon: ""
      };
    },
    //打开编辑icon窗口
    showEditDialog(row) {
      this.dialog = {
        show: true,
        title: "编辑图标",
        option: "edit"
      };
      this.formData = {
        _id: row._id,
        icon: row.icon
      };
    },
    //新增icon
    async addIcon() {
      await addIcon(this.formData);
      this.dialog.show = false;
      this.$notify({
        title: "成功",
        message: "新增icon成功!",
        type: "success"
      });
      this.getIconList();
    },
    //编辑icon
    async editIcon() {
      await editIcon(this.formData, this.formData._id);
      this.dialog.show = false;
      this.$notify({
        title: "成功",
        message: "编辑icon成功!",
        type: "success"
      });
      this.getIconList();
    },
    //删除icon
    handleDelete(row) {
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          this.$message({
            type: "success",
            message: "删除成功!"
          });
          await deleteIcon(row._id);
          this.getIconList();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    }
  }
};
</script>
 

@/utils/icons.js:

export const svgIcons = ["dashboard", "eye", "link", "nested", "password", "table", "tree", "user"]//自己手动添加要导入的svg名,要和@/icons/中的svg对应
export const elementIcons = ["platform-eleme", "eleme", "delete-solid", "delete", "s-tools", "setting", "user-solid", "user", "phone", "phone-outline", "more", "more-outline", "star-on", "star-off", "s-goods", "goods", "warning", "warning-outline", "question", "info", "remove", "circle-plus", "success", "error", "zoom-in", "zoom-out", "remove-outline", "circle-plus-outline", "circle-check", "circle-close", "s-help", "help", "minus", "plus", "check", "close", "picture", "picture-outline", "picture-outline-round", "upload", "upload2", "download", "camera-solid", "camera", "video-camera-solid", "video-camera", "message-solid", "bell", "s-cooperation", "s-order", "s-platform", "s-fold", "s-unfold", "s-operation", "s-promotion", "s-home", "s-release", "s-ticket", "s-management", "s-open", "s-shop", "s-marketing", "s-flag", "s-comment", "s-finance", "s-claim", "s-custom", "s-opportunity", "s-data", "s-check", "s-grid", "menu", "share", "d-caret", "caret-left", "caret-right", "caret-bottom", "caret-top", "bottom-left", "bottom-right", "back", "right", "bottom", "top", "top-left", "top-right", "arrow-left", "arrow-right", "arrow-down", "arrow-up", "d-arrow-left", "d-arrow-right", "video-pause", "video-play", "refresh", "refresh-right", "refresh-left", "finished", "sort", "sort-up", "sort-down", "rank", "loading", "view", "c-scale-to-original", "date", "edit", "edit-outline", "folder", "folder-opened", "folder-add", "folder-remove", "folder-delete", "folder-checked", "tickets", "document-remove", "document-delete", "document-copy", "document-checked", "document", "document-add", "printer", "paperclip", "takeaway-box", "search", "monitor", "attract", "mobile", "scissors", "umbrella", "headset", "brush", "mouse", "coordinate", "magic-stick", "reading", "data-line", "data-board", "pie-chart", "data-analysis", "collection-tag", "film", "suitcase", "suitcase-1", "receiving", "collection", "files", "notebook-1", "notebook-2", "toilet-paper", "office-building", "school", "table-lamp", "house", "no-smoking", "smoking", "shopping-cart-full", "shopping-cart-1", "shopping-cart-2", "shopping-bag-1", "shopping-bag-2", "sold-out", "sell", "present", "box", "bank-card", "money", "coin", "wallet", "discount", "price-tag", "news", "guide", "male", "female", "thumb", "cpu", "link", "connection", "open", "turn-off", "set-up", "chat-round", "chat-line-round", "chat-square", "chat-dot-round", "chat-dot-square", "chat-line-square", "message", "postcard", "position", "turn-off-microphone", "microphone", "close-notification", "bangzhu", "time", "odometer", "crop", "aim", "switch-button", "full-screen", "copy-document", "mic", "stopwatch", "medal-1", "medal", "trophy", "trophy-1", "first-aid-kit", "discover", "place", "location", "location-outline", "location-information", "add-location", "delete-location", "map-location", "alarm-clock", "timer", "watch-1", "watch", "lock", "unlock", "key", "service", "mobile-phone", "bicycle", "truck", "ship", "basketball", "football", "soccer", "baseball", "wind-power", "light-rain", "lightning", "heavy-rain", "sunrise", "sunrise-1", "sunset", "sunny", "cloudy", "partly-cloudy", "cloudy-and-sunny", "moon", "moon-night", "dish", "dish-1", "food", "chicken", "fork-spoon", "knife-fork", "burger", "tableware", "sugar", "dessert", "ice-cream", "hot-water", "water-cup", "coffee-cup", "cold-drink", "goblet", "goblet-full", "goblet-square", "goblet-square-full", "refrigerator", "grape", "watermelon", "cherry", "apple", "pear", "orange", "coffee", "ice-tea", "ice-drink", "milk-tea", "potato-strips", "lollipop", "ice-cream-square", "ice-cream-round"].map(s => "el-icon-" + s);

 

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值