vue 项目案例

项目案例

结合之前学习的 vue.js、脚手架、vuex、vue-router、axios、elementui 等知识点,来开发前端项目案例(仅前端不含后端)。

此案例中的页面,其实就是后续项目的界面,后续项目开发时,直接拿来和后端API进行集成就行了。

 

1.项目搭建

其实就是将我们项目需要用到的组件都安装并配置好,需要做的事有:

  • 创建项目 & 运行项目

    以前需要这样:

    vue create 项目名称
    npm run serve
    现在可以这样简便

    WebStorm集成开发环境

    新建项目 - vue.js - 项目名 - node(配置好环境变量) - vue-cli

    创建并运行项目
  • 安装和配置 vue-router

    没有WebStorm集成开发环境的时候

    npm install vue-router@3
    手动创建文件和配置
    有WebStorm集成开发环境 直接在终端输入(以下同理):

    vue add router

    y/n 选n
  • 安装和配置 vuex

    npm install vue-vuex@3
    手动创建文件和配置
    vue add vuex

    y/n 选y
  • 安装和配置 elementui

    npm install element-ui
    手动创建文件和配置
    vue add element

    y/n 选y
    Fully import
    y/n 选n
    zh-cn

2.登录

 

 需要的组件:

 

 Login.vue

<template>
  <div class="main">
    <div class="loginBox">
      <div class="tabBoxSwitch">
        <ul class="tabBoxSwitchUl">
          <!--            // tabSelected === index?'tab-active':''  三元运算 成立取tab-active 不成立取空-->
          <li :class="tabSelected === index?'tab-active':''" v-for="(txt,index) in tableList" :key="index"
              @click="tabSelected=index">{{ txt }}
          </li>

        </ul>
      </div>
      <div v-show="tabSelected===0">
<!--        //:rules="userRules" 表单的验证规则  :model="userForm" 绑定的数据在哪取  数据的键和规则的键能对上就能校验-->
<!--        //ref="userForm" ref属性将表单当做对象传到验证方法中-->
        <el-form :model="userForm" :rules="userRules" ref="userForm">
<!--          // prop="username" 错误提示 对应规则的message-->
          <el-form-item prop="username" style="margin-top: 24px;" >
            <el-input v-model="userForm.username" placeholder="用户名或手机号"></el-input>
          </el-form-item>
<!--          // prop="password" 错误提示 对应规则的message-->
          <el-form-item prop="password" >
            <el-input v-model="userForm.password" placeholder="密码" show-password></el-input>
          </el-form-item>
          <el-form-item>
<!--            // @click="submitForm('userForm')" 定义方法执行验证规则-->
            <el-button @click="submitForm('userForm')" type="primary" size="medium">登 录</el-button>
          </el-form-item>
        </el-form>
      </div>

      <div v-show="tabSelected===1">
        <el-form :model="smsForm" :rules="smsRules" ref="smsForm">
          <el-form-item prop="phone" style="margin-top: 24px;">
            <el-input v-model="smsForm.phone" placeholder="手机号"></el-input>
          </el-form-item>
          <el-form-item prop="code">
            <el-row type="flex" justify="space-between">
              <el-input v-model="smsForm.code" placeholder="验证码"></el-input>
<!--              //:disabled="btnSmsDisabled"  是否可点击-->
              <el-button :disabled="btnSmsDisabled" @click="sendSmsCode" style="margin-left: 10px;">
                {{btnSmsText}}
              </el-button>
            </el-row>

          </el-form-item>
          <el-form-item>
            <el-button @click="submitForm('smsForm')" type="primary" size="medium">登 录</el-button>
          </el-form-item>
        </el-form>
      </div>

    </div>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Login",
  data() {
    return {
      tabSelected: 0,
      tableList: ['密码登录', '免密登录'],
      userForm: {
        username: "",
        password: ""
      },
      smsForm: {
        phone: "",
        code: ""
      },
      userRules: {
        username: [ // 数据的键和规则的键能对上就能校验
          {required: true, message: '请输入用户名或手机', trigger: 'blur'},
        ],
        password: [
          {required: true, message: '请输入密码', trigger: 'blur'},
        ],
      },
      smsRules: {
        phone: [
          {required: true, message: '请输入手机号', trigger: 'blur'},
          {pattern: /^1[3456789]\d{9}$/, message: '手机号格式错误', trigger: 'blur'},
        ],
        code: [
          {required: true, message: '验证码', trigger: 'blur'},
        ],
      },
      btnSmsDisabled: false,
      btnSmsText: "发送验证码"
    };
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('验证通过');
        } else {
          console.log('未通过!!');
          return false;
        }
      });
    },
    // 发送验证码按钮
    sendSmsCode() {
      // $refs.smsForm 获取到表单需要验证的字段
      this.$refs.smsForm.validateField("phone", (error) => {// validateField("phone", 验证单个字段
        if (error) { // 如果有错 不通过
          return false;
        }
        // 验证通过拿到手机号,向后台发送请求 -> 发送验证码
        // 禁用按钮
        this.btnSmsDisabled = true;
        // 设置倒计时
        let txt = 60;
        let interval = window.setInterval(() => { // 定时器
          txt -= 1; // 过一秒数字减1
          this.btnSmsText = `${txt}秒后重发`
          if (txt < 1) {
            this.btnSmsText = "重新发送";
            this.btnSmsDisabled = false;
            window.clearInterval(interval); // 删掉定时器
          }
        }, 1000);

      })
    },
  }
}


</script>

<style scoped>
.main {
  width: 100%;
  height: 100vh;
  background-color: #2E3E9C;

  /*背景布局 按轴方向*/
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

/*登录的白框样式*/
.loginBox {
  background-color: #FFFFFF;
  box-shadow: 0 1px 3px rgba(26, 26, 26, 0.1);
  border-radius: 2px;
  width: 380px;
  min-height: 200px;
  padding: 0 24px 20px;
}

.tabBoxSwitch .tabBoxSwitchUl {
  list-style: none;
  padding: 0;
  margin: 0;
}

.tabBoxSwitch .tabBoxSwitchUl li {
  display: inline-block;
  height: 60px;
  font-size: 16px;
  line-height: 60px;
  margin-right: 24px;
  cursor: pointer;
}

/*两个tab的样式*/
.tab-active {
  position: relative;
  color: #1a1a1a;
  font-weight: 600;
  font-synthesis: style;
}

/*蓝线的样式*/
.tab-active::before {
  display: block;
  position: absolute;
  bottom: 0;
  content: "";
  width: 100%;
  height: 3px;
  background-color: #0084ff;
}
</style>
View Code

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
    
    {
        path: '/login',
        name: 'Login',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
    }
]

const router = new VueRouter({
    routes
})

export default router
View Code

3.路由和菜单

 

 

 

 

一级菜单(菜单的切换 默认选中):

Layout.vue

<template>
  <!--  顶部菜单 -->
  <div>
    <div>
<!--       default属性表示激活谁 :default-active="rootActiveRouter" 激活谁谁就被选中 -->
<!--       router表示可以把<el-menu-item>当作route-link用 -->
      <el-menu
          class="el-menu-demo"
          mode="horizontal"
          background-color="#545c64"
          text-color="#fff"
          :default-active="rootActiveRouter"
          active-text-color="#ffd04b" router>
<!--        点击切换tab 需要router-link  现在都是<el-menu-item>  所以再上个标签加入router属性就有router-link效果了   -->
<!--        通过route属性:route="{name:'ActivityList'} 可以帮我们跳转到某个路由-->
        <el-menu-item>媒体宝系统</el-menu-item>
        <el-menu-item index="Task" :route="{name:'Task'}">任务宝</el-menu-item>
        <el-menu-item index="Msg" :route="{name:'Msg'}">消息宝</el-menu-item>
        <el-menu-item index="Auth" :route="{name:'Auth'}">授权</el-menu-item>

        <el-submenu index="2" style="float: right">
          <template slot="title">吴沛琪</template>
          <el-menu-item index="2-1">个人中心</el-menu-item>
          <el-menu-item index="2-2">注销</el-menu-item>
        </el-submenu>
      </el-menu>
    </div>
    <div>
      <!--  菜单下的内容  通过子组件来渲染内容    -->
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Layout",
  data() {
    return {
      // 激活选中状态的变量
      rootActiveRouter: ""
    }
  },
  // 获取当前的所有路由
  mounted() {
    // 获取当前的所有路由  获取当前路由组件的名称  用来默认选中tab(刷新后还是默认选中的)
    this.rootActiveRouter = this.$route.matched[1].name;
  },
}
</script>

