橙紫皮专用(项目实现 思路)breaking news

闭包

在这里插入图片描述

深(新的全部)浅(地址第一层)拷贝

在这里插入图片描述

git 命令

请添加图片描述

样式 老项目 ~@ 现在脚手架项目 @

在这里插入图片描述
在这里插入图片描述

背景图问题 设置高度

在这里插入图片描述

AAA大事件项目

思路:
1.配置vue脚手架
2.创建项目,npm操作上传初始化项目

AAA001注册功能

引入配置路由 router
在这里插入图片描述
配置子组件
在这里插入图片描述

在这里插入图片描述

elementUI 使用方法

主体登录模块 from表单 input ico图标
在这里插入图片描述

匹配密码是否一致 from表单验证
在这里插入图片描述
axios 根据文档来设置请求和 判断 响应在这里插入图片描述

注册成功—>登录跳转 登录模块

1.相同的设置主体结构
2.校验数据输入
3.校验数据和数据库是否一致
4.实现登录成功功能 判断
5.登录成功跳转

在这里插入图片描述

6.将获取的token存起来## 登陆成功---->跳转首页

在这里插入图片描述

首页退出功能

根据elementui构建侧边栏,点击退出功能
//1.判断是否要退出
//2.销毁token
//3.跳转到登录页面
在这里插入图片描述
vuex修改值的mutations
在这里插入图片描述

1.先在vuex获取数据并传给 userinfo
1.1获取到数据

在这里插入图片描述
1.2把值调用修改数据
1.3把获取的值赋值给空值(来接收修改的数据)
在这里插入图片描述

Main.vue 组件的 created 生命周期函数中,调用 Vuex 中的 initUserInfo 函数,获取用户的基本信息:
Main.vue 组件中,基于 mapState 辅助函数,把 Vuex 中的 userInfo 数据映射到当前组件中使用:
在这里插入图片描述

在这里插入图片描述

首页模块

头部

在这里插入图片描述
侧边栏 获取数据渲染到页面

<!-- 侧边栏区域 -->
      <el-aside width="200px">
          <div class="user-box">
                <img :src="userinfo.user_pic" alt="" v-if="userinfo.user_pic" />
                <img src="../../assets/logo.png" alt=""  v-else/>
                <span>欢迎:{
    
    {
    
    userinfo.nickname||userinfo.username}}</span>
          </div>
           <el-menu
                default-active="/home"
                class="el-menu-vertical-demo"
                background-color="aqua"
                text-color="#fff"
                active-text-color="#409EFF"
                unique-opened
                router
                >
                <template v-for="item in  menus">
                    <!-- 不包含子菜单的“一级菜单” -->
                <el-menu-item :index="item.indexPath" :key="item.indexPath" v-if="!item.children"><i class="el-icon-s-tools"></i>{
    
    {
    
    item.title}}</el-menu-item>
                <!-- 包含子菜单的“一级菜单” -->
                <el-submenu :index="item.indexPath" :key="item.indexPath" v-else>
                    <template slot="title">
                    <i :class="item.icon"></i>
                    <span>{
    
    {
    
    item.title}}</span>
                    </template>
                    <el-menu-item :index="subItem.indexPath" v-for="subItem in item.children" :key="subItem.indexPath"><i :class="subItem.icon"></i>{
    
    {
    
    subItem.title}}</el-menu-item>
                </el-submenu>
                </template>
            </el-menu>
          </el-aside>
      <el-container>

多次axios获取token 解决方法axios请求拦截

**1.删除请求头在这里插入图片描述

优化身份认证的过程 2.在main.js里面添加拦截**

目标:掌握使用拦截器简化 Token 认证的能力

  1. 在调用获取用户基本信息获取左侧菜单接口时,不再单独提供 headers下的 Authorization 请求头。

  2. 在项目入口文件 main.js 中,配置 axios 的请求拦截器:
    在这里插入图片描述

3.(没有token)判断是否在有token的状态下,才能进入登录成功的状态.在这里插入图片描述

4.(有token) 跳转到登录页面

不合法的token 根据合法的token 才能发送ajax
在这里插入图片描述
2.通过响应拦截器判断token是否合法
设置axios响应拦截器
在这里插入图片描述

