vue-cli+elementui搭建单页面后台demo(table,form,router,组件传值)(以及中途遇到的 npm打包、axios,第三方插件等问题)

1、前台展示

首页:

首页

添加页:

添加音频模态框
添加专辑模态框

音频列表页:

音频列表模态框

修改页:

修改

数据统计页:

数据统计
数据统计 分类

vue可使用 <script> 引入,

这里使用的是npm vue-cli命令行形式:

代码

1.代码结构

代码结构

2.具体代码

App.vue 正常引入项目组件

<template>
  <div id="app">
    <bar></bar>
  </div>
</template>
 
<script>
import bar from "./components/Bar";
export default {
  name: "App",
  components: {
    bar
  }
};
</script>
 
<style>
#app .el-table {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 12px;
}
.el-table td, .el-table th{
  padding: 1px 0;
}
</style>

main.js 全局环境引入
注意:css文件引入的位置很重要,决定打包后的自定义 样式覆盖问题

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import 'element-ui/lib/theme-chalk/index.css'  
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
 
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

router/index.js 路由配置文件

import Vue from 'vue'
import Router from 'vue-router'
import CateSort from '@/components/routerTemplate/CateSort'
import DataAnalysis from '@/components/routerTemplate/DataAnalysis'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'CateSort',
      component: CateSort
    },
    {
      path: '/CateSort/:id',
      name: 'CateSort',
      component: CateSort
    },
    {
      path: '/DataAnalysis',
      name: 'DataAnalysis',
      component: DataAnalysis
    }
  ]
})

自定义主要组件(页面展示):

Bar.vue 头部导航栏 ,主要的含路由的地方

<template>
  <div>
    <el-menu :default-active="this.$route.path" router mode="horizontal">
      <el-menu-item index="1">
        <a href="http:/*****n/index.php" target="_blank">首页</a>
      </el-menu-item>
      <el-submenu index="2">
        <template slot="title">{{ check }}</template>
        <el-menu-item index="/CateSort/34">故事</el-menu-item>
        <el-menu-item index="/CateSort/35">儿歌</el-menu-item>
      </el-submenu>
      <el-menu-item>
        <a href="http://******_album.php" target="_blank">待审核专辑</a>
      </el-menu-item>
      <el-menu-item index="/DataAnalysis">数据统计</el-menu-item>
    </el-menu>
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
  </div>
</template>
 
<script>
//el-menu开启路由时 :default-active="this.$route.path" router   ,路由地址替换index中
export default {
  name: "Bar",
  data() {
    return {
      api_url: "htt******ory.php",
      activeIndex: "4",
      check: '分类'
    };
  },
  methods: {}
};
</script>

catesort.vue 专辑分类列表页(默认展示首页)

