前端学习(2451):表单数据的绑定

request.js

<template>
<div class="artical-container">
  <!--卡片-->
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      <!--面包屑导航-->
      <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>

    </div>
    <!--数据-->
    <el-form ref="form" :model="form" label-width="40px" size="mini">
      <el-form-item label="状态">
        <el-radio-group v-model="status">
          <el-radio :label="null">全部</el-radio>
          <el-radio :label="0">草稿</el-radio>
          <el-radio :label="1">待审核</el-radio>
          <el-radio :label="2">审核通过</el-radio>
          <el-radio :label="3">审核失败</el-radio>
          <el-radio :label="4">已删除</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="频道">
        <el-select v-model="channelId" placeholder="请选择频道">
          <el-option label="全部" :value="null"></el-option>
          <el-option :label="channel.name" :value="channel.id" v-for="(channel,index) in channels" :key="index"></el-option>

        </el-select>
      </el-form-item>

      <el-form-item label="日期">
        <el-date-picker
          v-model="rangeDate"
          type="datetimerange"
          placeholder="选择日期时间"
          align="right"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
          >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :disabled="loading" @click="loadArticals(1)">查询</el-button>

      </el-form-item>
    </el-form>
  </el-card>
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      根据筛选条件有{{totalCount}}条结果
    </div>
      <!--数据列表-->
      <el-table
        :data="articals"
        style="width: 100%" stripe size="mini" >
        <el-table-column
          prop="date"
          label="封面"
          v-loading="loading"
        >
          <template slot-scope="scope">
            <img v-if="scope.row.cover.images[0]" :src="scope.row.cover.images[0]" class="artical-cover" alt="">
            <img v-else class="artical-cover" src="./pic_bg.png" alt="">
          </template>
        </el-table-column>
        <el-table-column
          prop="title"
          label="标题"
        >
        </el-table-column>
        <el-table-column
          prop="status"
          label="状态"
        >
          <!--如果需要自定义遍历当前数据-->
          <template slot-scope="scope">
            <el-tag :type="articalsStatus[scope.row.status].type">{{articalsStatus[scope.row.status].text}}</el-tag>
           <!-- <el-tag v-else-if="scope.row.status===1">待审核</el-tag>
            <el-tag v-else-if="scope.row.status===2" type="success">审核通过</el-tag>
            <el-tag v-else-if="scope.row.status===3" type="danger">审核失败</el-tag>
            <el-tag v-else-if="scope.row.status===4" type="info">已删除</el-tag>-->
          </template>
        </el-table-column>
        <el-table-column
          prop="pubdate"
          label="发布时间"
        >
        </el-table-column>
        <el-table-column
          prop="cover"
          label="操作"
        >
          <template slot-scope="scope">
           <el-button size="mini" icon="el-icon-edit" type="primary" circle></el-button>
            <el-button size="mini" icon="el-icon-delete" type="danger" @click="onDeleteArtical(scope.row.id)" circle></el-button>
          </template>
        </el-table-column>
      </el-table>
      <!--分页-->
      <el-pagination class="list-table"
        layout="prev, pager, next"
        :total="totalCount" :page-size="pageSize"
                     :disabled="loading"
                     @current-change="OnCurrentChange" >
      </el-pagination>

  </el-card>

</div>
</template>
<script>
import {
  getArtical,
  deleteArtical,
  getArticalChannels
} from '@/api/artical'