获取用户数据(并修改不会造成直接修改state数据)

在这里插入图片描述

点击重置 ----->点击修改

1.考虑到重置是获取上一次的数据
在这里插入图片描述
修改数据put 后需要更新vuex组件最新的数据

在这里插入图片描述

图片的同步

在这里插入图片描述

<template>
      <el-card class="box-card">
        <template v-slot:header>
          <div class="clearfix">
            <span>更换头像</span>
          </div>
        </template>
    <div>
      <!-- 图片,用来展示用户选择的头像 -->
      <img :src="avatar" alt=""  v-if="avatar"/>
      <img src="@/assets/images/avatar.jpg" v-else/>

      <!-- 按钮区域 -->
      <div class="btn-box">
        <!-- 1.书写input:file的表单项,并且让他隐藏 -->
          <input type="file" accrpt="image/*" style="display:none" ref="iptRef" @change="onIptChange">
        <el-button type="primary" icon="el-icon-plus" @click="chooseImg" >选择图片</el-button>
        <el-button type="success" icon="el-icon-upload" :disabled="avatar===''" @click="uploadImg" >上传头像</el-button>
      </div>
    </div>
      </el-card>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      avatar: ''
    }
  },
  name: 'UserAvtatar',
  methods: {
    
    
    chooseImg () {
    
    
      this.$refs.iptRef.click()
    },
    onIptChange (e) {
    
    
      //  console.dir(e.target)
      if (e.target.files.length === 0) {
    
    
        // 没有图片
        this.avatar = ''
      } else {
    
    
        // 选择了一张图片   图片对象--> base64 格式的字符串
        // e.target.files[0]
        // 1. new dileReader() 文件读取器(浏览器自带的)
        const reader = new FileReader()
        // 2.读取图片对象
        reader.readAsDataURL(e.target.files[0])
        // 3. 监听onload文件读取完毕事件
        reader.onload = () => {
    
    
        //   console.log(reader.result)
        // 头像预览赋值
          this.avatar = reader.result
        }
      }
    },
    async  uploadImg () {
    
    
      // 4.图片上传
      const {
    
     data: res } = await this.$http.patch('/my/update/avatar', {
    
     avatar: this.avatar })
      //   console.log(res)
      if (res.code !== 0) return this.$message.error('上传头像失败!')
      this.$message.success('上传成功')
      // 再次通知vuex获取用户信息 // 上传头像成功
      this.$store.dispatch('initUserInfo')
    }
  }
}
</script>

<style>

</style>

重置密码

1.配置动态rules 校验表单
在这里插入图片描述
2.验证密码框是否一致
在这里插入图片描述
3.手动校验 patch请求传送新密码 自定义检测新旧密码是否相同检测两次新密码是否一致的校验规则
在这里插入图片描述

4.重置密码
在这里插入图片描述

文章分类

<template>
  <div>
    <el-card class="box-card">
      <div slot="header" class="clearfix header-box">
        <span>文章分类</span>
        <el-button type="primary" size="mini" @click="dialogVisible = true">添加分类</el-button>
      </div>
     <el-table :data="cateList" style="width: 100%" borde   stripe>
         <el-table-column type="index" width="50">
        </el-table-column>
        <el-table-column label="序号" width="180"></el-table-column>
        <el-table-column prop="cate_name" label="姓名" width="180">
        </el-table-column>
        <el-table-column prop="cate_alias" label="分类别名">
        </el-table-column>
        <el-table-column label="操作">
            <!-- 设置插槽    {
    
    row}解构对象   -->
         <template  v-slot="{row}">
             <!-- v-slot="scope"   v-slot="{row}"  -->
             <!-- {
    
    {
    
    scope.column}}   {
    
    {
    
    row}} -->
              <el-button size="mini"  type="primary" @click="editCate(row.id)" >修改</el-button>
              <el-button size="mini" type="danger" @click="remove(row.id) ">删除</el-button>
        </template>

      </el-table-column>
     </el-table>
    </el-card>