<template>
  <div>
    <el-row class="toolList">
      <el-input size="small" placeholder="请输入内容" v-model="tableInit.keyword" class="input"></el-input>
      <el-button icon="el-icon-search" size="small" @click="searchKeyword()">搜索</el-button>
      <el-button type="primary" size="small" @click="addNew()">添加</el-button>
    </el-row>
    <el-table :data="tableData" style="width: 100%" height="650" border>
      <el-table-column prop="id" label="ID" min-width="2" align="center"></el-table-column>
      <el-table-column prop="name" label="专辑名" min-width="5"></el-table-column>
      <el-table-column label="封面图" min-width="3" align="center">
        <template slot-scope="scope">
          <img :src="scope.row.pic" width="50" height="50" class="head_pic" />
        </template>
      </el-table-column>
      <el-table-column prop="desc" label="简介" min-width="10"></el-table-column>
      <!-- <el-table-column prop="user_num" label="用户数" min-width="2" align="center"></el-table-column> -->
      <el-table-column prop="real_num" label="收听数" min-width="3" align="center"></el-table-column>
      <el-table-column prop="cate_name" label="分类" min-width="3" align="center"></el-table-column>
      <el-table-column prop="age_name" label="年龄段" min-width="3" align="center"></el-table-column>
      <el-table-column prop="recom" label="排序" min-width="2" align="center"></el-table-column>
      <el-table-column min-width="8" align="center" label="操作">
        <template slot-scope="scope">
          <el-button size="mini" @click="openModify(scope.$index, scope.row)">修改</el-button>
          <el-button size="mini" @click="mp3List(scope.$index, scope.row)">音频列表</el-button>
          <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 主体表格 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="tableInit.currentPage"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="tableInit.limit"
      layout="total, sizes, prev, pager, next, jumper"
      :total="tableInit.total"
    ></el-pagination>
    <!-- 页码 -->
    <el-dialog
      title="新增音频/专辑"
      width="50%"
      top="5vh"
      :visible.sync="dialogTableVisible"
      center
      :append-to-body="true"
      :lock-scroll="false"
      :close-on-click-modal="false"
    >
      <UploadForm></UploadForm>
    </el-dialog>
    <!-- 新增dialog -->
    <el-dialog
      :title="dialogModify.title"
      width="50%"
      top="5vh"
      :visible.sync="dialogModify.Visible"
      center
      :append-to-body="true"
      :lock-scroll="false"
      :close-on-click-modal="false"
      :before-close="resetForm"
    >
      <ModifyForm :albumInfo="dialogModify.albumInfo" v-on:childByValue="childByValue"></ModifyForm>
    </el-dialog>
    <!-- 修改专辑dialog -->
    <el-dialog
      :title="dialogMp3List.title"
      width="80%"
      top="2vh"
      :visible.sync="dialogMp3List.Visible"
      center
      :append-to-body="true"
      :lock-scroll="false"
      :close-on-click-modal="false"
      :before-close="resetForm"
    >
      <AudioList :mp3Info="dialogMp3List.mp3Info" v-on:childByValue="childByValue"></AudioList>
    </el-dialog>
    <!-- 音频列表dialog -->
  </div>
</template>
 
