├── .browserslistrc ├── public ├── favicon.ico └── index.html ├── babel.config.js ├── src ├── assets │ └── img │ │ ├── 404.png │ │ ├── cat.jpg │ │ ├── del.png │ │ ├── hou.png │ │ ├── min.png │ │ ├── sec.png │ │ ├── admire.png │ │ ├── avatar.jpg │ │ ├── back.jpg │ │ ├── back.png │ │ ├── ball.jpg │ │ ├── header.jpg │ │ ├── home.jpeg │ │ ├── home.jpg │ │ ├── icons.png │ │ ├── pic_bg.png │ │ ├── reply.png │ │ ├── collect.png │ │ ├── default.gif │ │ ├── default.jpg │ │ ├── imgicon.png │ │ ├── login_bg.jpg │ │ ├── selected.png │ │ ├── toutiao.png │ │ ├── logo_admin.png │ │ ├── logo_index.png │ │ ├── wap-preview.png │ │ └── collect_select.png ├── utils │ ├── eventBus.js │ └── request.js ├── App.vue ├── constant │ └── API.js ├── views │ ├── 404.vue │ ├── home │ │ ├── home.vue │ │ └── index.vue │ ├── picture │ │ └── index.vue │ ├── comment │ │ └── index.vue │ ├── account │ │ └── index.vue │ ├── login │ │ └── index.vue │ ├── material │ │ └── index.vue │ ├── publish │ │ └── index.vue │ └── articles │ │ └── index.vue ├── actions │ └── articles.js ├── components │ ├── common │ │ ├── bread-crumb.vue │ │ ├── star-rain.vue │ │ └── write-card.vue │ ├── index.js │ ├── publish │ │ ├── cover-image.vue │ │ └── select-image.vue │ ├── home │ │ ├── layout-aside.vue │ │ └── layout-header.vue │ └── star.js ├── main.js ├── permission │ └── index.js ├── styles │ └── index.less └── router │ └── index.js ├── .editorconfig ├── .gitignore ├── .eslintrc.js ├── README.md ├── package.json └── index.html /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/img/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/404.png -------------------------------------------------------------------------------- /src/assets/img/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/cat.jpg -------------------------------------------------------------------------------- /src/assets/img/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/del.png -------------------------------------------------------------------------------- /src/assets/img/hou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/hou.png -------------------------------------------------------------------------------- /src/assets/img/min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/min.png -------------------------------------------------------------------------------- /src/assets/img/sec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/sec.png -------------------------------------------------------------------------------- /src/assets/img/admire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/admire.png -------------------------------------------------------------------------------- /src/assets/img/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/avatar.jpg -------------------------------------------------------------------------------- /src/assets/img/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/back.jpg -------------------------------------------------------------------------------- /src/assets/img/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/back.png -------------------------------------------------------------------------------- /src/assets/img/ball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/ball.jpg -------------------------------------------------------------------------------- /src/assets/img/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/header.jpg -------------------------------------------------------------------------------- /src/assets/img/home.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/home.jpeg -------------------------------------------------------------------------------- /src/assets/img/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/home.jpg -------------------------------------------------------------------------------- /src/assets/img/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/icons.png -------------------------------------------------------------------------------- /src/assets/img/pic_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/pic_bg.png -------------------------------------------------------------------------------- /src/assets/img/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/reply.png -------------------------------------------------------------------------------- /src/utils/eventBus.js: -------------------------------------------------------------------------------- 1 | // 公共实例 2 | import Vue from 'vue' 3 | export default new Vue() // 公共实例 => 实例化了一个Vue 4 | -------------------------------------------------------------------------------- /src/assets/img/collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/collect.png -------------------------------------------------------------------------------- /src/assets/img/default.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/default.gif -------------------------------------------------------------------------------- /src/assets/img/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/default.jpg -------------------------------------------------------------------------------- /src/assets/img/imgicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/imgicon.png -------------------------------------------------------------------------------- /src/assets/img/login_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/login_bg.jpg -------------------------------------------------------------------------------- /src/assets/img/selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/selected.png -------------------------------------------------------------------------------- /src/assets/img/toutiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/toutiao.png -------------------------------------------------------------------------------- /src/assets/img/logo_admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/logo_admin.png -------------------------------------------------------------------------------- /src/assets/img/logo_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/logo_index.png -------------------------------------------------------------------------------- /src/assets/img/wap-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/wap-preview.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /src/assets/img/collect_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiruohanyu/90heimatoutiao/HEAD/src/assets/img/collect_select.png -------------------------------------------------------------------------------- /src/constant/API.js: -------------------------------------------------------------------------------- 1 | export const API_ARTICLES = '/articles' // 设置一个常量 作为请求地址 2 | export const API_CHANNELS = '/channels' // 频道地址 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /src/views/404.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /src/actions/articles.js: -------------------------------------------------------------------------------- 1 | // 专门放置文章请求的 2 | // 获取文章 3 | import request from '../utils/request' 4 | import { API_ARTICLES, API_CHANNELS } from '../constant/API' 5 | export function getArticles (params) { 6 | return request({ 7 | url: API_ARTICLES, 8 | params 9 | }) 10 | } 11 | // 获取频道数据 12 | export function getChannels () { 13 | return request({ 14 | url: API_CHANNELS 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 90heimatoutiao 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /src/components/common/bread-crumb.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import './permission' // 引用权限模块 4 | import router from './router' 5 | import ElementUI from 'element-ui' // 引入模块 6 | import Component from './components' 7 | import 'element-ui/lib/theme-chalk/index.css' // 引入样式 8 | import './styles/index.less' // 引入初始化样式 9 | import axios from './utils/request' 10 | Vue.prototype.$axios = axios // 赋值给全局对象 11 | Vue.use(ElementUI) // 全局注册 12 | Vue.use(Component) // 全局注册 13 | Vue.config.productionTip = false 14 | 15 | new Vue({ 16 | router, 17 | render: h => h(App) 18 | }).$mount('#app') 19 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 90heimatoutiao 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/permission/index.js: -------------------------------------------------------------------------------- 1 | 2 | // 处理路由拦截器 导航守卫 3 | import router from '../router' 4 | import progresss from 'nprogress' 5 | import 'nprogress/nprogress.css' 6 | // 全局前置守卫 当 路由发生变化时 这个方法里的回调函数就会执行 7 | router.beforeEach(function (to, from, next) { 8 | progresss.start() // 开启进度条 9 | // 权限拦截 认为有token 让过去 没token不让过 10 | if (to.path.startsWith('/home')) { 11 | // 确定要去检查的范围 12 | let token = window.localStorage.getItem('user-token') 13 | if (token) { 14 | next() // 放过 15 | } else { 16 | next('/login') // 跳转到登录页 17 | } 18 | } else { 19 | next() // 直接放过 20 | } 21 | }) 22 | router.afterEach(() => { 23 | // setTimeout(() => progresss.done(), 1000) 24 | progresss.done() 25 | // 关闭进度条 26 | }) 27 | -------------------------------------------------------------------------------- /src/views/home/home.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | 35 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import layoutAside from './home/layout-aside' 2 | import layoutHeader from './home/layout-header' 3 | import breadCrumb from './common/bread-crumb' 4 | import { quillEditor } from 'vue-quill-editor' // quill编辑器组件对象 5 | import CoverImage from './publish/cover-image' 6 | import SelectImage from './publish/select-image' 7 | import WriteCard from './common/write-card' 8 | import StarRain from './common/star-rain' 9 | import 'quill/dist/quill.core.css' 10 | import 'quill/dist/quill.snow.css' 11 | import 'quill/dist/quill.bubble.css' 12 | export default { 13 | install (Vue) { 14 | Vue.component('layout-aside', layoutAside) // 注册一个全局组件 15 | Vue.component('layout-header', layoutHeader) // 注册一个全局组件 16 | Vue.component('bread-crumb', breadCrumb) // 全局注册一个面包屑组件 17 | Vue.component('quill-editor', quillEditor) // 注册一个全局的富文本编辑器 18 | Vue.component('cover-image', CoverImage) // 注册一个封面组件 19 | Vue.component('select-image', SelectImage) // 注册一个素材库和上传图片组件 20 | Vue.component('WriteCard', WriteCard) 21 | Vue.component('StarRain', StarRain) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/views/home/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /src/styles/index.less: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | *, 6 | *:before, 7 | *:after { 8 | box-sizing: inherit; 9 | } 10 | 11 | li { 12 | list-style: none; 13 | } 14 | dl, 15 | dd, 16 | dt, 17 | ul, 18 | li { 19 | margin: 0; 20 | padding: 0; 21 | } 22 | 23 | .no-padding { 24 | padding: 0px !important; 25 | } 26 | 27 | .padding-content { 28 | padding: 4px 0; 29 | } 30 | 31 | a:focus, 32 | a:active { 33 | outline: none; 34 | } 35 | 36 | a, 37 | a:focus, 38 | a:hover { 39 | cursor: pointer; 40 | color: inherit; 41 | text-decoration: none; 42 | } 43 | 44 | b { 45 | font-weight: normal; 46 | } 47 | 48 | div:focus { 49 | outline: none; 50 | } 51 | 52 | .fr { 53 | float: right; 54 | } 55 | 56 | .fl { 57 | float: left; 58 | } 59 | 60 | .pr-5 { 61 | padding-right: 5px; 62 | } 63 | 64 | .pl-5 { 65 | padding-left: 5px; 66 | } 67 | 68 | .block { 69 | display: block; 70 | } 71 | 72 | .pointer { 73 | cursor: pointer; 74 | } 75 | 76 | .inlineBlock { 77 | display: block; 78 | } 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "90heimatoutiao", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^3.4.3", 13 | "echarts": "^4.6.0", 14 | "element-ui": "^2.13.0", 15 | "json-bigint": "^0.3.0", 16 | "nprogress": "^0.2.0", 17 | "vue": "^2.6.10", 18 | "vue-quill-editor": "^3.0.6", 19 | "vue-router": "^3.1.3" 20 | }, 21 | "devDependencies": { 22 | "@babel/plugin-syntax-dynamic-import": "^7.7.4", 23 | "@vue/cli-plugin-babel": "^4.1.0", 24 | "@vue/cli-plugin-eslint": "^4.1.0", 25 | "@vue/cli-plugin-router": "^4.1.0", 26 | "@vue/cli-service": "^4.1.0", 27 | "@vue/eslint-config-standard": "^4.0.0", 28 | "babel-eslint": "^10.0.3", 29 | "eslint": "^5.16.0", 30 | "eslint-plugin-vue": "^5.0.0", 31 | "less": "^3.0.4", 32 | "less-loader": "^5.0.0", 33 | "lint-staged": "^9.4.3", 34 | "vue-template-compiler": "^2.6.10" 35 | }, 36 | "gitHooks": { 37 | "pre-commit": "lint-staged" 38 | }, 39 | "lint-staged": { 40 | "*.{js,vue}": [ 41 | "vue-cli-service lint", 42 | "git add" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/components/publish/cover-image.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | // 封装一个axios 2 | import axios from 'axios' 3 | import router from '../router' 4 | import { Message } from 'element-ui' 5 | import JSONBig from 'json-bigint' // 引入第三方的包 6 | axios.defaults.baseURL = 'http://ttapi.research.itcast.cn/mp/v1_0' // 设置一个常态值 7 | 8 | // 请求拦截器 9 | axios.interceptors.request.use(function (config) { 10 | // 执行请求ok 11 | // config 请求参数配置 12 | let token = window.localStorage.getItem('user-token')// 取token 13 | config.headers.Authorization = `Bearer ${token}` // 统一注入token 14 | return config // 表示会用该config请求进行后台操作 15 | }, function () { 16 | // 执行请求错误 17 | 18 | }) 19 | 20 | axios.defaults.transformResponse = [function (data) { 21 | return data ? JSONBig.parse(data) : {} // 解决js处理大数字失真问题 22 | }] 23 | 24 | // 响应拦截器 25 | axios.interceptors.response.use(function (response) { 26 | // 成功时执行该函数 状态码 200 /201 /204 27 | 28 | return response.data ? response.data : {} 29 | }, function (error) { 30 | // 失败时执行该函数 31 | let status = error.response.status 32 | let message = '' 33 | switch (status) { 34 | case 400: 35 | message = '请求参数错误' 36 | break 37 | case 507: 38 | message = '服务器数据库异常' 39 | break 40 | case 401: 41 | // token过期或者失效 42 | // this.$router 43 | window.localStorage.removeItem('user-token') // 删除过期的token 44 | router.push('/login') // 跳转到登录页 45 | break 46 | case 403: 47 | message = '没有设置这条评论的权限' 48 | break 49 | default: 50 | break 51 | } 52 | Message({ type: 'warning', message }) // 提示信息 53 | // 这里需要注意 错误执行函数 如果不做任何操作 还会进入到promise then中 54 | return Promise.reject(error) // 只要reject =>catch 55 | }) 56 | export default axios 57 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Home from '../views/home' 4 | import Login from '../views/login' 5 | import Home2 from '../views/home/home.vue' 6 | Vue.use(VueRouter) 7 | 8 | const routes = [ 9 | { 10 | path: '/', 11 | redirect: '/home' // 强制跳转 12 | }, 13 | { 14 | path: '*', 15 | component: () => import('../views/404') 16 | }, 17 | { 18 | path: '/home', 19 | name: 'home', 20 | component: Home, 21 | children: [{ 22 | path: '', // 二级路由地址什么都不写 代表二级路由默认的组件 23 | component: Home2 24 | }, { 25 | path: 'comment', // 完整 相对 26 | component: () => import('../views/comment') 27 | }, { 28 | path: 'material', 29 | component: () => import('../views/material') 30 | }, { 31 | path: 'articles', // 文章列表 32 | component: () => import('../views/articles') 33 | }, { 34 | path: 'publish/:articleId?', // 修改文章 35 | component: () => import('../views/publish') 36 | }, { 37 | path: 'account', 38 | component: () => import('../views/account') 39 | }, { 40 | path: 'picture', 41 | component: () => import('../views/picture') 42 | }] 43 | }, { 44 | path: '/login', 45 | component: Login 46 | } 47 | // { 48 | // path: '/about', 49 | // name: 'about', 50 | // // route level code-splitting 51 | // // this generates a separate chunk (about.[hash].js) for this route 52 | // // which is lazy-loaded when the route is visited. 53 | // component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') 54 | // } 55 | ] 56 | 57 | const router = new VueRouter({ 58 | routes 59 | }) 60 | 61 | export default router 62 | -------------------------------------------------------------------------------- /src/components/home/layout-aside.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 58 | 59 | 75 | -------------------------------------------------------------------------------- /src/components/common/star-rain.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 100 | 101 | 104 | -------------------------------------------------------------------------------- /src/components/home/layout-header.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 75 | 76 | 97 | -------------------------------------------------------------------------------- /src/components/publish/select-image.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 84 | 85 | 111 | -------------------------------------------------------------------------------- /src/views/picture/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 109 | 110 | 116 | -------------------------------------------------------------------------------- /src/views/comment/index.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 101 | 102 | 104 | -------------------------------------------------------------------------------- /src/components/star.js: -------------------------------------------------------------------------------- 1 | class star { 2 | pointX = 0 // x坐标 3 | pointY = 10 // y坐标 4 | length = 0 // 长度 5 | canvas = null 6 | direction = '' // 方向 left / right 7 | flying = false // 飞行状态 8 | maxWidth = 0 9 | maxHeight = 0 10 | constructor ({ maxWidth, maxHeight, canvas, direction, callBack, index, speed }) { 11 | // props传入起始坐标点 长度 canvasContext对象 12 | this.maxWidth = maxWidth 13 | this.maxHeight = maxHeight 14 | this.canvas = canvas 15 | this.direction = direction 16 | this.callBack = callBack 17 | this.index = index 18 | this.speed = speed 19 | this.startFlay() // 初始化完毕后开始飞翔 20 | } 21 | /*** 22 | * 开始飞 23 | * ****/ 24 | startFlay () { 25 | if (!this.flying) { 26 | this.flying = true 27 | this.angel = 45 // 随机的角度 28 | this.length = Math.floor(Math.random() * 70) + 40 // 随机的长度 29 | this.pointX = Math.floor(Math.random() * this.maxWidth) + 1 30 | 31 | let { width, height } = this.getXYLength(this.length) 32 | this.width = width 33 | this.height = height 34 | // 随机的开始坐标点 35 | window.requestAnimationFrame(this.animateFrame.bind(this)) 36 | } 37 | } 38 | // 动画 39 | animateFrame () { 40 | // this.canvas.save() 41 | // 计算坐标 42 | // 向左时 流星坐标的x起始坐标 大于 终点坐标 43 | // 向右时 x坐标大于终点坐标 44 | // 根据勾股定理 推理 起始x y 坐标 (长度) => 终点x y坐标 45 | // 最终得到 x y 坐标的唯一解 做两侧坐标绝对值 46 | // this.direction === 'left' ? 47 | // this.clearPath() 48 | 49 | // this.canvas.save() 50 | let next = this.getXYLength(this.speed) 51 | let newPoint = this.getEndPoint(next.width, next.height) 52 | this.pointX = newPoint.endX 53 | this.pointY = newPoint.endY 54 | 55 | let endPoint = this.getEndPoint(this.width, this.height) 56 | this.canvas.beginPath() 57 | // 分段设置颜 58 | var line = this.canvas.createLinearGradient(this.pointX, this.pointY, 59 | endPoint.endX, 60 | endPoint.endY) 61 | // 分段设置颜色 62 | line.addColorStop(1, '#fff') 63 | line.addColorStop(0, '#090723') 64 | this.canvas.lineWidth = 1 65 | this.canvas.strokeStyle = line 66 | 67 | this.canvas.moveTo(this.pointX, this.pointY) 68 | this.canvas.lineTo(endPoint.endX, endPoint.endY) 69 | this.canvas.closePath() 70 | this.canvas.stroke() 71 | // this.canvas.restore() 72 | 73 | if (this.pointX > 0 && this.pointX < this.maxWidth && this.pointY < this.maxHeight && this.flying) { 74 | window.requestAnimationFrame(this.animateFrame.bind(this)) 75 | } else { 76 | this.stopFlay() 77 | // this.clearPath() 78 | 79 | this.callBack && this.callBack(this.index) 80 | } 81 | } 82 | step () { 83 | this.animateFrame() 84 | } 85 | clearPath () { 86 | this.canvas.clearRect(this.pointX - this.width - 3, this.pointY - 3, this.width + 5, this.height + 5) 87 | } 88 | // 计算结束的坐标点 89 | getEndPoint (width, height) { 90 | // 数学公式 91 | let endY = this.pointY + height 92 | let endX = this.pointX + (this.direction === 'left' ? -(width) : width) 93 | return { 94 | endX, endY 95 | } 96 | } 97 | getXYLength (length) { 98 | let width = length * Math.sin(this.angel / 180 * Math.PI) // 算出直角边上 也就是x竖直高度 99 | let height = length * Math.cos(this.angel / 180 * Math.PI) 100 | return { 101 | width, height 102 | } 103 | } 104 | /**** 105 | *停止飞 106 | * *****/ 107 | stopFlay () { 108 | this.flying = false // 停止飞行 109 | } 110 | } 111 | export default star 112 | -------------------------------------------------------------------------------- /src/views/account/index.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 109 | 110 | 122 | -------------------------------------------------------------------------------- /src/views/login/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 91 | 92 | 125 | -------------------------------------------------------------------------------- /src/views/material/index.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 151 | 152 | 180 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 一起来看流星雨 7 | 202 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /src/components/common/write-card.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 218 | 219 | 231 | -------------------------------------------------------------------------------- /src/views/publish/index.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 223 | 224 | 267 | -------------------------------------------------------------------------------- /src/views/articles/index.vue: -------------------------------------------------------------------------------- 1 | 86 | 87 | 229 | 230 | 296 | --------------------------------------------------------------------------------