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
需要的组件:

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>
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

一级菜单(菜单的切换 默认选中):
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>
子组件(TaskLayout MsgLayout AuthLayout ):
<template> <div>task</div> </template> <script> export default { name: "TaskLayout" } </script> <style scoped> </style>
路由(包含子路由)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
二级菜单-展示:

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>
子路由(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>
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
二级菜单-默认选中:
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>
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>
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
<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>
消息推送的-搜素(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>
消息推送-表格区域(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>
消息推送-对话框(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>
<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>
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>
活动管理-路由设计实现(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
活动管理-列表
<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>
活动管理-新建
<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>
推广码(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>
参与粉丝(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>
数据统计
下载
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>
小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



浙公网安备 33010602011771号