export default {
  name: 'ArticalIndex',
  created () {
    this.loadArticals(1)
    this.loadChannels()
  },

  data () {
    return {
      loading: true,
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''

      },
      status: null, // 状态为空 查询文章的状态
      totalCount: 0, // 初始数据
      pageSize: 20, // 每页大小
      articals: [], // 记录文章的数据
      channels: [],
      channelId: null, // 文章的频道
      rangeDate: null, // 日期数据
      articalsStatus: [
        { status: 0, text: '草稿', type: 'info' },
        { status: 1, text: '待审核', type: '' },
        { status: 2, text: '审核通过', type: 'success' },
        { status: 3, text: '审核失败', type: 'warning' },
        { status: 4, text: '已删除', type: 'danger' }
      ]

    }
  },
  methods: {
    // 文章删除
    onDeleteArtical (articleId) {
      this.$confirm('确认删除吗', '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        /* 要删除的文章id */
        deleteArtical(articleId.toString()).then(res => {
          console.log(res)
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    onSubmit () {
      console.log('submit!')
    },
    loadArticals (page = 1) {
      this.loading = true
      getArtical({
        page,
        per_page: this.pageSize,
        status: this.status,
        channel_id: this.channelId,
        /*
        *  */
        begin_pubdate: this.rangeDate ? this.rangeDate[0] : null,
        end_pubdate: this.rangeDate ? this.rangeDate[1] : null
      }).then(res => {
        const { results, total_count: totalCount } = res.data.data
        this.totalCount = totalCount
        this.articals = results
        // 关闭加载
        this.loading = false
      })
    },
    loadChannels () {
      getArticalChannels().then(res => {
        console.log(res)
        this.channels = res.data.data.channels
      })
    },
    OnCurrentChange (page) {
      this.loadArticals(page)
    }
  }
}

</script>
<style scope lang="less">
.filter-card{
  margin-bottom: 30px;
}
.list-table{
  margin-bottom: 20px;
}
.artical-cover{
  width: 60px;
  background-size:cover;
}
</style>


app.vue

<template>
  <div id="app">

    <router-view/>
  </div>
</template>
<script>
export default {
  name: 'App'
}
</script>
<style lang="less">

</style>

index.vue

<template>
  <div class="login-container">
    <!--必须用el-form进行包裹-->
    <div class="login-head"></div>
    <!--配置表单验证
    //必须为表单提供验证对象
    2添加prop属性
    3通过el-form组件库里面的rules-->

    <el-form class="login-form" ref="login-form" :model="user" :rules="formRules">
      <el-form-item prop="mobile">
        <el-input v-model="user.mobile" placeholder="请输入手机号"></el-input>
      </el-form-item>

        <el-form-item prop="code">
          <el-input v-model="user.code" placeholder="请输入验证码"></el-input>
        </el-form-item>
      <el-form-item prop="agree">
        <el-checkbox v-model="checked">我已阅读并同意用户协议和隐私条款</el-checkbox>

      </el-form-item>
      <el-form-item>
        <el-button class="login-btn" type="primary" :loading="loginLoading" @click="onLogin">登录</el-button>

      </el-form-item>
    </el-form>
  </div>
</template>

<script>

import { login } from '@/api/user'
export default {
  name: 'LoginIndex',
  components: {
  },
  props: {},
  data () {
    return {
      user: {
        mobile: '', // 手机号
        code: '', // 验证码
        agree: false// 是否同意协议
      },

      loginLoading: false, // 登录的loding状态
      /*  checked: false, // 是否同意协议 */
      formRules: {
        mobile: [{
          required: true,
          message: '手机号不能为空',
          trigger: 'change'
        },
        { pattern: /^1[3|5|7|9]\d{9}$/, message: '请输入正确的号码格式', trigger: 'change' }
        ],
        code: [{
          required: true,
          message: '验证码不能为空',
          trigger: 'change'
        },
        { pattern: /^\d{6}$/, message: '请输入正确的验证码格式', trigger: 'change' }

        ],
        agree: [{
          // 调用
          validator: (rule, value, callback) => {
            if (value) {
              callback()
            } else {
              callback(new Error('请同意用户协议'))
            }
          },

          trigger: 'change'
        }]
      }
    }
  },
  methods: {
    onLogin () {
      // 获取表单数据
      // const user = this.user
      // 触发表单验证 validate是异步
      this.$refs['login-form'].validate((valid, err) => {
        console.log(valid)
        console.log(err)
        // 如果
        if (!valid) {
          return
        }
        this.login()
      })
    },
    login () {
      // 开启loading
      this.loginLoading = true
      // 验证通过
      // 请求直接封装
      login(this.user).then(res => {
        console.log(res)
        this.$message({
          message: '登录成功',
          type: 'success'

        })
        this.loginLoading = false
      }).catch(err => {
        console.log('登录失败', err)
        this.$message.error({
          message: '手机号或者验证码错误',
          type: 'warning'

        })
        this.loginLoading = false
      })
    }
  }

}
</script>
<style scoped lang="less">
.login-container{
position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background: url("./login_bg.jpg") no-repeat;
  background-size: cover;
  .login-head{
    width: 300px;
    height: 57px;
    background:url("./logo_index.png") no-repeat;
    margin-bottom: 30px;
  }
  .login-form{
    background-color: #fff;
    padding: 50px;
    min-width: 300px;
    .login-btn{
      width: 100%;
    }
  }
}
</style>

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './styles/index.less'
// 加载组件库
import ElementUI from 'element-ui'
// 加载样式
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
// 注册组件库
Vue.use(ElementUI)
new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '@/views/login/index'
Vue.use(VueRouter)

// 路由配置表
const routes = [{
  path: '/login',
  name: 'login',
  component: Login
}]
const router = new VueRouter({
  routes
})

export default router

user.js

// 用户登录的请求模块
import request from '@/utils/request'

export const login = data => {
  return request({
    method: 'POST',
    url: '/mp/v1_0/authorizations',
    data
  })
}

// 获取用户信息

index.vue

<template>
  <div class="home-container">首页</div>
</template>
<script>
export default {
  name: 'HomeIndex',
  data () {
    return {

    }
  }
}
</script>
<style scoped lang="less">

</style>

index.vue

<template>

  <el-container class="layout-container">
    <el-aside class="aside">
      <app-aside class="aside-menu"></app-aside>
    </el-aside>
    <el-container>
      <el-header class="header">
        <div>
          <i class="el-icon-s-fold"></i>
          <span>江苏传智播客科技教育有限公司</span>
        </div>
        <el-dropdown>
          <div class="avatar-wrap">
            <img class="avatar" src="./avatar.jpg" alt="">
            <span>歌谣</span>
            <i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>
          </div>
  <!--<span>
    下拉菜单<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>
  </span>-->
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>设置</el-dropdown-item>
            <el-dropdown-item>退出</el-dropdown-item>

          </el-dropdown-menu>
        </el-dropdown>
      </el-header>
      <el-main class="main">
        <router-view /></el-main>
    </el-container>
  </el-container>

</template>
<script>
import AppAside from './component/aside'

export default {
  name: 'LayoutIndex',
  components: { AppAside },
  component: {
    AppAside
  },
  data () {
    return {

    }
  }
}
</script>
<style scoped lang="less">
.layout-container{
  position: fixed;
  left:0;
  right:0;
  top:0;
  bottom: 0;

}

.aside{
  width: 100px;
  background-color: #d3dce6;
  .aside-menu{
    height: 100%;
  }
}
.header{
  height: 60px;
  background-color: #b3c0d1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #ccc;
}
.main{
  background-color: #e9eef3;
}
.avatar-wrap{
  display: flex;
  align-items: center;
  .avatar{
  width: 40px;
    height: 40px;
    border-radius: 50%;
    margin-right: 10px;
  }
}
</style>

aside.vue

 

<template>
<div class="artical-container">
  <!--卡片-->
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      <!--面包屑导航-->
      <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>

    </div>
    <!--数据-->
    <el-form ref="form" :model="form" label-width="40px" size="mini">
      <el-form-item label="状态">
        <el-radio-group v-model="form.resource">
          <el-radio label="全部"></el-radio>
          <el-radio label="查找"></el-radio>
          <el-radio label="待审核"></el-radio>
          <el-radio label="审核通过"></el-radio>
          <el-radio label="审核失败"></el-radio>
          <el-radio label="已删除"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="频道">
        <el-select v-model="form.region" placeholder="请选择频道">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="日期">
        <el-date-picker
          v-model="form.date1"
          type="datetime"
          placeholder="选择日期时间"
          align="right"
          >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">查询</el-button>

      </el-form-item>
    </el-form>
  </el-card>
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      根据筛选条件有1314520条结果
    </div>
      <!--数据列表-->
      <el-table
        :data="articals"
        style="width: 100%" stripe size="mini" >
        <el-table-column
          prop="date"
          label="封面"
        >
        </el-table-column>
        <el-table-column
          prop="title"
          label="标题"
        >
        </el-table-column>
        <el-table-column
          prop="status"
          label="状态"
        >
          <!--如果需要自定义遍历当前数据-->
          <template slot-scope="scope">
            <el-tag v-if="scope.row.status===0">草稿</el-tag>
            <el-tag v-else-if="scope.row.status===1">待审核</el-tag>
            <el-tag v-else-if="scope.row.status===2" type="success">审核通过</el-tag>
            <el-tag v-else-if="scope.row.status===3" type="danger">审核失败</el-tag>
            <el-tag v-else-if="scope.row.status===4" type="info">已删除</el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="pubdate"
          label="发布时间"
        >
        </el-table-column>
        <el-table-column
          prop="cover"
          label="操作"
        >
          <template>
           <el-button size="mini" icon="el-icon-edit" type="primary" circle></el-button>
            <el-button size="mini" icon="el-icon-delete" type="danger" circle></el-button>
          </template>
        </el-table-column>
      </el-table>
      <!--分页-->
      <el-pagination class="list-table"
        layout="prev, pager, next"
        :total="1000">
      </el-pagination>

  </el-card>

</div>
</template>
<script>
import { getArtical } from '@/api/artical'

export default {
  name: 'ArticalIndex',
  created () {
    this.loadArticals()
  },

  data () {
    return {
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''

      },
      articals: [] // 记录文章的数据

    }
  },
  methods: {
    onSubmit () {
      console.log('submit!')
    },
    loadArticals () {
      getArtical().then(res => {
        console.log(res)
        console.log(res)
        console.log(res)
        this.articals = res.data.data.results
      })
    }
  }
}

</script>
<style scope lang="less">
.filter-card{
  margin-bottom: 30px;
}
.list-table{
  margin-bottom: 20px;
}
</style>

 content--->index.vue

<template>
<div class="artical-container">
  <!--卡片-->
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      <!--面包屑导航-->
      <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>

    </div>
    <!--数据-->
    <el-form ref="form" :model="form" label-width="40px" size="mini">
      <el-form-item label="状态">
        <el-radio-group v-model="status">
          <el-radio :label="null">全部</el-radio>
          <el-radio :label="0">草稿</el-radio>
          <el-radio :label="1">待审核</el-radio>
          <el-radio :label="2">审核通过</el-radio>
          <el-radio :label="3">审核失败</el-radio>
          <el-radio :label="4">已删除</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="频道">
        <el-select v-model="channelId" placeholder="请选择频道">
          <el-option label="全部" :value="null"></el-option>
          <el-option :label="channel.name" :value="channel.id" v-for="(channel,index) in channels" :key="index"></el-option>

        </el-select>
      </el-form-item>

      <el-form-item label="日期">
        <el-date-picker
          v-model="rangeDate"
          type="datetimerange"
          placeholder="选择日期时间"
          align="right"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
          >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :disabled="loading" @click="loadArticals(1)">查询</el-button>

      </el-form-item>
    </el-form>
  </el-card>
  <el-card class="filter-card">
    <div slot="header" class="clearfix">
      根据筛选条件有{{totalCount}}条结果
    </div>
      <!--数据列表-->
      <el-table
        :data="articals"
        style="width: 100%" stripe size="mini" >
        <el-table-column
          prop="date"
          label="封面"
          v-loading="loading"
        >
          <template slot-scope="scope">
            <img v-if="scope.row.cover.images[0]" :src="scope.row.cover.images[0]" class="artical-cover" alt="">
            <img v-else class="artical-cover" src="./pic_bg.png" alt="">
          </template>
        </el-table-column>
        <el-table-column
          prop="title"
          label="标题"
        >
        </el-table-column>
        <el-table-column
          prop="status"
          label="状态"
        >
          <!--如果需要自定义遍历当前数据-->
          <template slot-scope="scope">
            <el-tag :type="articalsStatus[scope.row.status].type">{{articalsStatus[scope.row.status].text}}</el-tag>
           <!-- <el-tag v-else-if="scope.row.status===1">待审核</el-tag>
            <el-tag v-else-if="scope.row.status===2" type="success">审核通过</el-tag>
            <el-tag v-else-if="scope.row.status===3" type="danger">审核失败</el-tag>
            <el-tag v-else-if="scope.row.status===4" type="info">已删除</el-tag>-->
          </template>
        </el-table-column>
        <el-table-column
          prop="pubdate"
          label="发布时间"
        >
        </el-table-column>
        <el-table-column
          prop="cover"
          label="操作"
        >
          <template slot-scope="scope">
           <el-button size="mini" icon="el-icon-edit" type="primary" circle></el-button>
            <el-button size="mini" icon="el-icon-delete" type="danger" @click="onDeleteArtical(scope.row.id)" circle></el-button>
          </template>
        </el-table-column>
      </el-table>
      <!--分页-->
      <el-pagination class="list-table"
        layout="prev, pager, next"
        :total="totalCount" :page-size="pageSize"
                     :disabled="loading"
                     @current-change="OnCurrentChange" >
      </el-pagination>

  </el-card>

</div>
</template>
<script>
import {
  getArtical,
  deleteArtical,
  getArticalChannels
} from '@/api/artical'

export default {
  name: 'ArticalIndex',
  created () {
    this.loadArticals(1)
    this.loadChannels()
  },

  data () {
    return {
      loading: true,
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''

      },
      status: null, // 状态为空 查询文章的状态
      totalCount: 0, // 初始数据
      pageSize: 20, // 每页大小
      articals: [], // 记录文章的数据
      channels: [],
      channelId: null, // 文章的频道
      rangeDate: null, // 日期数据
      articalsStatus: [
        { status: 0, text: '草稿', type: 'info' },
        { status: 1, text: '待审核', type: '' },
        { status: 2, text: '审核通过', type: 'success' },
        { status: 3, text: '审核失败', type: 'warning' },
        { status: 4, text: '已删除', type: 'danger' }
      ]

    }
  },
  methods: {
    // 文章删除
    onDeleteArtical (articleId) {
      this.$confirm('确认删除吗', '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        /* 要删除的文章id */
        deleteArtical(articleId)
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    onSubmit () {
      console.log('submit!')
    },
    loadArticals (page = 1) {
      this.loading = true
      getArtical({
        page,
        per_page: this.pageSize,
        status: this.status,
        channel_id: this.channelId,
        /*
        *  */
        begin_pubdate: this.rangeDate ? this.rangeDate[0] : null,
        end_pubdate: this.rangeDate ? this.rangeDate[1] : null
      }).then(res => {
        const { results, total_count: totalCount } = res.data.data
        this.totalCount = totalCount
        this.articals = results
        // 关闭加载
        this.loading = false
      })
    },
    loadChannels () {
      getArticalChannels().then(res => {
        console.log(res)
        this.channels = res.data.data.channels
      })
    },
    OnCurrentChange (page) {
      this.loadArticals(page)
    }
  }
}

</script>
<style scope lang="less">
.filter-card{
  margin-bottom: 30px;
}
.list-table{
  margin-bottom: 20px;
}
.artical-cover{
  width: 60px;
  background-size:cover;
}
</style>

publish-->index.vue

<template>
  <!--card插件-->
  <div class="publish-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item>发布文章</el-breadcrumb-item>
        </el-breadcrumb>
        <el-form ref="form" :model="artical" label-width="80px">
          <el-form-item label="标题">
            <el-input v-model="artical.title"></el-input>
          </el-form-item>
          <el-form-item label="内容">
            <el-input type="textarea" v-model="artical.content"></el-input>
          </el-form-item>
          <el-form-item label="封面">
            <el-radio-group v-model="artical.cover.type">
              <el-radio label="单图"></el-radio>
              <el-radio label="三图"></el-radio>
              <el-radio label="无图"></el-radio>
              <el-radio label="自动"></el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="频道">
            <el-select v-model="artical.channel_id" placeholder="请选择频道">
              <el-option :label="channel.name" :value="channel.id"
              v-for="(channel,index) in channels" :key="index"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmit">发表</el-button>
            <el-button>存入草稿</el-button>
          </el-form-item>
        </el-form>
      </div>

    </el-card>
  </div>
</template>
<script>
import { getArticalChannels } from '@/api/artical'

export default {
  data () {
    return {

      channels: [],
      artical: {
        title: '',
        content: '',
        cover: {
          type: 0,
          images: []
        },
        channel_id: null
      }
    }
  },
  created () {
    this.loadChannels()
  },
  methods: {
    onSubmit () {
      console.log('submit!')
    },
    loadChannels () {
      getArticalChannels().then(({ data }) => {
        this.channels = data.data.channels
      })
    }
  }
}
</script>
<style>

</style>

运行结果

 

©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页