<style scoped>

</style>
View Code

子组件(TaskLayout  MsgLayout AuthLayout ):

<template>
  <div>task</div>
</template>

<script>
export default {
  name: "TaskLayout"
}
</script>

<style scoped>

</style>
View Code

路由(包含子路由)index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
    {
        path: '/',
        name: 'Layout',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/Layout.vue'),
        children: [

            {
                path: 'task',
                name: 'Task',
                component: () => import('../views/task/TaskLayout.vue'),
            },

            {
                path: 'msg',
                name: 'Msg',
                component: () => import('../views/msg/MsgLayout.vue'),
            },

            {
                path: 'auth',
                name: 'Auth',
                component: () => import('../views/auth/AuthLayout.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'Login',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
    }
]

const router = new VueRouter({
    routes
})

export default router
View Code

 

二级菜单-展示:

 

 TaskLayout.vue

<template>
  <div>
    <el-menu
        class="sub-menu"
        mode="horizontal"
        :default-active="rootActiveRouter" router>
      <!--      router可以是使标签 <el-menu-item> 和router-link一样可以点击  -->
      <!--      index="Activity" :route="{name:'Activity'} 可以通过点击找到子相应组件-->
      <el-menu-item index="Activity" :route="{name:'Activity'}"><i class="el-icon-coin"></i>活动管理</el-menu-item>
      <el-menu-item index="Promo" :route="{name:'Promo'}"><i class="el-icon-data-analysis"></i>推广码</el-menu-item>
      <el-menu-item index="Stat" :route="{name:'Stat'}"><i class="el-icon-document"></i>数据统计</el-menu-item>
      <el-menu-item index="Fans" :route="{name:'Fans'}"><i class="el-icon-setting"></i>参与粉丝</el-menu-item>
    </el-menu>
    <!--    将获取的到的子组件进行渲染-->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "TaskLayout",
 
}
</script>

<style scoped>
      .sub-menu .el-menu-item {
        line-height: 40px;
        height: 40px;
        vertical-align: middle;
        font-size: 13px;
      }

      .sub-menu .el-menu-item i {
        margin-top: -3px;
      }
</style>
View Code

子路由(Activity Fans Promo Stat):

<template>
  <div>Activity</div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Activity"
}
</script>

<style scoped>

</style>
View Code