<script>
import axios from "axios";
import UploadForm from "../cateTemplate/UploadForm";
import ModifyForm from "../cateTemplate/ModifyForm";
import AudioList from "../cateTemplate/AudioList";
export default {
  name: "Bar",
  components: { UploadForm, ModifyForm, AudioList }, //新增专辑、音频页面
  data() {
    return {
      api_url: "http://*****ry.php",
      tableInit: {
        limit: 10,
        currentPage: 1,
        cate: 34,
        total: 900,
        keyword: "" //搜索关键词
      },
      tableData: [], //表格数据
      dialogTableVisible: false, //模态框状态
      dialogModify: {
        Visible: false, //修改模态框状态
        title: "",
        albumInfo: {}
      },
      dialogMp3List: {
        Visible: false, //mp3list修改模态框状态
        title: "",
        albumInfo: {}
      }
    };
  },
  created: function() {
    var that = this;
    that.tableInit.cate = that.$route.params.id;
    that.changeCateOrPage(1);
  },
  watch: {
    $route(to, from) {
      var that = this;
      that.tableInit.cate = that.$route.params.id;
      that.tableInit.currentPage = 1;
      that.tableInit.keyword = "";
      that.changeCateOrPage(1);
    }
  },
  methods: {
    childByValue: function(childValue) {
      // childValue就是子组件传过来的值
      this.dialogModify.Visible = childValue;
    },
    //修改模态框关闭时回掉
    resetForm(done) {
      //this.$refs["modifyForm"].resetFields();
      done();
    },
    //删除功能
    handleDelete(a, b) {
      var that = this;
      that
        .$confirm("此操作将删除该专辑, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
        .then(() => {
          axios
            .get(that.api_url, {
              params: {
                method: "delete_album",
                id: b.id
              }
            })
            .then(function(response) {
              that.tableData.splice(a, 1);
              if (response.data.ret) {
                that.$message({
                  duration: 1000,
                  message: response.data.msg,
                  type: "success"
                });
              } else {
                that.$message.error(response.data.msg);
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        })
        .catch(() => {
          that.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },
    //搜索功能
    searchKeyword() {
      var that = this;
      that.tableInit.currentPage = 1;
      that.changeCateOrPage(1);
    },
    //显示新增专辑音频组件
    addNew() {
      this.dialogTableVisible = true; //默认页面不显示为false,点击按钮将这个属性变成true
    },
    //显示修改专辑组件
    openModify(a, b) {
      var that = this;
      that.$nextTick(() => {
        that.dialogModify.Visible = true; //默认页面不显示为false,点击按钮将这个属性变成true
        that.dialogModify.title = "《" + b.name + "》修改";
        that.dialogModify.albumInfo = b;
      });
    },
    //展示mp3list
    mp3List(a, b) {
      var that = this;
      that.$nextTick(() => {
        that.dialogMp3List.Visible = true; //默认页面不显示为false,点击按钮将这个属性变成true
        that.dialogMp3List.title = "《" + b.name + "》音频列表";
        that.dialogMp3List.mp3Info = b;
      });
    },
    //修改每页条数
    handleSizeChange(val) {
      var that = this;
      that.tableInit.limit = val;
      that.tableInit.currentPage = 1;
      that.changeCateOrPage(1);
    },
    //翻页
    handleCurrentChange(val) {
      var that = this;
      that.changeCateOrPage(val);
    },
    changeCateOrPage(page) {
      var that = this;
      axios
        .get(that.api_url, {
          params: {
            method: "get_story_album_list",
            cate: that.tableInit.cate,
            page: page,
            limit: that.tableInit.limit,
            keyword: that.tableInit.keyword
          }
        })
        .then(function(response) {
          that.tableData = response.data.data;
          that.tableInit.total = Number(response.data.count);
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  }
};
</script>
<style>
.toolList {
  padding-top: 5px;
  padding-bottom: 5px;
}
.input {
  width: 200px !important;
}
</style>

cateTemplate/uploadform.vue 新增页面
注意form表单提交时 post方式以及数据类型需要调整调整 qs

<template>
  <el-form
    :rules="rules"
    ref="form"
    :model="form"
    :hide-required-asterisk="true"
    label-width="80px"
  >
    <el-form-item label="类型">
      <el-switch
        v-model="form.delivery"
        active-text="新增专辑"
        inactive-text="新增音频"
        @change="typeChange"
      ></el-switch>
    </el-form-item>
    <!-- 操作分类 -->
    <div v-if="form.delivery">
      <el-form-item label="封面图">
        <el-upload
          class="avatar-uploader"
          accept="image/jpg, image/jpeg"
          :action="api_url"
          :data="{method:'upload',type:'images'}"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <div
            slot="tip"
            class="el-upload__tip"
            style="line-height: 5px;"
          >注意:请上传jpg/jpeg类型,且宽高比为1:1 的图片</div>
          <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar">
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      <el-form-item label="专辑名" prop="name">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="专辑描述" prop="desc">
        <el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="form.desc"></el-input>
      </el-form-item>
      <el-form-item label="分类" prop="album">
        <el-select v-model="form.album" placeholder="请选择专辑分类">
          <el-option label="故事" value="34"></el-option>
          <el-option label="儿歌" value="35"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="年龄段" prop="age">
        <el-select v-model="form.age" placeholder="请选择年龄段">
          <el-option label="孕期" value="1"></el-option>
          <el-option label="0-3岁" value="2"></el-option>
          <el-option label="3-6岁" value="3"></el-option>
        </el-select>
      </el-form-item>
    </div>
    <!-- 新增专辑 -->
    <div v-else>
      <el-row>
        <el-col :span="7">
          <el-form-item label="专辑名">
            <el-select v-model="album" placeholder="请选择分类" @change="searchAlbum">
              <el-option label="故事" value="34"></el-option>
              <el-option label="儿歌" value="35"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="album_id" label-width="10px">
            <el-select v-model="form.album_id" filterable placeholder="请选择专辑">
              <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
    </div>
    <el-form-item label="音频文件">
      <el-upload
        class="upload-demo"
        ref="upload"
        accept="audio/mpeg"
        :action="api_url"
        :data="{method:'upload',type:'mp3'}"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-success="handelSuccess"
        :file-list="fileList"
        :auto-upload="true"
        :multiple="true"
      >
        <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
        <div slot="tip" class="el-upload__tip">注意:多选,音频文件名即是在app播放列表中音频名,请确定好文件名再上传!</div>
      </el-upload>
    </el-form-item>
    <!-- 添加音频 -->
    <el-form-item>
      <el-button type="primary" @click="submitForm('form')">立即提交</el-button>
      <!-- <el-button @click="resetForm()">重置</el-button> -->
    </el-form-item>
    <!-- 提交 -->
  </el-form>
</template>
<script>
import { type } from "os";
import axios from "axios";
import qs from "qs";
export default {
  data() {
    return {
      api_url: "http******y.php",
      album: "",
      fileList: [],
      //表单数据
      form: {
        name: "",
        desc: "",
        delivery: false,
        imageUrl: "",
        album_id: "",
        mp3_url_arr: []
      },
      options: "",
      //验证规则
      rules: {
        name: [
          { required: true, message: "请输入专辑名称", trigger: "blur" },
          { min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" }
        ],
        age: [{ required: true, message: "请选择年龄段", trigger: "change" }],
        album: [{ required: true, message: "请选择分类", trigger: "change" }],
        album_id: [
          { required: true, message: "请选择特定专辑", trigger: "change" }
        ],
        desc: [{ required: true, message: "请填写专辑描述", trigger: "blur" }]
      }
    };
  },
  methods: {
    //获取专辑列表
    searchAlbum(cate_id) {
      var that = this;
      axios
        .get(that.api_url, {
          params: {
            method: "get_album",
            cate_id: cate_id
          }
        })
        .then(function(response) {
          that.options = response.data.data;
        })
        .catch(function(error) {
          console.log(error);
        });
    },
    //类型修改重置表单值
    typeChange(type) {
      this.$refs["form"].resetFields();
    },
    //封面图方法
    handleAvatarSuccess(res, file) {
      //this.form.imageUrl = URL.createObjectURL(file.raw);
      if (res.code) {
        this.form.imageUrl = res.data.url;
        this.$message({
          message: res.msg,
          type: "success"
        });
      } else {
        this.$message({
          message: res.msg,
          type: "warning"
        });
      }
    },
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg";
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    //音频方法
    handleRemove(file, fileList) {
      this.form.mp3_url_arr = [];
      fileList.forEach(item => {
        this.form.mp3_url_arr.push({
          name: item.response.data.name,
          url: item.response.data.url,
          dura: item.response.data.dura
        });
      });
    },
    handlePreview(file) {
      console.log(file);
    },
    handelSuccess(response, file, fileList) {
      this.form.mp3_url_arr.push({
        name: response.data.name,
        url: response.data.url,
        dura: response.data.dura
      });
    },
    //提交
    submitForm(formName) {
      var that = this;
      this.$refs[formName].validate(valid => {
        if (valid) {
          if (that.form.delivery && that.form.imageUrl == "") {
            this.$message({
              message: "封面图不能为空!",
              type: "warning"
            });
            return false;
          }
 
          axios
            .post(
              that.api_url,
              qs.stringify({
                method: "save_story",
                form_data: that.form
              }),
              {
                headers: { "Content-Type": "application/x-www-form-urlencoded" } //post
              }
            )
            .then(function(response) {
              if (response.data.ret) {
                that.$message({
                  duration: 1000,
                  message: response.data.msg,
                  type: "success",
                  onClose: function() {
                    window.location.reload();
                  }
                });
              } else {
                that.$message.error(response.data.msg);
              }
            })
            .catch(function(error) {
              console.log(error);
            });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm() {
      this.$message({
        duration: 1000,
        message: "ceshihhhhhhh",
        type: "success",
        onClose: function() {
          window.location.reload();
        }
      });
    }
  }
};
</script>
 
<style>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.avatar {
  width: 100px;
  height: 100px;
  display: block;
}
</style>

cateTemplate/AudioList.vue、modifyForm.vue、modifyBoxForm.vue 与新增表单相似
音频 audio标签的使用

      <el-table-column label="音频" min-width="8" align="center">
        <template slot-scope="scope">
          <audio ref="audio" controls="controls" type="audio/mpeg" :src="scope.row.high_url"></audio>
        </template>
      </el-table-column>

DataAnalysis.vue 数据统计组件,简单的列表页

<template>
  <div>
    <el-table :data="tableData" style="width: 100%" height="650" border>
      <el-table-column prop="day" label="日期" min-width="2" align="center"></el-table-column>
      <el-table-column prop="view_num" label="收听数" min-width="5"></el-table-column>
      <el-table-column prop="user_num" label="用户量" min-width="3" align="center"></el-table-column>
      <el-table-column min-width="5" align="center" label="操作">
        <template slot-scope="scope">
          <el-button size="mini" @click="openDetail(scope.$index, scope.row)">详情</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 主体表格 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="tableInit.currentPage"
      :page-sizes="[50, 100]"
      :page-size="tableInit.limit"
      layout="total, sizes, prev, pager, next, jumper"
      :total="tableInit.total"
    ></el-pagination>
    <!-- 页码 -->
    <el-dialog
      :title="dialogModify.title"
      width="98%"
      top="1vh"
      :visible.sync="dialogModify.Visible"
      center
      :append-to-body="true"
      :lock-scroll="false"
      :close-on-click-modal="false"
      :before-close="resetForm"
    >
      <LogDetail :day="dialogModify.day" v-on:childByValue="childByValue"></LogDetail>
    </el-dialog>
    <!-- 修改专辑dialog -->
  </div>
</template>
 
<script>
import axios from "axios";
import LogDetail from "../logTemplate/LogDetail";
export default {
  components: { LogDetail},
  data() {
    return {
      api_url: "http://b***ory.php",
      tableInit: {
        limit: 50,
        currentPage: 1,
        cate: 34,
        total: 900,
        keyword: "" //搜索关键词
      },
      tableData: [], //表格数据
      dialogModify: {
        Visible: false, //修改模态框状态
        day: "",
      }
    };
  },
  created: function() {
    var that = this;
    that.changePage(1);
  },
  watch: {
  },
  methods: {
    childByValue: function(childValue) {
      // childValue就是子组件传过来的值
      this.dialogModify.Visible = childValue;
    },
    //修改模态框关闭时回掉
    resetForm(done) {
      //this.$refs["modifyForm"].resetFields();
      done();
    },
    //显示修改专辑组件
    openDetail(a, b) {
      var that = this;
      that.$nextTick(() => {
        that.dialogModify.Visible = true; //默认页面不显示为false,点击按钮将这个属性变成true
        that.dialogModify.title = '详情';
        that.dialogModify.day = b.day;
      });
    },
    //修改每页条数
    handleSizeChange(val) {
      var that = this;
      that.tableInit.limit = val;
      that.tableInit.currentPage = 1;
      that.changePage(1);
    },
    //翻页
    handleCurrentChange(val) {
      var that = this;
      that.changePage(val);
    },
    changePage(page) {
      var that = this;
      axios
        .get(that.api_url, {
          params: {
            method: "get_story_log_list",
            page: page,
            limit: that.tableInit.limit
          }
        })
        .then(function(response) {
          that.tableData = response.data.data;
          that.tableInit.total = Number(response.data.count);
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  }
};
</script>
<style>
.toolList {
  padding-top: 5px;
  padding-bottom: 5px;
}
.input {
  width: 200px;
}
</style>

LogDetail.vue 专辑排行 与 音频排行组件 主要是两张表,以及切换日期。

<template>
  <div>
    <el-row class="f_row">
      <el-col :span="2" v-for="(item,i) in dated_list" :key="i">
        <el-button
          v-if="i === check"
          type="primary"
          size="mini"
          round
          @click="changeDay(item,i)"
        >{{ item }}</el-button>
        <el-button v-else size="mini" round @click="changeDay(item,i)">{{ item }}</el-button>
      </el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="11">
        <AlbumLog :day="detailDay"></AlbumLog>
      </el-col>
      <el-col :span="13">
        <BoxLog :day="detailDay"></BoxLog>
      </el-col>
    </el-row>
  </div>
</template>
 
<script>
import axios from "axios";
import AlbumLog from "./AlbumLog";
import BoxLog from "./BoxLog";
export default {
  props: {
    day: {}
  },
  components: { AlbumLog, BoxLog },
  data() {
    return {
      api_url: "http://b*****ry.php",
      dated_list: [],
      detailDay: "",
      check: 2
    };
  },
  created: function() {
    var that = this;
    that.detailDay = that.day;
    that.getDated(that.day);
  },
  watch: {
    day(newValue, oldValue) {
      var that = this;
      that.day = newValue;
      that.detailDay = newValue;
      that.getDated(newValue);
    }
  },
  methods: {
    childByValue: function(childValue) {
      // childValue就是子组件传过来的值
      this.dialogModify.Visible = childValue;
    },
    //修改模态框关闭时回掉
    resetForm(done) {
      //this.$refs["modifyForm"].resetFields();
      done();
    },
    //切换日期
    changeDay(day, i) {
      var that = this;
      that.detailDay = day;
      that.check = i;
    },
    //获取日期
    getDated(day) {
      var that = this;
      axios
        .get(that.api_url, {
          params: {
            method: "get_dated",
            day: day
          }
        })
        .then(function(response) {
          that.dated_list = response.data;
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  }
};
</script>
<style>
.f_row {
  padding-bottom: 5px;
}
.el-table {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 12px;
}
.el-link {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 12px;
}
</style>

BoxLog.vue 与 AlbumLog.vue 结构一样

<template>
  <div>
    <el-table :data="tableData" style="width: 100%" height="600" border>
      <el-table-column type="index" width="40%"></el-table-column>
      <el-table-column prop="box_id" label="id" min-width="3" align="center"></el-table-column>
      <el-table-column prop="box_name" label="音频名" min-width="5"></el-table-column>
      <el-table-column prop="view_num" label="收听数" min-width="3" align="center"></el-table-column>
      <el-table-column prop="cate_name" label="分类" min-width="3" align="center"></el-table-column>
      <el-table-column prop="age_name" label="年龄" min-width="3" align="center"></el-table-column>
      <el-table-column prop="album_name" label="专辑名" min-width="5">
        <template slot-scope="scope">
          <el-link type="primary"  @click="openAlbumBox(scope.$index, scope.row)">{{ scope.row.album_name }}</el-link>
        </template>
      </el-table-column>
    </el-table>
    <!-- 主体表格 -->
  
    <el-dialog
      :title="dialogModify.title"
      width="75%"
      top="2vh"
      :visible.sync="dialogModify.Visible"
      center
      :append-to-body="true"
      :lock-scroll="false"
      :close-on-click-modal="false"
      :before-close="resetForm"
    >
      <AlbumBox :ListInfo="dialogModify.ListInfo" v-on:childByValue="childByValue"></AlbumBox>
    </el-dialog>
    <!-- 修改专辑dialog -->
  </div>
</template>
 
<script>
import axios from "axios";
import AlbumBox from "./AlbumBox";
export default {
  props: {
    day: {}
  },
  components: {AlbumBox},
  data() {
    return {
      api_url: "http:/*****tory.php",
      tableInit: {
        limit: 100,
        currentPage: 1,
        cate: 34,
        total: 900,
        keyword: "" //搜索关键词
      },
      tableData: [], //表格数据
      dialogModify: {
        Visible: false, //修改模态框状态
      }
    };
  },
  created: function() {
    var that = this;
    that.changePage(1);
  },
  watch: {
    day(newValue, oldValue) {
      var that = this;
      that.day = newValue;
      that.changePage(1);
    }
  },
  methods: {
    childByValue: function(childValue) {
      // childValue就是子组件传过来的值
      this.dialogModify.Visible = childValue;
    },
    //修改模态框关闭时回掉
    resetForm(done) {
      //this.$refs["modifyForm"].resetFields();
      done();
    },
    //显示专辑音频列表
    openAlbumBox(a, b) {
      var that = this;
      b.day = that.day;
      that.$nextTick(() => {
        that.dialogModify.Visible = true; //默认页面不显示为false,点击按钮将这个属性变成true
        that.dialogModify.title = "《"+b.album_name+"》"+b.age_name+","+b.cate_name;
        that.dialogModify.ListInfo = b;
      });
    },
    //修改每页条数
    handleSizeChange(val) {
      var that = this;
      that.tableInit.limit = val;
      that.tableInit.currentPage = 1;
      that.changePage(1);
    },
    //翻页
    handleCurrentChange(val) {
      var that = this;
      that.changePage(val);
    },
    changePage(page) {
      var that = this;
      axios
        .get(that.api_url, {
          params: {
            method: "get_story_box_log_list",
            page: page,
            limit: that.tableInit.limit,
            day: that.day
          }
        })
        .then(function(response) {
          that.tableData = response.data.data;
          that.tableInit.total = Number(response.data.count);
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  }
};
</script>
<style>
.toolList {
  padding-top: 5px;
  padding-bottom: 5px;
}
</style>

2、问题:

打包遇到的问题

a、npm run build 打包时存储目录需要修改:
config文件夹下的index.js

    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),
 
    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',//修改为相对路径当前文件夹下

b、修改build-webpack.base.conf.js,解决引入字体图标,比如font-awesome的图标路径出错的问题,在webpack.base.conf.js里面修改limit要改大,把10000改为90000。

规范性验证!!!

去除eslint验证,修改修改webpack.base.conf.js,注释下面那行! 或者在初始化的时候不选择eslint

    rules: [
      // ...(config.dev.useEslint ? [createLintingRule()] : []),
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },

引入element-ui(文档很清楚)

element-ui

加载element-ui:

npm install element-ui --save-dev 
#或者 npm i element-ui -S

配置element-ui: 在main.js中引入element.js和样式

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'   //引入element
import 'element-ui/lib/theme-chalk/index.css'
//import axios from 'axios'
//import VueAxios from 'vue-axios'
 
Vue.config.productionTip = false
//Vue.use(ElementUI,VueAxios,axios)
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

webpack打包进行丑化压缩遇到(TypeError: Cannot read property 'compilation' of undefined)问题

安装环境的使用一定要-save-dev或者是-save!!!!

版本升级或降级

1、npm i uglifyjs-webpack-plugin@1.0.0 --save
 
2、npm i optimize-css-assets-webpack-plugin@2 --save

Vue axios发post请求后台接收不到参数(有多种方式,这里使用qs转换):

【引入 qs ,这个库是 axios 里面包含的,不需要再下载了】

import qs from 'qs'
          axios
            .post(
              that.api_url,
              qs.stringify({
                method: "save_story",
                form_data: that.form
              }),
              {
                headers: { "Content-Type": "application/x-www-form-urlencoded" } //post
              }
            )
            .then(function(response) {
              console.log(response.data);
              if (response.data.ret) {
                that.$message({
                  duration: 1000,
                  message: response.data.msg,
                  type: "success",
                  onClose: function() {
                    window.location.reload();
                  }
                });
              } else {
                that.$message.error(response.data.msg);
              }
            })
            .catch(function(error) {
              console.log(error);
            });
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342