<!-- 添加文章分类 -->
    <el-dialog   @closed="headerAddClose" title="添加文章分类" :visible.sync="dialogVisible" width="40%">
       <span>
          <el-form  ref="addCloseRef" :model="form" :rules="CateRules" label-width="80px">
             <el-form-item label="分类名称" prop="cate_name">
               <el-input v-model="form.cate_name" autocomplete="off"></el-input>
             </el-form-item>
             <el-form-item label="分类别名" prop="cate_alias" >
                 <el-input v-model="form.cate_alias" autocomplete="off"></el-input>
          </el-form-item>
        </el-form>
       </span>
      <span slot="footer" class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addCate">确 定</el-button>
      </span>
   </el-dialog>

   <!-- 修改文章分类的对话框 -->
<el-dialog title="修改文章分类" :visible.sync="editVisible" width="35%" @closed="handleEditClose">
  <span>
      <!-- 修改的表单 -->
         <el-form :model="editCateForm" :rules="CateRules" ref="editFormRef" label-width="100px">
           <el-form-item label="分类名称" prop="cate_name">
             <el-input v-model="editCateForm.cate_name"></el-input>
           </el-form-item>
           <el-form-item label="分类别名" prop="cate_alias">
             <el-input v-model="editCateForm.cate_alias"></el-input>
           </el-form-item>
         </el-form>
  </span>
  <span slot="footer" class="dialog-footer">
         <el-button size="mini" @click="editVisible = false">取 消</el-button>
         <el-button size="mini" type="primary" @click="alterCate">确 定</el-button>
  </span>
</el-dialog>
  </div>
</template>