index.js 路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
    {
        path: '/',
        name: 'Layout',
        component: () => import('../views/Layout.vue'),
        children: [ // Layout的子路由

            {
                path: 'task',
                name: 'Task',
                component: () => import('../views/task/TaskLayout.vue'),
                children: [ // TaskLayout的子路由
                    {
                        path: "activity",
                        name: 'Activity',
                        component: () => import('../views/task/Activity.vue'),

                    },
                    {
                        path: "promo",
                        name: 'Promo',
                        component: () => import('../views/task/Promo.vue'),
                    },
                    {
                        path: "stat",
                        name: 'Stat',
                        component: () => import('../views/task/Stat.vue'),
                    },
                    {
                        path: "fans",
                        name: 'Fans',
                        component: () => import('../views/task/Fans.vue'),
                    },
                ]

            },

            {
                path: 'msg',
                name: 'Msg',
                component: () => import('../views/msg/MsgLayout.vue'),
                children: [//MsgLayout的子路由

                    {
                        path: "push",
                        name: 'Push',
                        component: () => import('../views/msg/Push.vue'),
                    },
                    {
                        path: "sop",
                        name: 'Sop',
                        component: () => import('../views/msg/Sop.vue'),
                    },
                ]
            },

            {
                path: 'auth',
                name: 'Auth',
                component: () => import('../views/auth/AuthLayout.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'Login',
       
        component: () => import('../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import( '../views/AboutView.vue')
    }
]

const router = new VueRouter({
    routes
})

export default router
View Code

 

二级菜单-默认选中:

Layout.vue

<!--        点击一级菜单可以默认选中一个二级菜单跳转 将名字改成二级Activity 就行了-->
<el-menu-item index="Task" :route="{name:'Activity'}">任务宝</el-menu-item>
<el-menu-item index="Msg" :route="{name:'Push'}">消息宝</el-menu-item>
<el-menu-item index="Auth" :route="{name:'Auth'}">授权</el-menu-item>
<template>
  <!--  顶部菜单 -->
  <div>
    <div>
<!--       default属性表示激活谁 :default-active="rootActiveRouter" 激活谁谁就被选中 -->
<!--       router表示可以把<el-menu-item>当作route-link用 -->
      <el-menu
          class="el-menu-demo"
          mode="horizontal"
          background-color="#545c64"
          text-color="#fff"
          :default-active="rootActiveRouter"
          active-text-color="#ffd04b" router>
<!--        点击切换tab 需要router-link  现在都是<el-menu-item>  所以再上个标签加入router属性就有router-link效果了   -->
<!--        通过route属性:route="{name:'ActivityList'} 可以帮我们跳转到某个路由-->
        <el-menu-item>媒体宝系统</el-menu-item>
<!--        点击一级菜单可以默认选中一个二级菜单跳转 将名字改成二级Activity 就行了-->
        <el-menu-item index="Task" :route="{name:'Activity'}">任务宝</el-menu-item>
        <el-menu-item index="Msg" :route="{name:'Push'}">消息宝</el-menu-item>
        <el-menu-item index="Auth" :route="{name:'Auth'}">授权</el-menu-item>

        <el-submenu index="2" style="float: right">
          <template slot="title">吴沛琪</template>
          <el-menu-item index="2-1">个人中心</el-menu-item>
          <el-menu-item index="2-2">注销</el-menu-item>
        </el-submenu>
      </el-menu>
    </div>
    <div>
      <!--  菜单下的内容  通过子组件来渲染内容    -->
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Layout",
  data() {
    return {
      // 激活选中状态的变量
      rootActiveRouter: ""
    }
  },
  // 获取当前的所有路由
  mounted() {
    // 获取当前的所有路由  获取当前路由组件的名称  用来默认选中tab(刷新后还是默认选中的)
    this.rootActiveRouter = this.$route.matched[1].name;
  },
}
</script>

<style scoped>

</style>
View Code

TaskLayout.vue

<template>
  <div>
    <el-menu
        class="sub-menu"
        mode="horizontal"
        :default-active="subActiveRouter" router>
      <!--      router可以是使标签 <el-menu-item> 和router-link一样可以点击  -->
      <!--      index="Activity" :route="{name:'Activity'} 可以通过点击找到子相应组件-->
      <el-menu-item index="Activity" :route="{name:'Activity'}"><i class="el-icon-coin"></i>活动管理</el-menu-item>
      <el-menu-item index="Promo" :route="{name:'Promo'}"><i class="el-icon-data-analysis"></i>推广码</el-menu-item>
      <el-menu-item index="Stat" :route="{name:'Stat'}"><i class="el-icon-document"></i>数据统计</el-menu-item>
      <el-menu-item index="Fans" :route="{name:'Fans'}"><i class="el-icon-setting"></i>参与粉丝</el-menu-item>
    </el-menu>
    <!--    将获取的到的子组件进行渲染-->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "TaskLayout",
  data() {
    return {
      // 激活选中状态的变量
      subActiveRouter: ""
    }
  },
  watch:{// 监听路由 一旦发生变化 默认被选中的状态也会跟着变
    $route:function (to) {
      // console.log('--->',to);
      this.subActiveRouter = to.matched[2].name;
    }
  },
  // 获取当前的所有路由
  mounted() {
    // 获取当前的所有路由  获取当前路由组件的名称  用来默认选中tab(刷新后还是默认选中的)
    this.subActiveRouter = this.$route.matched[2].name;
  },
}
</script>

<style scoped>
      .sub-menu .el-menu-item {
        line-height: 40px;
        height: 40px;
        vertical-align: middle;
        font-size: 13px;
      }

      .sub-menu .el-menu-item i {
        margin-top: -3px;
      }
</style>
View Code

index.js

{
path: "/", // task后面是空的话
redirect:"push", // 就直接跳转到push组件

},
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
    {
        path: '/',
        name: 'Layout',
        component: () => import('../views/Layout.vue'),
        children: [ // Layout的子路由

            {
                path: 'task',
                name: 'Task',
                component: () => import('../views/task/TaskLayout.vue'),
                children: [ // TaskLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect:"activity", // 就直接跳转到activity组件

                    },
                    {
                        path: "activity",
                        name: 'Activity',
                        component: () => import('../views/task/Activity.vue'),

                    },
                    {
                        path: "promo",
                        name: 'Promo',
                        component: () => import('../views/task/Promo.vue'),
                    },
                    {
                        path: "stat",
                        name: 'Stat',
                        component: () => import('../views/task/Stat.vue'),
                    },
                    {
                        path: "fans",
                        name: 'Fans',
                        component: () => import('../views/task/Fans.vue'),
                    },
                ]

            },

            {
                path: 'msg',
                name: 'Msg',
                component: () => import('../views/msg/MsgLayout.vue'),
                children: [//MsgLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect:"push", // 就直接跳转到push组件

                    },

                    {
                        path: "push",
                        name: 'Push',
                        component: () => import('../views/msg/Push.vue'),
                    },
                    {
                        path: "sop",
                        name: 'Sop',
                        component: () => import('../views/msg/Sop.vue'),
                    },
                ]
            },

            {
                path: 'auth',
                name: 'Auth',
                component: () => import('../views/auth/AuthLayout.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'Login',

        component: () => import('../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import( '../views/AboutView.vue')
    }
]

const router = new VueRouter({
    routes
})

export default router
View Code

 

4.授权

<template>
    <div>
<!--element ui 中的卡片 card-->
        <el-card class="box-card flex-row-center" shadow="hover">
            <div class="flex-col-center">
                <i class="el-icon-circle-plus-outline icon"></i>
                <div class="text">添加公众号</div>
            </div>
        </el-card>

        <el-card class="box-card box-item" shadow="hover" :body-style="{width:'100%',padding:'20px'}">
            <div class="item flex-row-center">
                <el-avatar size="large"
                           src="http://wx.qlogo.cn/mmopen/t6cpMpYeAkhIjyBs9Y5nD6g8SPSfXbVRY2icK7MELDVWs0jPuQQXga8YCnVY6z8U4DI4ZMfvTqTww6FQeQNc4cfyDTHyr4wMm/0"></el-avatar>
            </div>
            <div class="item flex-row-center">路飞小课</div>
            <div class="item flex-row-center">
                <div class="flex-row-between" style="width: 100px;font-size: 12px;">
                    <div style="color: gray">服务号</div>
                    <div style="color: #0c8eff;">已认证</div>
                </div>
            </div>
            <el-divider></el-divider>
            <div class="item small flex-row-between">
                <div><i class="el-icon-position"></i> 任务包</div>
                <div class="date">2020-11-11到期</div>
            </div>
            <div class="item small flex-row-between">
                <div><i class="el-icon-bell"></i> 消息宝</div>
                <div class="date">2020-11-11到期</div>
            </div>
        </el-card>

        <el-card class="box-card box-item" shadow="hover" :body-style="{width:'100%',padding:'20px'}">
            <div class="item flex-row-center">
                <el-avatar size="large"
                           src="http://wx.qlogo.cn/mmopen/t6cpMpYeAkhIjyBs9Y5nD6g8SPSfXbVRY2icK7MELDVWs0jPuQQXga8YCnVY6z8U4DI4ZMfvTqTww6FQeQNc4cfyDTHyr4wMm/0"></el-avatar>
            </div>
            <div class="item flex-row-center">路飞小课</div>
            <div class="item flex-row-center">
                <div class="flex-row-between" style="width: 100px;font-size: 12px;">
                    <div style="color: gray">服务号</div>
                    <div style="color: #0c8eff;">已认证</div>
                </div>
            </div>
            <el-divider></el-divider>
            <div class="item small flex-row-between">
                <div><i class="el-icon-position"></i> 任务包</div>
                <div class="date">2020-11-11到期</div>
            </div>
            <div class="item small flex-row-between">
                <div><i class="el-icon-bell"></i> 消息宝</div>
                <div class="date">2020-11-11到期</div>
            </div>
        </el-card>

        <el-card class="box-card box-item" shadow="hover" :body-style="{width:'100%',padding:'20px'}">
            <div class="item flex-row-center">
                <el-avatar size="large"
                           src="http://wx.qlogo.cn/mmopen/t6cpMpYeAkhIjyBs9Y5nD6g8SPSfXbVRY2icK7MELDVWs0jPuQQXga8YCnVY6z8U4DI4ZMfvTqTww6FQeQNc4cfyDTHyr4wMm/0"></el-avatar>
            </div>
            <div class="item flex-row-center">路飞小课</div>
            <div class="item flex-row-center">
                <div class="flex-row-between" style="width: 100px;font-size: 12px;">
                    <div style="color: gray">服务号</div>
                    <div style="color: #0c8eff;">已认证</div>
                </div>
            </div>
            <el-divider></el-divider>
            <div class="item small flex-row-between">
                <div><i class="el-icon-position"></i> 任务包</div>
                <div class="date">2020-11-11到期</div>
            </div>
            <div class="item small flex-row-between">
                <div><i class="el-icon-bell"></i> 消息宝</div>
                <div class="date">2020-11-11到期</div>
            </div>
        </el-card>

        <el-card class="box-card box-item" shadow="hover" :body-style="{width:'100%',padding:'20px'}">
            <div class="item flex-row-center">
                <el-avatar size="large"
                           src="http://wx.qlogo.cn/mmopen/t6cpMpYeAkhIjyBs9Y5nD6g8SPSfXbVRY2icK7MELDVWs0jPuQQXga8YCnVY6z8U4DI4ZMfvTqTww6FQeQNc4cfyDTHyr4wMm/0"></el-avatar>
            </div>
            <div class="item flex-row-center">路飞小课</div>
            <div class="item flex-row-center">
                <div class="flex-row-between" style="width: 100px;font-size: 12px;">
                    <div style="color: gray">服务号</div>
                    <div style="color: #0c8eff;">已认证</div>
                </div>
            </div>
            <el-divider></el-divider>
            <div class="item small flex-row-between">
                <div><i class="el-icon-position"></i> 任务包</div>
                <div class="date">2020-11-11到期</div>
            </div>
            <div class="item small flex-row-between">
                <div><i class="el-icon-bell"></i> 消息宝</div>
                <div class="date">2020-11-11到期</div>
            </div>
        </el-card>

        <el-card class="box-card box-item" shadow="hover" :body-style="{width:'100%',padding:'20px'}">
            <div class="item flex-row-center">
                <el-avatar size="large"
                           src="http://wx.qlogo.cn/mmopen/t6cpMpYeAkhIjyBs9Y5nD6g8SPSfXbVRY2icK7MELDVWs0jPuQQXga8YCnVY6z8U4DI4ZMfvTqTww6FQeQNc4cfyDTHyr4wMm/0"></el-avatar>
            </div>
            <div class="item flex-row-center">路飞小课</div>
            <div class="item flex-row-center">
                <div class="flex-row-between" style="width: 100px;font-size: 12px;">
                    <div style="color: gray">服务号</div>
                    <div style="color: #0c8eff;">已认证</div>
                </div>
            </div>
            <el-divider></el-divider>
            <div class="item small flex-row-between">
                <div><i class="el-icon-position"></i> 任务包</div>
                <div class="date">2020-11-11到期</div>
            </div>
            <div class="item small flex-row-between">
                <div><i class="el-icon-bell"></i> 消息宝</div>
                <div class="date">2020-11-11到期</div>
            </div>
        </el-card>

    </div>
</template>

<script>
    export default {
      // eslint-disable-next-line vue/multi-word-component-names
        name: 'Auth',
        created: function () {

        }
    }
</script>

<style scoped>
    .box-card {
        width: 240px;
        height: 260px;
        float: left;
        margin: 20px;
    }

    .box-item {
        display: flex;
    }

    .box-item .item {
        padding: 5px 0;
    }

    .box-item .small {
        font-size: 14px;
        padding: 10px 0;
        color: #646464;
    }

    .box-item .date {
        font-size: 13px;
        color: #908e8e;
    }

    .flex-row-center {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }

    .flex-row-between {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
    }

    .flex-col-center {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .box-card .icon {
        font-size: 50px;
    }

    .box-card .text {
        font-size: 14px;
        margin-top: 8px;
    }

    .el-divider--horizontal {
        margin: 18px 0;
    }
</style>
View Code

 

5.消息宝

消息推送的-搜素(push.vue)

<template>
  <div>
    <!--  element ui  卡片 card-->
    <el-card class="box-card" style="padding: 20px" size="small" >
      <!--  element ui  行内表单-->
      <el-form :inline="true" class="demo-form-inline" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
<!--          v-model="searchFrom.title" 数据的绑定 输入后可以显示在页面上-->
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
<!--            通过循环对下拉框的数据 categoryOptions 展示-->
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>

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

        <!--  时间选择器 -->
        <el-form-item label="推送时间" prop="dateValue">
          <el-date-picker
              v-model="searchForm.dateValue"
              type="datetimerange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['12:00:00']">
          </el-date-picker>
        </el-form-item>
      </el-form>
        <el-row type="flex" justify="center">
          <el-button size="small" type="primary" @click="clickSearch" >筛选</el-button>
<!--          重置 需要做三个步骤 表单添加model  ref属性:model="searchForm" ref="searchForm" 在el-form-item里定义 pop属性-->
          <el-button size="small" type="success" @click="resetSearchForm('searchForm')" >重置</el-button>
        </el-row>
    </el-card>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Push",
  data() {
    return {
      searchForm: {
        title: '',
        category: '',
        dateValue: '',
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],

      }
    },
  methods:{
    clickSearch(){
      console.log(this.clickSearch())
    },
    resetSearchForm(formName){
      this.$refs[formName].resetFields();
    },

  }
}
</script>

<style scoped>

</style>
View Code

 消息推送-表格区域(push.vue)

<template>
  <div>
    <!--    搜索-->
    <!--  element ui  卡片 card-->
    <el-card class="box-card" style="padding: 20px" size="small">
      <!--  element ui  行内表单-->
      <el-form :inline="true" class="demo-form-inline" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
          <!--          v-model="searchFrom.title" 数据的绑定 输入后可以显示在页面上-->
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
            <!--            通过循环对下拉框的数据 categoryOptions 展示-->
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>

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

        <!--  时间选择器 -->
        <el-form-item label="推送时间" prop="dateValue">
          <el-date-picker
              v-model="searchForm.dateValue"
              type="datetimerange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['12:00:00']">
          </el-date-picker>
        </el-form-item>
      </el-form>
      <el-row type="flex" justify="center">
        <el-button size="small" type="primary" @click="clickSearch">筛选</el-button>
        <!--          重置 需要做三个步骤 表单添加model  ref属性:model="searchForm" ref="searchForm" 在el-form-item里定义 pop属性-->
        <el-button size="small" type="success" @click="resetSearchForm('searchForm')">重置</el-button>
      </el-row>
    </el-card>
    <!--  表格区域-->
    <!--    卡片 card-->
    <el-card class="box-card" style="margin-top: 25px;">
      <div slot="header" class="clearfix">
        <!--  <i class="el-icon-s-grid"></i> 图标-->
        <span><i class="el-icon-s-grid"></i> 消息列表</span>
        <el-button style="float: right;" type="primary" size="small" @click="clickAddDialog">
          <!-- <i class="el-icon-circle-plus-outline"></i> 图标-->
          <i class="el-icon-circle-plus-outline"></i> 操作按钮
        </el-button>
      </div>
      <!--      Table表格-->
      <div>
        <el-table :data="tableData" border style="width: 100%">
          <el-table-column prop="date" label="日期"></el-table-column>
          <el-table-column prop="name" label="姓名"></el-table-column>
          <el-table-column prop="address" label="地址"></el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
              <!--Popconfirm 气泡确认框-->
              <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
<!--      Pagination 分页-->
      <el-row type="flex" justify="end" style="margin-top: 30px;">
        <el-pagination
            :total="page.totalCount"
            :page-size="page.perPageSize"
            background
            layout="prev, pager, next,jumper"
            @current-change="handleCurrentChange"
        >
        </el-pagination>
      </el-row>
    </el-card>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Push",
  data() {
    return {
      searchForm: {
        title: '',
        category: '',
        dateValue: '',
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible:false

    }
  },
  methods: {
    clickSearch() {
      console.log(this.clickSearch())
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    clickAddDialog() {
      this.dialogFormVisible = true;
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    handleClick(row) {
      console.log(row);
      this.dialogVisible = true;
    },

  }
}
</script>

<style scoped>

</style>
View Code

 消息推送-对话框(push.vue)

<template>
  <div>
    <!--    搜索-->
    <!--  element ui  卡片 card-->
    <el-card class="box-card" style="padding: 20px" size="small">
      <!--  element ui  行内表单-->
      <el-form :inline="true" class="demo-form-inline" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
          <!--          v-model="searchFrom.title" 数据的绑定 输入后可以显示在页面上-->
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
            <!--            通过循环对下拉框的数据 categoryOptions 展示-->
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>

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

        <!--  时间选择器 -->
        <el-form-item label="推送时间" prop="dateValue">
          <el-date-picker
              v-model="searchForm.dateValue"
              type="datetimerange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['12:00:00']">
          </el-date-picker>
        </el-form-item>
      </el-form>
      <el-row type="flex" justify="center">
        <el-button size="small" type="primary" @click="clickSearch">筛选</el-button>
        <!--          重置 需要做三个步骤 表单添加model  ref属性:model="searchForm" ref="searchForm" 在el-form-item里定义 pop属性-->
        <el-button size="small" type="success" @click="resetSearchForm('searchForm')">重置</el-button>
      </el-row>
    </el-card>
    <!--  表格区域-->
    <!--    卡片 card-->
    <el-card class="box-card" style="margin-top: 25px;">
      <div slot="header" class="clearfix">
        <!--  <i class="el-icon-s-grid"></i> 图标-->
        <span><i class="el-icon-s-grid"></i> 消息列表</span>
        <!--        @click="clickAddDialog 点击事件出现对话框-->
        <el-button style="float: right;" type="primary" size="small" @click="clickAddDialog">
          <!-- <i class="el-icon-circle-plus-outline"></i> 图标-->
          <i class="el-icon-circle-plus-outline"></i> 操作按钮
        </el-button>
      </div>
      <!--      Table表格-->
      <div>
        <el-table :data="tableData" border style="width: 100%">
          <el-table-column prop="date" label="日期"></el-table-column>
          <el-table-column prop="name" label="姓名"></el-table-column>
          <el-table-column prop="address" label="地址"></el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
              <!--Popconfirm 气泡确认框-->
              <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--      Pagination 分页-->
      <el-row type="flex" justify="end" style="margin-top: 30px;">
        <el-pagination
            :total="page.totalCount"
            :page-size="page.perPageSize"
            background
            layout="prev, pager, next,jumper"
            @current-change="handleCurrentChange"
        >
        </el-pagination>
      </el-row>

    </el-card>

    <!-- 对话框-->
    <el-dialog title="收货地址" :visible.sync="dialogFormVisible">
      <!--      表单 提交数据-->
      <el-form label-position="left" label-width="80px" :model="addForm">
        <el-form-item label="活动名称" prop="x1">
          <el-input autocomplete="off" v-model="addForm.x1"></el-input>
        </el-form-item>
        <el-form-item label="活动区域" prop="x2">
          <el-select placeholder="请选择活动区域" v-model="addForm.x2">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <!--        dialogFormVisible = false 点击取消 隐藏对话框-->
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>

    
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Push",
  data() {
    return {
      searchForm: {
        title: '',
        category: '',
        dateValue: '',
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,  // 对话框默认隐藏
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible: false

    }
  },
  methods: {
    clickSearch() {
      console.log(this.clickSearch())
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    clickAddDialog() { // 点击按钮 出现对话框
      this.dialogFormVisible = true; //对话框默认隐藏 true显示
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    handleClick(row) {
      console.log(row);
      this.dialogVisible = true;
    },

  }
}
</script>

<style scoped>

</style>
View Code
<template>
  <div>
    <!--    搜索-->
    <!--  element ui  卡片 card-->
    <el-card class="box-card" style="padding: 20px" size="small">
      <!--  element ui  行内表单-->
      <el-form :inline="true" class="demo-form-inline" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
          <!--          v-model="searchFrom.title" 数据的绑定 输入后可以显示在页面上-->
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
            <!--            通过循环对下拉框的数据 categoryOptions 展示-->
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>

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

        <!--  时间选择器 -->
        <el-form-item label="推送时间" prop="dateValue">
          <el-date-picker
              v-model="searchForm.dateValue"
              type="datetimerange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['12:00:00']">
          </el-date-picker>
        </el-form-item>
      </el-form>
      <el-row type="flex" justify="center">
        <el-button size="small" type="primary" @click="clickSearch">筛选</el-button>
        <!--          重置 需要做三个步骤 表单添加model  ref属性:model="searchForm" ref="searchForm" 在el-form-item里定义 pop属性-->
        <el-button size="small" type="success" @click="resetSearchForm('searchForm')">重置</el-button>
      </el-row>
    </el-card>
    <!--  表格区域-->
    <!--    卡片 card-->
    <el-card class="box-card" style="margin-top: 25px;">
      <div slot="header" class="clearfix">
        <!--  <i class="el-icon-s-grid"></i> 图标-->
        <span><i class="el-icon-s-grid"></i> 消息列表</span>
        <!--        @click="clickAddDialog 点击事件出现对话框-->
        <el-button style="float: right;" type="primary" size="small" @click="clickAddDialog">
          <!-- <i class="el-icon-circle-plus-outline"></i> 图标-->
          <i class="el-icon-circle-plus-outline"></i> 操作按钮
        </el-button>
      </div>
      <!--      Table表格-->
      <div>
        <el-table :data="tableData" border style="width: 100%">
          <el-table-column prop="date" label="日期"></el-table-column>
          <el-table-column prop="name" label="姓名"></el-table-column>
          <el-table-column prop="address" label="地址"></el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
              <!--Popconfirm 气泡确认框-->
              <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--      Pagination 分页-->
      <el-row type="flex" justify="end" style="margin-top: 30px;">
        <el-pagination
            :total="page.totalCount"
            :page-size="page.perPageSize"
            background
            layout="prev, pager, next,jumper"
            @current-change="handleCurrentChange"
        >
        </el-pagination>
      </el-row>

    </el-card>

    <!-- 操作  对话框-->
    <!--    :visible.sync="dialogFormVisible" 默认Flase 隐藏-->
    <el-dialog title="收货地址" :visible.sync="dialogFormVisible">
      <!--      表单 提交数据-->
      <el-form label-position="left" label-width="80px" :model="addForm">
        <el-form-item label="活动名称" prop="x1">
          <el-input autocomplete="off" v-model="addForm.x1"></el-input>
        </el-form-item>
        <el-form-item label="活动区域" prop="x2">
          <el-select placeholder="请选择活动区域" v-model="addForm.x2">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <!--        dialogFormVisible = false 点击取消 隐藏对话框-->
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 查看  对话框-->
    <!--    :visible.sync="dialogVisible"默认Flase 隐藏-->
    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
              </span>
    </el-dialog>

  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Push",
  data() {
    return {
      searchForm: {
        title: '',
        category: '',
        dateValue: '',
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,  // 对话框默认隐藏
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible: false // 对话框默认隐藏

    }
  },
  methods: {
    clickSearch() {
      console.log(this.clickSearch())
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    clickAddDialog() { // 点击按钮 出现对话框
      this.dialogFormVisible = true; //对话框默认隐藏 true显示
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    handleClick(row) { // 绑定查看按钮 点击 对框框显示
      console.log(row);
      this.dialogVisible = true;
    },

  }
}
</script>

<style scoped>

</style>
View Code

 sop计划(sop.vue)就是比push页多了一列 标签

<template>
  <div style="padding: 20px;">
    <el-card class="box-card">
      <el-form :inline="true" class="demo-form-inline" size="small" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>

        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button size="small" type="primary" @click="clickSearch">筛选</el-button>
          <el-button size="small" @click="resetSearchForm('searchForm')">重置</el-button>
        </el-form-item>

      </el-form>

    </el-card>

    <el-card class="box-card" style="margin-top: 25px;">
      <div slot="header" class="clearfix">
        <span><i class="el-icon-s-grid"></i> 消息列表</span>
        <el-button style="float: right;" type="primary" size="small" @click="clickAddDialog">
          <i class="el-icon-circle-plus-outline"></i> 操作按钮
        </el-button>
      </div>
      <div>
        <el-table :data="tableData" border style="width: 100%">
          <el-table-column prop="date" label="日期"></el-table-column>
          <el-table-column prop="name" label="姓名"></el-table-column>
          <el-table-column prop="address" label="地址"></el-table-column>
          
          <!--          比push页多了一列 标签-->
          <el-table-column label="状态">
            <template slot-scope="scope">
<!--              判断当前行的状态scope.row.status 如果是1显示成功 否则显示失败-->
              <el-tag v-if="scope.row.status === 1" type="success">成功</el-tag>
              <el-tag v-else type="danger">失败</el-tag>
            </template>
          </el-table-column>
          
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>

              <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <el-row type="flex" justify="end" style="margin-top: 30px;">
        <el-pagination
            :total="page.totalCount"
            :page-size="page.perPageSize"
            background
            layout="prev, pager, next,jumper"
            @current-change="handleCurrentChange"
        >
        </el-pagination>
      </el-row>
    </el-card>


    <el-dialog title="收货地址" :visible.sync="dialogFormVisible">
      <el-form label-position="left" label-width="80px" :model="addForm">
        <el-form-item label="活动名称" prop="x1">
          <el-input autocomplete="off" v-model="addForm.x1"></el-input>
        </el-form-item>
        <el-form-item label="活动区域" prop="x2">
          <el-select placeholder="请选择活动区域" v-model="addForm.x2">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
              </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Sop",
  data() {
    return {
      searchForm: {
        title: "",
        category: ""
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
          status: 1 // 状态
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333,
          status: 2
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333,
          status: 1
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333,
          status: 1
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible: false
    }
  },
  methods: {
    clickSearch() {
      console.log(this.searchForm);
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    handleClick(row) {
      console.log(row);
      this.dialogVisible = true;
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    clickAddDialog() {
      this.dialogFormVisible = true;
    },
  }
}
</script>

<style scoped>

</style>
View Code

 

6.任务宝

活动管理-路由设计实现(index.js)

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
    {
        path: '/',
        name: 'Layout',
        component: () => import('../views/Layout.vue'),
        children: [ // Layout的子路由

            {
                path: 'task',
                name: 'Task',
                component: () => import('../views/task/TaskLayout.vue'),
                children: [ // TaskLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect:"activity", // 就直接跳转到activity组件

                    },
                    {
                        path: "activity",
                        name: 'Activity',
                        component: () => import('../views/task/Activity.vue'),
                        children:[
                            { // 重定向 同理task
                                path: "/",
                                redirect: "list"
                            },
                            {
                                path: "list", // 活动列表路由
                                name: 'ActivityList',
                                component: () => import('../views/task/ActivityList.vue'),
                            },
                            {
                                path: "create", // 新建活动
                                name: 'ActivityCreate',
                                component: () => import('../views/task/ActivityCreate.vue'),
                            }
                        ]

                    },
                    {
                        path: "promo",
                        name: 'Promo',
                        component: () => import('../views/task/Promo.vue'),
                    },
                    {
                        path: "stat",
                        name: 'Stat',
                        component: () => import('../views/task/Stat.vue'),
                    },
                    {
                        path: "fans",
                        name: 'Fans',
                        component: () => import('../views/task/Fans.vue'),
                    },
                ]

            },

            {
                path: 'msg',
                name: 'Msg',
                component: () => import('../views/msg/MsgLayout.vue'),
                children: [//MsgLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect:"push", // 就直接跳转到push组件

                    },

                    {
                        path: "push",
                        name: 'Push',
                        component: () => import('../views/msg/Push.vue'),
                    },
                    {
                        path: "sop",
                        name: 'Sop',
                        component: () => import('../views/msg/Sop.vue'),
                    },
                ]
            },

            {
                path: 'auth',
                name: 'Auth',
                component: () => import('../views/auth/Auth.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'Login',

        component: () => import('../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import( '../views/AboutView.vue')
    }
]

const router = new VueRouter({
    routes
})

export default router
View Code

活动管理-列表

<template>
  <div style="padding: 20px">
<!--    按钮的跳转-->
    <router-link :to="{name:'ActivityCreate'}">
      <el-button type="primary" size="small"><i class="el-icon-circle-plus-outline"></i> 新建活动</el-button>
    </router-link>

    <el-row style="margin-top: 25px;">
      <el-form :inline="true" class="demo-form-inline" size="small" :model="searchForm" ref="searchForm">


        <el-form-item label="活动状态" prop="category">
          <el-select placeholder="全部状态" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="公众号" prop="category">
          <el-select placeholder="全部公众号" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="活动名称" prop="title">
          <el-input placeholder="活动名称" v-model="searchForm.title"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary">筛选</el-button>
          <el-button size="small">重置</el-button>
        </el-form-item>

      </el-form>

    </el-row>

    <el-row :gutter="20">
<!--      布局 el-col  类似于栅格系统-->
<!--      style="width: 240px 固定宽度   12 元素个数-->
      <el-col style="width: 240px;margin-bottom: 20px;" v-for="(o, index) in 12" :key="o">
        <el-card :body-style="{ padding: '0px' }">
          <img style="height: 160px;width: 100%;"
               src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png"
               class="image">
          <div style="padding: 14px;">
            <span>好吃的汉堡{{index}}</span>
            <el-row style="margin-top: 8px;">
              <el-button icon="el-icon-search" size="mini" circle></el-button>
              <el-button icon="el-icon-edit" size="mini" circle></el-button>
              <el-button icon="el-icon-check" size="mini" circle></el-button>
              <el-button icon="el-icon-message" size="mini" circle></el-button>
            </el-row>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  name: "ActivityList",
  data() {
    return {
      searchForm: {
        title: "",
        category: ""
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      currentDate: new Date()
    }
  },
  created() { // 访问组件自动加载
    this.axios.get("/base/test/").then(res => {
      console.log("请求成功", res);
    }).catch(reason => {
      console.log('请求失败', reason);
      return reason;
    })
  }

}
</script>

<style scoped>

.image {
  width: 100%;
  display: block;
}

</style>
View Code

活动管理-新建

<template>
  <div style="padding: 20px;">
    <el-row type="flex" justify="end">
      <el-button type="success" size="small"><i class="el-icon-setting"></i> 保存</el-button>
    </el-row>
    <el-tabs tab-position="left" v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="活动设置" name="tab1">活动设置</el-tab-pane>
      <el-tab-pane label="参与公众号" name="tab2">参与公众号</el-tab-pane>
      <el-tab-pane label="奖励设置" name="tab3">奖励设置</el-tab-pane>
      <el-tab-pane label="海报设置" name="tab4">海报设置</el-tab-pane>
      <el-tab-pane label="进度消息" name="tab5">进度消息</el-tab-pane>
      <el-tab-pane label="其他消息" name="tab6">其他消息</el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
export default {
  name: "ActivityCreate",
  data() {
    return {
      activeName: "tab2"
    }
  },
  created() { // 进入组件会自动加载
    // 正在加载中的图标样式
    const loading = this.$loading({
      lock: true,
      text: '努力加载中',
      spinner: 'el-icon-loading'
    });

    setTimeout(() => {
      loading.close();
    }, 2000);
  },
  methods: {
    handleClick(tab, event) {
      console.log(tab, event);
    }
  }
}
</script>

<style scoped>

</style>
View Code

推广码(Promo)

<!--和消息宝类似-->
<template>
  <div style="padding: 20px;">
<!--    搜索-->
    <el-card class="box-card">
      <el-form :inline="true" class="demo-form-inline" size="small" :model="searchForm" ref="searchForm">
        <el-form-item label="标题" prop="title">
          <el-input placeholder="标题" v-model="searchForm.title"></el-input>
        </el-form-item>

        <el-form-item label="类型" prop="category">
          <el-select placeholder="类型" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button size="small" type="primary" @click="clickSearch">筛选</el-button>
          <el-button size="small" @click="resetSearchForm('searchForm')">重置</el-button>
        </el-form-item>

      </el-form>

    </el-card>

    <el-card class="box-card" style="margin-top: 25px;">
      <div slot="header" class="clearfix">
        <span><i class="el-icon-s-grid"></i> 消息列表</span>
        <el-button style="float: right;" type="primary" size="small" @click="clickAddDrawer">
          <i class="el-icon-circle-plus-outline"></i> 新建推广码
        </el-button>
      </div>
<!--      表格-->
      <div>
        <el-table :data="tableData" border style="width: 100%">
          <el-table-column prop="date" label="日期"></el-table-column>
          <el-table-column prop="name" label="姓名"></el-table-column>
          <el-table-column prop="address" label="地址"></el-table-column>
          <el-table-column label="二维码">

            <template slot-scope="scope">
<!--              二维码图片image 组件-->
<!--              popover 弹框组件  trigger="hover" 鼠标放上会激活  slot="reference"没激活展示正常图 激活后展示弹窗的图-->
              <el-popover
                  placement="right"
                  trigger="hover">
                <div>
<!--                  scope.row.url  绑定属性-->
                  <el-image
                      style="width: 140px; height: 140px"
                      :src="scope.row.url"
                      fit="fit"></el-image>
                </div>
                <el-image slot="reference" style="width: 40px; height: 40px" :src="scope.row.url"
                          fit="fit"></el-image>
              </el-popover>

            </template>

          </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>

              <el-button @click="handleEditClick(scope.row)" type="text" size="small">编辑</el-button>


              <el-popconfirm style="display: inline-block;margin-left: 10px;" title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>

            </template>
          </el-table-column>
        </el-table>
      </div>
      <el-row type="flex" justify="end" style="margin-top: 30px;">
        <el-pagination
            :total="page.totalCount"
            :page-size="page.perPageSize"
            background
            layout="prev, pager, next,jumper"
            @current-change="handleCurrentChange"
        >
        </el-pagination>
      </el-row>
    </el-card>


    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
              </span>
    </el-dialog>

<!--    抽屉标签-->
<!--   direction="ltr"显示方向  :visible.sync="drawerVisible"是否显示和数据进行绑定默认flase不显示 点击 新建推广码 clickAddDrawer的时候赋值为true-->
    <el-drawer title="我是标题" :visible.sync="drawerVisible" :before-close="handleDrawerClose" direction="ltr">
      <!--      抽屉里的内容-->
      <div style="padding: 25px;">
        <el-form label-position="left" label-width="80px" :model="addForm" size="small">
          <el-form-item label="活动名称" prop="x1">
            <el-input autocomplete="off" v-model="addForm.x1"></el-input>
          </el-form-item>
          <el-form-item label="活动区域" prop="x2">
            <el-select placeholder="请选择活动区域" v-model="addForm.x2">
              <el-option label="区域一" value="shanghai"></el-option>
              <el-option label="区域二" value="beijing"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button @click="dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-drawer>

  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Promo",
  data() {
    return {
      drawerVisible: false,
      searchForm: {
        title: "",
        category: ""
      },
      categoryOptions: [
        {
          value: '1',
          label: '黄金糕'
        }, {
          value: '2',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
          url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
          status: 1
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333,
          url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
          status: 2
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333,
          url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
          status: 1
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333,
          url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
          status: 1
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible: false
    }
  },
  methods: {
    clickSearch() {
      console.log(this.searchForm);
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    handleClick(row) {
      console.log(row);
      this.dialogVisible = true;
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    clickAddDrawer() {
      this.drawerVisible = true; // 点击新建 抽屉就会出来
    },
    handleDrawerClose(done) {// 关闭抽屉
      console.log("要关闭了");
      done(); // 执行done() 才会关闭
    },
    handleEditClick(row){ // 编辑按钮  row当前行数据
      console.log(row);
      this.drawerVisible = true;
    }
  }
}
</script>

<style scoped>

</style>
View Code

参与粉丝(fans)

<template>
  <div style="padding: 20px;">
    <el-card class="box-card">
      <el-form :inline="true" class="demo-form-inline" size="small" :model="searchForm" ref="searchForm">
<!--两个下拉框-->
        <el-form-item label="当前任务" prop="category" style="margin-bottom: 0">
<!--          @change="changeTask" 选中值发生变化触发-->
          <el-select placeholder="全部任务" v-model="searchForm.task" @change="changeTask">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>


        <el-form-item label="推广码" prop="category" style="margin-bottom: 0">
          <el-select placeholder="全部渠道" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

      </el-form>

    </el-card>

    <!--   <el-button @click="selectedOne">点我</el-button>-->
    <el-row style="margin-top: 30px;">
<!--按钮和输入框和两tab悬浮 style="float: right 在同一行-->
      <el-row justify="end" type="flex" style="float: right;z-index: 1">
<!--        输入框-->
        <el-input
            style="margin-right: 10px;"
            size="small"
            placeholder="请输入内容"
            suffix-icon="el-icon-search"
            v-model="keySearch">
        </el-input>
        <el-button size="small" type="primary">导出</el-button>
        <el-button size="small" type="primary" @click="addToBlackList">移入黑名单</el-button>
        <el-button size="small" type="primary">移出黑名单</el-button>
      </el-row>

<!--tab标签页-->
<!--      两个tab 参与用户 黑名单-->
      <el-tabs v-model="activeName" type="card">
        <el-tab-pane label="参与用户" name="first">
          <!--tab页里的表格-->
          <!-- 多选框  ref="myTable"   绑定选择事件@selection-change="handleSelectionChange"-->
          <el-table ref="myTable" :data="tableData" style="width: 100%"
                    @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column prop="date" label="日期"></el-table-column>
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
            <el-table-column label="状态">
              <template slot-scope="scope">
                <el-tag v-if="scope.row.status === 1" type="success">成功</el-tag>
                <el-tag v-else type="danger">失败</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>

                <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                  <el-button slot="reference" type="text" size="small">删除</el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <el-row type="flex" justify="end" style="margin-top: 30px;">
            <el-pagination
                :total="page.totalCount"
                :page-size="page.perPageSize"
                background
                layout="prev, pager, next,jumper"
                @current-change="handleCurrentChange"
            >
            </el-pagination>
          </el-row>
        </el-tab-pane>


        <el-tab-pane label="黑名单" name="second">
          <el-table :data="tableData" border style="width: 100%">
            <!--tab页里的表格-->
            <el-table-column prop="date" label="日期"></el-table-column>
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
            <el-table-column label="状态">
              <template slot-scope="scope">
                <el-tag v-if="scope.row.status === 1" type="success">成功</el-tag>
                <el-tag v-else type="danger">失败</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>

                <el-popconfirm title="这是一段内容确定删除吗?" @confirm="confirmDelete(scope.row)">
                  <el-button slot="reference" type="text" size="small">删除</el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <el-row type="flex" justify="end" style="margin-top: 30px;">
            <el-pagination
                :total="page.totalCount"
                :page-size="page.perPageSize"
                background
                layout="prev, pager, next,jumper"
                @current-change="handleCurrentChange"
            >
            </el-pagination>
          </el-row>
        </el-tab-pane>
      </el-tabs>

    </el-row>


    <el-dialog title="收货地址" :visible.sync="dialogFormVisible">
      <el-form label-position="left" label-width="80px" :model="addForm">
        <el-form-item label="活动名称" prop="x1">
          <el-input autocomplete="off" v-model="addForm.x1"></el-input>
        </el-form-item>
        <el-form-item label="活动区域" prop="x2">
          <el-select placeholder="请选择活动区域" v-model="addForm.x2">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
              </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Fans",
  data() {
    return {
      keySearch: "",
      activeName: "first",
      searchForm: {
        task: "3",
        category: ""
      },
      categoryOptions: [
        {
          value: '11',
          label: '黄金糕'
        }, {
          value: '12',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
          status: 1
        }, {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333,
          status: 2
        }, {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333,
          status: 1
        }, {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333,
          status: 1
        }],
      page: {
        totalCount: 10000,
        perPageSize: 20
      },
      dialogFormVisible: false,
      addForm: {
        x1: "",
        x2: ""
      },
      dialogVisible: false,
      checkDataList: [] // 维护一个列表存数据
    }
  },
  mounted() { //触发事件会选择
    this.$refs.myTable.toggleRowSelection(this.tableData[3]);
  },
  methods: {
    clickSearch() {
      console.log(this.searchForm);
    },
    resetSearchForm(formName) {
      this.$refs[formName].resetFields();
    },
    handleClick(row) {
      console.log(row);
      this.dialogVisible = true;
    },
    confirmDelete(row) {
      console.log("确定删除", row);
    },
    handleCurrentChange(page) {
      console.log("想要查看:", page);
    },
    clickAddDialog() {
      this.dialogFormVisible = true;
    },
    changeTask(obj) {
      console.log("修改任务", obj);
    },
    handleSelectionChange(valueList) {
      console.log(valueList);
      this.checkDataList = valueList; // checkDataList维护一个列表 存选中的数据
    },
    selectedOne() {
      this.$refs.myTable.toggleRowSelection(this.tableData[2]);
    },
    addToBlackList() {
      // 获取已经选中的列表里的数据
      console.log('移入黑名单', this.checkDataList);
    }
  }
}
</script>

<style scoped>

</style>
View Code

数据统计

下载
npm install highcharts-vue

main.js配置 import HighchartsVue from 'highcharts-vue' ​ Vue.use(HighchartsVue)

官网:

文档:https://www.highcharts.com.cn/docs/highcharts-vue

<template>
  <div style="padding: 20px;">
<!--    搜索-->
    <el-card class="box-card" shadow="never">
      <el-form :inline="true" class="demo-form-inline" size="small" :model="searchForm" ref="searchForm">

        <el-form-item label="当前任务" prop="category" style="margin-bottom: 0">
          <el-select placeholder="全部任务" v-model="searchForm.task" @change="changeTask">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>


        <el-form-item label="推广码" prop="category" style="margin-bottom: 0">
          <el-select placeholder="全部渠道" v-model="searchForm.category">
            <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
                       :value="item.value"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>

      </el-form>

    </el-card>
<!--:span="12"  flex布局 -->
    <el-row style="margin-top: 30px;" :gutter="20">
<!--      这是左边-->
      <el-col :span="12">
<!--面板-->
        <el-row type="flex" justify="space-between" :gutter="20" style="flex-wrap: wrap">
          <el-col :span="12">
            <el-card shadow="never" class="stat-panel">
              <div class="row">
                <el-row type="flex" justify="space-between">
                  <div>
                    <div style="font-size: 40px;font-weight: bold">0</div>
                    <div>今日新增</div>
                  </div>
                  <div>
                    <i class="el-icon-attract" style="font-size: 60px;color: #0c8eff"></i>
                  </div>
                </el-row>
                <el-row type="flex" justify="space-between">
                  <div>昨日数据:0</div>
                  <div>累计:23</div>
                </el-row>
              </div>
            </el-card>
          </el-col>
          <el-col :span="12">
            <el-card shadow="never" class="stat-panel">
              <div class="row">
                <el-row type="flex" justify="space-between">
                  <div>
                    <div style="font-size: 40px;font-weight: bold">0</div>
                    <div>今日新增</div>
                  </div>
                  <div>
                    <i class="el-icon-attract" style="font-size: 60px;color: #0c8eff"></i>
                  </div>
                </el-row>
                <el-row type="flex" justify="space-between">
                  <div>昨日数据:0</div>
                  <div>累计:23</div>
                </el-row>
              </div>
            </el-card>
          </el-col>
          <el-col :span="12" style="margin-top: 8px">
            <el-card shadow="never" class="stat-panel">
              <div class="row">
                <el-row type="flex" justify="space-between">
                  <div>
                    <div style="font-size: 40px;font-weight: bold">0</div>
                    <div>今日新增</div>
                  </div>
                  <div>
                    <i class="el-icon-attract" style="font-size: 60px;color: #0c8eff"></i>
                  </div>
                </el-row>
                <el-row type="flex" justify="space-between">
                  <div>昨日数据:0</div>
                  <div>累计:23</div>
                </el-row>
              </div>
            </el-card>
          </el-col>
          <el-col :span="12" style="margin-top: 8px">
            <el-card shadow="never" class="stat-panel">
              <div class="row">
                <el-row type="flex" justify="space-between">
                  <div>
                    <div style="font-size: 40px;font-weight: bold">0</div>
                    <div>今日新增</div>
                  </div>
                  <div>
                    <i class="el-icon-attract" style="font-size: 60px;color: #0c8eff"></i>
                  </div>
                </el-row>
                <el-row type="flex" justify="space-between">
                  <div>昨日数据:0</div>
                  <div>累计:23</div>
                </el-row>
              </div>
            </el-card>
          </el-col>
        </el-row>

      </el-col>
<!--      这是右边图表-->
      <el-col :span="12">

<!--加一个el-card卡片面板 可以调图表大小-->
        <el-card class="box-card" shadow="never">
<!--          第三方的图表组件  看官网使用  需要下载包-->
          <highcharts :options="opt1" style="height: 330px;min-width: 300px"></highcharts>
        </el-card>

      </el-col>
    </el-row>

<!--底部两侧图表 和上面同理-->
    <el-row style="margin-top: 30px;" :gutter="20" type="flex" justify="space-between">
      <el-col :xs="12">
        <el-card class="box-card" shadow="never">
          <div slot="header">
            <span>xx统计情况</span>
          </div>
          <highcharts :options="opt2" style="height: 330px;min-width: 300px"></highcharts>
        </el-card>
      </el-col>
      <el-col :xs="12">
        <el-card class="box-card" shadow="never">
          <div slot="header">
            <span>裂变情况</span>
          </div>
          <highcharts :options="opt3" style="height: 330px;min-width: 300px"></highcharts>
        </el-card>
      </el-col>
    </el-row>

  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "Stat",
  data() {
    return {
      searchForm: {
        task: "3",
        category: ""
      },
      categoryOptions: [
        {
          value: '11',
          label: '黄金糕'
        }, {
          value: '12',
          label: '双皮奶'
        }, {
          value: '3',
          label: '蚵仔煎'
        }, {
          value: '4',
          label: '龙须面'
        }, {
          value: '5',
          label: '北京烤鸭'
        }],
      opt1: { // 图表配置
        title: {
          text: '2010 ~ 2016 年太阳能行业就业人员发展情况'
        },
        subtitle: {
          text: '数据来源:thesolarfoundation.com'
        },
        yAxis: {
          title: {
            text: '就业人数'
          }
        },
        legend: {
          layout: 'vertical',
          align: 'right',
          verticalAlign: 'middle'
        },
        plotOptions: {
          series: {
            label: {
              connectorAllowed: false
            },
            pointStart: 2010
          }
        },
        series: [{
          name: '安装,实施人员',
          data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
        }, {
          name: '工人',
          data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
        }, {
          name: '销售',
          data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
        }, {
          name: '项目开发',
          data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
        }, {
          name: '其他',
          data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
        }],
        responsive: {
          rules: [{
            condition: {
              maxWidth: 500
            },
            chartOptions: {
              legend: {
                layout: 'horizontal',
                align: 'center',
                verticalAlign: 'bottom'
              }
            }
          }]
        }
      },
      opt2: {
        chart: {
          plotBackgroundColor: null,
          plotBorderWidth: null,
          plotShadow: false,
          type: 'pie'
        },
        title: {
          text: '2018 年浏览器市场份额'
        },
        tooltip: {
          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        },
        plotOptions: {
          pie: {
            allowPointSelect: true,
            cursor: 'pointer',
            dataLabels: {
              enabled: false
            },
            showInLegend: true
          }
        },
        series: [{
          name: 'Brands',
          colorByPoint: true,
          data: [{
            name: 'Chrome',
            y: 61.41,
            sliced: true,
            selected: true
          }, {
            name: 'Internet Explorer',
            y: 11.84
          }, {
            name: 'Firefox',
            y: 10.85
          }, {
            name: 'Edge',
            y: 4.67
          }, {
            name: 'Safari',
            y: 4.18
          }, {
            name: 'Other',
            y: 7.05
          }]
        }]
      },
      opt3: {
        chart: {
          type: 'column'
        },
        title: {
          text: '月平均降雨量'
        },
        subtitle: {
          text: '数据来源: WorldClimate.com'
        },
        xAxis: {
          categories: [
            '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'
          ],
          crosshair: true
        },
        yAxis: {
          min: 0,
          title: {
            text: '降雨量 (mm)'
          }
        },
        tooltip: {
          // head + 每个 point + footer 拼接成完整的 table
          headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
          pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
              '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
          footerFormat: '</table>',
          shared: true,
          useHTML: true
        },
        plotOptions: {
          column: {
            borderWidth: 0
          }
        },
        series: [{
          name: '东京',
          data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
        }, {
          name: '纽约',
          data: [83.6, 78.8, 98.5, 93.4, 106.0, 84.5, 105.0, 104.3, 91.2, 83.5, 106.6, 92.3]
        }, {
          name: '伦敦',
          data: [48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2]
        }, {
          name: '柏林',
          data: [42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 47.6, 39.1, 46.8, 51.1]
        }]
      }

    }
  }
}
</script>

<style scoped>
.stat-panel .row {
  height: 140px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
</style>
View Code

 

 

小bug修改:

访问链接地址上有# ,访问没有路由地址没有404展示

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
 
    {
        path: '/',
        name: 'Layout',
        component: () => import('../views/Layout.vue'),
        children: [ // Layout的子路由
            {
                path: "",
                redirect: "task",
            },

            {
                path: 'task',
                name: 'Task',
                component: () => import('../views/task/TaskLayout.vue'),
                children: [ // TaskLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect: "activity", // 就直接跳转到activity组件

                    },
                    {
                        path: "activity",
                        name: 'Activity',
                        component: () => import('../views/task/Activity.vue'),
                        children: [
                            { // 重定向 同理task
                                path: "/",
                                redirect: "list"
                            },
                            {
                                path: "list", // 活动列表路由
                                name: 'ActivityList',
                                component: () => import('../views/task/ActivityList.vue'),
                            },
                            {
                                path: "create", // 新建活动
                                name: 'ActivityCreate',
                                component: () => import('../views/task/ActivityCreate.vue'),
                            }
                        ]

                    },
                    {
                        path: "promo",
                        name: 'Promo',
                        component: () => import('../views/task/Promo.vue'),
                    },
                    {
                        path: "stat",
                        name: 'Stat',
                        component: () => import('../views/task/Stat.vue'),
                    },
                    {
                        path: "fans",
                        name: 'Fans',
                        component: () => import('../views/task/Fans.vue'),
                    },
                ]

            },

            {
                path: 'msg',
                name: 'Msg',
                component: () => import('../views/msg/MsgLayout.vue'),
                children: [//MsgLayout的子路由
                    {
                        path: "/",  // task后面是空的话
                        redirect: "push", // 就直接跳转到push组件

                    },

                    {
                        path: "push",
                        name: 'Push',
                        component: () => import('../views/msg/Push.vue'),
                    },
                    {
                        path: "sop",
                        name: 'Sop',
                        component: () => import('../views/msg/Sop.vue'),
                    },
                ]
            },

            {
                path: 'auth',
                name: 'Auth',
                component: () => import('../views/auth/Auth.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'Login',

        component: () => import('../views/Login.vue')
    },
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import( '../views/AboutView.vue')
    },
    {// 如果以上的路由都没有匹配上  匹配上了/*  则展示 404组件
        path: '/*',
        component: () => import('../views/NotFound.vue')
    }
]

const router = new VueRouter({
    routes,
    mode: "history" // history浏览器的模式  没有#的路由
})


export default router
View Code

 

posted @ 2022-07-07 15:24  贰号猿  阅读(3602)  评论(0)    收藏  举报