<script>
export default {
    
    
  name: 'ArtCate',
  data () {
    
    
    return {
    
    
      editCateForm: [],
      cateList: [],
      //   文章新增分类隐藏
      dialogVisible: false,
      editVisible: false,
      form: {
    
     cate_name: '', cate_alias: '' },
      CateRules: {
    
    
        cate_name: [
          {
    
     required: true, message: '输入名字', trigger: 'blur' },
          {
    
     pattern: /^\S{
    
    1,10}$/, message: '输入名字1~10位非空字符', trigger: 'blur' }],
        cate_alias: [
          {
    
     required: true, message: '输入分类', trigger: 'blur' },
          {
    
     pattern: /^[a-zA-Z0-9]{
    
    1,15}$/, message: '输入名字1~15位字母数字', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    
    
    async initCateList () {
    
    
      const {
    
     data: res } = await this.$http.get('/my/cate/list')
      //   console.log(res)
      if (res.code === 0) {
    
    
        this.cateList = res.data
      }
    },
    // 处理关闭重置
    headerAddClose () {
    
    
      this.$refs.addCloseRef.resetFields()
    }, // 添加分类
    addCate () {
    
    
      this.$refs.addCloseRef.validate(async (valid) => {
    
    
        // 手动校验
        if (!valid) return
        // 发送axios
        const {
    
     data: res } = await this.$http.post('/my/cate/add', this.form)
        // 可以判断不等于0  添加错误提示
        // if (res.code !== 0) return this.$message.error(res.message)
        if (res.code === 0) {
    
    
        // 1.关闭对话框
          this.dialogVisible = false
          // 2.重新获取分类数据
          this.initCateList()
        }
      })
    },
    // 修改数据思路  1.点击根据id来修改数据2.插槽
    // 修改数据
    async  editCate (id) {
    
    
      // id为1或2时  数据不能修改
      if (id === 1 || id === 2) return this.$message.warning('该数据不能不修改')

      //   console.log(id)
      //   axios获取数据  axios.get('地址',{params:参数})     get或delete
      // axios.post(地址,{参数})
      /*   axios({
             url:'请求路径',
             method:'get',
             data: { 'post请求参数'},
             params: { 'get请求参数'}
          }).then(res=>{
             //成功回调
             console.log(res)
          }) */
      const {
    
     data: res } = await this.$http.get('/my/cate/info', {
    
     params: {
    
     id: id } })
      //   console.log(res)
      //   2.赋值
      if (res.code === 0) this.editCateForm = res.data
      console.log(this.editCateForm)
      // 3. 展示对话框
      this.editVisible = true
    },
    // 处理编辑弹出框关闭事件
    handleEditClose () {
    
    
      this.$refs.editFormRef.resetFields()
    },
    // 修改数据成功
    alterCate () {
    
    
      this.$refs.editFormRef.validate(async (valid) => {
    
    
        //   1.手动校验
        if (!valid) return
        //   2. 发送axios更新数据
        const {
    
     data: res } = await this.$http.put('/my/cate/info', this.editCateForm)
        // console.log(res)
        // 3.判断修改数据
        // 失败 res.code !== 0    this.$message.error(res.message)
        if (res.code !== 0) return this.$message.error(res.message)
        // 成功
        this.$message.success(res.message)
        //   this.editCateForm = res.data  ???错误操作
        // 4..重新获取分类数据
        this.initCateList()
      })
      this.editVisible = false
    },
    //  删除数据  根据id删除
    async  remove (id) {
    
    
      if (id === 1 || id === 2) return this.$message.warning('不允许删除')
      // 方法1
      /* // 询问用户是否删除
      const res = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      // 取消
      if (res !== 'confirm') return
      // 确定后
      const { data: result } = await this.$http.delete('/my/cate/del', { params: { id } })
      // 判断后弹框
      if (result.code !== 0) return this.$message.error(result.message)
      // 成功提示
      this.$message.success(result.message)
      // 更新数据
      this.initCateList() */
      // 2.方法2
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
    
    
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
    
    
        this.$message({
    
    

          type: 'success',
          message: '删除成功!'
        })
        this.$http.delete('/my/cate/del', {
    
     params: {
    
     id } })
        this.initCateList()
      }).catch(() => {
    
    
        this.$message({
    
    
          type: 'info',
          message: '已取消删除'
        })
      })
    }
  },
  // 钩子函数 调用
  created () {
    
    
    this.initCateList()
  }

}
</script>

<style lang="less" scoped>
.header-box {
    
    
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

发表文章

<template>
  <div>
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>文章列表</span>
      </div>
      <!-- 搜索区域 -->
      <div class="search-box">
        <el-form :inline="true" :model="q" ref="searchRef">
          <el-form-item label="文章分类">
            <el-select v-model="q.cate_id" placeholder="请选择分类" size="small">
              <el-option :label="item.cate_name" :value="item.id" v-for="item in cateList" :key="item.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="发布状态" style="margin-left: 15px;">
            <el-select v-model="q.state" placeholder="请选择状态" size="small">
              <el-option label="已发布" value="已发布"></el-option>
              <el-option label="草稿" value="草稿"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="small"  @click="search">筛选</el-button>
            <el-button type="info" size="small"  @click="reset">重置</el-button>
          </el-form-item>
        </el-form>
        <!-- 发表文章的按钮    @click="pubDialogVisible=true"   控制span信息显示-->
        <el-button type="primary" size="small" class="btn-pub" @click="pubDialogVisible=true">发表文章</el-button>
      </div>

      <!-- 文章表格区域 -->
       <el-table :data="artList" border  stripe >
          <el-table-column label="文章标题" >
            <template v-slot="{row}">
             <el-link  type="primary" @click="getArtDetail(row.id)">{
    
    {
    
    row.title}}</el-link>
            </template>
          </el-table-column>
          <el-table-column label="文章分类" prop="cate_name"></el-table-column>
          <!-- 格式化时间  作用域插槽  获取时间并渲染 -->
          <el-table-column label="文章时间" ><!--  prop="pub_date"  -->
            <template v-slot="{row}">
              {
    
    {
    
    row.pub_date|dateFormat}}
            </template>
          </el-table-column>
          <el-table-column label="状态" prop="state"></el-table-column>
          <el-table-column label="操作" >
      <template v-slot="{row}">
        <el-button type="danger" size="mini" @click="delArt(row.id)">删除</el-button>
      </template>
          </el-table-column>
       </el-table>
            <!-- 分页区域 -->

            <!--
            current-page  当前页码值
            page-sizes    每一显示条数列表
            page-size     当前每页显示的条数
            layout        分页显示 布局
            total         数据总条数
            size-change   每页显示的条数发生变化时
            current-change页码值改变触发
            -->

        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="q.pagenum"
          :page-sizes="[2, 3, 5, 10]"
          :page-size="q.pagesize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        >
        </el-pagination>
    </el-card>
    <!--  发表文章弹出框发表文章的 Dialog 对话框 -->
<el-dialog @close="onDialogClosed" title="发表文章" :visible.sync="pubDialogVisible" fullscreen :before-close="handleBeforeClose">
 <!--  :before-close="handleClose"点击×触发这个事件(elementui封装的) -->

  <!-- 发布文章的对话框 -->
    <el-form :model="pubForm" :rules="pubFormRules" ref="pubFormRef" label-width="100px">
      <el-form-item label="文章标题" prop="title">
        <el-input v-model="pubForm.title" placeholder="请输入标题"></el-input>
      </el-form-item>
      <el-form-item label="文章分类" prop="cate_id">
        <el-select v-model="pubForm.cate_id" placeholder="请选择分类" style="width: 100%;">
          <el-option :label="item.cate_name" :value="item.id" v-for="item in  cateList" :key="item.id"></el-option>
        </el-select>
    </el-form-item>

             <!-- 富文本编辑器 -->
             <el-form-item label="文章内容" prop="content" >
             <!-- 使用 v-model 进行双向的数据绑定 -->
            <quill-editor v-model="pubForm.content"  ></quill-editor>
    </el-form-item>

    <el-form-item label="文章封面">
          <!-- 用来显示封面的图片 -->
          <img src="@/assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef" />
          <br />
          <!-- 文件选择框,默认被隐藏 -->
          <input @change="onFIleeChange" type="file" style="display: none;" accept="image/*" ref="iptFile" />
          <!-- 选择封面的按钮 -->
          <el-button type="text" @click="choseImg">+ 选择封面</el-button>
    </el-form-item>
        <!-- <el-form-item>  包一个就位置同步了 -->
          <el-button type="primary"  style="margin-left: 100px;" @click="pubArticle('已发布')">发布</el-button>
          <el-button type="info" @click="pubArticle('草稿')">存为草稿</el-button>
            <!-- </el-form-item> -->
         </el-form>

</el-dialog>
<!-- 文章详情弹出框 -->
     <!-- 查看文章详情的对话框 -->
<!-- 查看文章详情的对话框 -->
<el-dialog title="文章预览" :visible.sync="detailVisible" width="80%">
  <h1 class="title">{
    
    {
    
     artDetail.title }}</h1>

  <div class="info">
    <span>作者:{
    
    {
    
     artDetail.nickname || artDetail.username }}</span>
    <span>发布时间:{
    
    {
    
     artDetail.pub_date | dateFormat }}</span>
    <span>所属分类:{
    
    {
    
     artDetail.cate_name }}</span>
    <span>状态:{
    
    {
    
     artDetail.state }}</span>
  </div>

  <!-- 分割线 -->
  <el-divider></el-divider>

  <img :src="'http://www.liulongbin.top:3008' + artDetail.cover_img" alt="" />

  <div v-html="artDetail.content"></div>
</el-dialog>
  </div>
</template>

<script>
import defaultImg from '@/assets/images/cover.jpg'
export default {
    
    
  name: 'ArtList',
  data () {
    
    
    return {
    
    
      // 发表文章弹出框
      pubDialogVisible: false,
      // 查询参数对象
      q: {
    
    
        pagenum: 1,
        pagesize: 2,
        cate_id: '',
        state: ''
      },
      // 发表表单数据
      pubForm: {
    
    
        title: '',
        cate_id: '',
        content: '', // 发布文章 草稿   或者   收集数据 发布
        state: '',
        // 文档初始图片
        cover_img: null
      },
      // 发表表单数据规则
      pubFormRules: {
    
    
        title: [
          {
    
     required: true, message: '请输入文章标题', trigger: 'blur' },
          {
    
     min: 1, max: 30, message: '文章标题的长度为1-30个字符', trigger: 'blur' }
        ],
        cate_id: [{
    
     required: true, message: '请选择文章标题', trigger: 'blur' }],
        content: [{
    
     required: true, message: '请选择文章内容', trigger: 'blur' }]
      },
      // 文章分类
      cateList: [],
      // 文章列表
      artList: [],
      // 文章条数
      total: 0,
      // 控制文章详情对话框的显示与隐藏
      detailVisible: false,
      // 文章的详情信息对象
      artDetail: {
    
    }
    }
  },
  methods: {
    
    
    // 对话框dialog
    async handleBeforeClose (done) {
    
    
      const res = await this.$confirm('你确定要关闭发表文章对话框吗?').catch(err => err)
      //   console.log(res)
      if (res === 'cancel') return
      done()
    },
    async initCateList () {
    
    
      const {
    
     data: res } = await this.$http.get('/my/cate/list')
      //   console.log(res)
      if (res.code === 0) {
    
    
        this.cateList = res.data
      }
    },
    // 点击button触发input上传框
    choseImg () {
    
    
      this.$refs.iptFile.click()
    },
    // cheange   触发内置事件   图片    看文档
    onFIleeChange (e) {
    
    
      console.log(e.target.files)
      const files = e.target.files
      if (files.length === 0) {
    
    
        // 1. 没有图片
        this.pubForm.cover_img = null
        // 没有选择
        // this.$refs.imgRef.src = '../../../assets/images/cover.jpg'  //路径赋值无效后
        // 路径赋值无效后     图片模块导入   defaultImg(先导入图片 在赋值 )
        this.$refs.imgRef.src = defaultImg // 图片模块
      } else {
    
    
        // 2.  获取图片
        this.pubForm.cover_img = files[0]
        // // 图片预览 2种解决方案
        // 方案一: files[0]图片对象  =>img展示(1.base64)(阅览器 new FileReader())
        /*  onIptChange (e) {
                   //  console.dir(e.target)
                   if (e.target.files.length === 0) {
                     // 没有图片
                     this.avatar = ''
                   } else {
                     // 选择了一张图片   图片对象--> base64 格式的字符串
                     // e.target.files[0]
                     // 1. new dileReader() 文件读取器(浏览器自带的)
                     const reader = new FileReader()
                     // 2.读取图片对象
                     reader.readAsDataURL(e.target.files[0])
                     // 3. 监听onload文件读取完毕事件
                     reader.onload = () => {
                     //   console.log(reader.result)
                     // 头像预览赋值
                       this.avatar = reader.result
                     }
                   }
                 }, */
        // 方案二 : 图片地址 (阅览器)
        // 实现 图片预览
        const url = URL.createObjectURL(files[0])
        console.log(url)
        // 将url赋值给img的src属性
        this.$refs.imgRef.src = url
        // this.$refs.imgRef.setAttribute('src', url)
      }
    },
    // 上传文章
    pubArticle (state) {
    
    
      // console.log(state)
      this.pubForm.state = state// 接收传值
      // 手动校验
      this.$refs.pubFormRef.validate(async (valid) => {
    
    
        // 判断文章输入信息是否完全
        if (!valid) return this.$message.warning('输入完全信息')
        // 判断图片上传
        if (!this.pubForm.cover_img) return this.$message.warning('请上传图片')
        // axios 发送请求
        // 看文档 数据转换
        const fd = new FormData()
        // Object.keys() 对象 =>数组   对象中所有的键
        // console.log(Object.keys(this.pubForm))//['title', 'cate_id', 'content', 'state', 'cover_img']
        /*  for (const k in this.pubForm) {
          fd.append(k, this.pubForm[k])
        } */

        // 数据格式转换
        Object.keys(this.pubForm).forEach(item => {
    
    
          fd.append(item, this.pubForm[item])
        })
        // 看fd的值
        /*  console.log(fd)// 出不来
        fd.forEach((value, key) => {
          console.log(key, value)
        }) */

        const {
    
     data: res } = await this.$http.post('/my/article/add', fd)
        console.log(res)
        if (res.code !== 0) return this.$message.error(res.message)
        this.$message.success(res.message)

        // 关闭弹出框
        this.pubDialogVisible = false
        // 刷新数据
        this.initArtList()
      })
    }, // 获取文章列表
    async   initArtList () {
    
    
      const {
    
     data: res } = await this.$http.get('/my/article/list', {
    
     params: this.q })
      // console.log(res)
      // 失败return this.$message.error('获取文章列表失败')
      if (res.code === 0) {
    
    
      // 成功
        this.artList = res.data
        // console.log(this.artList)
        // 文章的条数
        this.total = res.total
      }
    },
    // 关闭弹出框重置表单数据
    onDialogClosed () {
    
    
      this.$refs.pubFormRef.resetFields()
      // this.pubForm.cover_img = null // 1. 没有图片
      this.$refs.imgRef.src = defaultImg // 2.清除视图
      // this.$refs.imgRef.resetFields()   现不了提交清除图片
    },
    // 每页val条  pagesize  发生变化
    handleSizeChange (val) {
    
    
      // console.log(val)
      // 每页条数赋值   只显示第一条
      this.q.pagesize = val
      this.pagesize = 1
      // 重新发请求 刷新数据
      this.initArtList()
    },
    // 当前页val条
    handleCurrentChange (val) {
    
    
      // console.log(val)
      // 页码赋值
      this.q.pagenum = val
      // 重新发请求 刷新数据
      this.initArtList()
    }, // 筛选
    search () {
    
    
      // 解决点击筛选时获取数据 筛选出现bug  所以重置为1
      this.initArtList()
      // 页码赋值
      this.q.pagenum = 1
    },
    // 重置筛选
    reset () {
    
    
      // 清空表单
      this.$refs.searchRef.resetFields()
      // q初始化
      this.q = {
    
    
        pagenum: 1,
        pagesize: 2,
        cate_id: '',
        state: ''
      }
      // 重新获取数据
      this.initArtList()
    },
    // 根据id获取文章详情
    async getArtDetail (id) {
    
    
      // axios请求
      const {
    
     data: res } = await this.$http.get('/my/article/info', {
    
     params: {
    
     id: id } })
      // console.log(res)
      this.artDetail = res.data
      this.detailVisible = true
    },
    /*  try{

    }catch{

    }
 */
    // 根据id删除文章
    async delArt (id) {
    
    
      try {
    
    
        await this.$confirm('你确定要删除吗?')// promise
        // 这里的代码是点击的确定按钮
        const {
    
     data: res } = await this.$http.delete('/my/article/info', {
    
     params: {
    
     id } })
        // 失败
        if (res.code !== 0) return this.$message.error(res.message)
        // 成功
        this.$message.success(res.message)
        // 如果在刷新数据之前,当前页的数据只有 1 条,
        // 而且,当前的页码值 > 1,
        // 则说明当前页已没有数据可显示,需要让页码值 -1
        // 删除优化  当页面中只有一条数据时  展示上一页的数据
        if (this.artList.length === 1 && this.q.pagenum > 1) {
    
    
          this.q.pagenum--
        }

        // 刷新数据
        this.initArtList()
      } catch (err) {
    
    
        // 打印 点击效果
        return err
      }
    }
  },
  created () {
    
    
    this.initCateList()
    this.initArtList()
  }
}
</script>

<style lang="less" scoped>
.title {
    
    
  font-size: 24px;
  text-align: center;
  font-weight: normal;
  color: #000;
  margin: 0 0 10px 0;
}

.info {
    
    
  font-size: 12px;
  span {
    
    
    margin-right: 20px;
  }
}
.el-pagination {
    
    
  margin-top: 15px;
}
.search-box {
    
    
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  .btn-pub {
    
    
    margin-top: 5px;
  }
}
// 设置富文本编辑器的默认最小高度
//vue组件中,不能修改子组件的样式    vue中 css样式穿透 深度选择器(作用域?)
//语法:  /deep/   ::v-deep

/deep/ .ql-editor {
    
    
  min-height: 300px;
}// 设置图片封面的宽高
.cover-img {
    
    
  width: 400px;
  height: 280px;
  object-fit: cover;
}.putbtn{
    
    
 margin-left: 100px;
}

</style>

富文本编辑器

dayjs转换时间

猜你喜欢

转载自blog.csdn.net/qq_43944285/article/details/124815975