├── static ├── .gitkeep ├── button │ ├── index.json │ ├── index.wxml │ ├── index.wxss │ └── index.js ├── iconfont.ttf ├── img │ └── user-bg.jpg ├── test.css └── font.css ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── src ├── pages │ ├── user │ │ ├── main.js │ │ └── user.vue │ ├── article │ │ ├── main.js │ │ ├── test.css │ │ └── article.vue │ └── index │ │ ├── main.js │ │ └── index.vue ├── components │ ├── card.vue │ ├── icons.js │ ├── icon.vue │ ├── type-block.vue │ ├── avatar.vue │ ├── simple-article.vue │ ├── slider-nav.vue │ └── content.vue ├── common │ ├── css │ │ └── base.scss │ └── js │ │ ├── basic.js │ │ └── filters.js ├── utils │ ├── index.js │ └── fly.js ├── App.vue └── main.js ├── .postcssrc.js ├── .editorconfig ├── .gitignore ├── .babelrc ├── index.html ├── project.config.json ├── README.md └── package.json /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/button/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true 3 | } 4 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /static/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaxQin/mpvue-cnode/HEAD/static/iconfont.ttf -------------------------------------------------------------------------------- /static/img/user-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaxQin/mpvue-cnode/HEAD/static/img/user-bg.jpg -------------------------------------------------------------------------------- /src/pages/user/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './user' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | -------------------------------------------------------------------------------- /src/pages/article/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './article' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-mpvue-wxss": {} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | -------------------------------------------------------------------------------- /static/test.css: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-29 18:03:15 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-29 18:03:47 6 | */ 7 | .test{ 8 | width: 100px; 9 | height: 100px; 10 | background: red; 11 | } -------------------------------------------------------------------------------- /src/pages/article/test.css: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-29 18:03:15 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-29 18:03:47 6 | */ 7 | .test{ 8 | width: 100px; 9 | height: 100px; 10 | background: red; 11 | } -------------------------------------------------------------------------------- /src/components/card.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /src/pages/index/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | export default { 8 | config: { 9 | "usingComponents": { 10 | "i-button": "../../../static/button/index" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/icons.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-29 22:19:21 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-29 22:20:13 6 | */ 7 | 8 | 'use strict'; 9 | import icon from './icon.vue'; 10 | export default (Vue) => { 11 | Vue.component("icon", icon); 12 | } 13 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/common/css/base.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-30 14:08:04 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-30 14:34:05 6 | */ 7 | 8 | $grey-border: #bcbab6; //常用于区块的border 9 | $slider-color: red; //首页中滑动导航滑块的颜色 10 | $light-color: #80bd01; //选中状态 高亮状态 11 | $page-bg: #f4f4f4; //用于一个页面的背景色 12 | 13 | 14 | $time: .2s; // 一般用于transition 的时间 15 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | my-mpvue 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | function formatNumber (n) { 2 | const str = n.toString() 3 | return str[1] ? str : `0${str}` 4 | } 5 | 6 | export function formatTime (date) { 7 | const year = date.getFullYear() 8 | const month = date.getMonth() + 1 9 | const day = date.getDate() 10 | 11 | const hour = date.getHours() 12 | const minute = date.getMinutes() 13 | const second = date.getSeconds() 14 | 15 | const t1 = [year, month, day].map(formatNumber).join('/') 16 | const t2 = [hour, minute, second].map(formatNumber).join(':') 17 | 18 | return `${t1} ${t2}` 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 27 | -------------------------------------------------------------------------------- /static/font.css: -------------------------------------------------------------------------------- 1 | /* This stylesheet generated by Transfonter (https://transfonter.org) on March 29, 2018 9:54 AM */ 2 | 3 | @font-face { 4 | font-family: 'iconfont'; 5 | src: url('iconfont.ttf') format('truetype'); 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-heart:before { 19 | content: "\e631"; 20 | } 21 | 22 | .icon-eye:before { 23 | content: "\e6f1"; 24 | } 25 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "setting": { 4 | "urlCheck": true, 5 | "es6": false, 6 | "postcss": true, 7 | "minified": true, 8 | "newFeature": true 9 | }, 10 | "miniprogramRoot": "./dist/", 11 | "compileType": "miniprogram", 12 | "appid": "wx5f83e7937032cbbb", 13 | "projectname": "my-mpvue", 14 | "condition": { 15 | "search": { 16 | "current": -1, 17 | "list": [] 18 | }, 19 | "conversation": { 20 | "current": -1, 21 | "list": [] 22 | }, 23 | "game": { 24 | "currentL": -1, 25 | "list": [] 26 | }, 27 | "miniprogram": { 28 | "current": -1, 29 | "list": [] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/common/js/basic.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-28 17:52:33 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-31 12:28:38 6 | */ 7 | 8 | 'use strict'; 9 | const navList = [ 10 | { title: '全部', type: 'all' }, 11 | { title: '精华', type: 'good' }, 12 | { title: '分享', type: 'share' }, 13 | { title: '问答', type: 'ask' }, 14 | { title: '招聘', type: 'job' }, 15 | { title: '测试', type: 'dev' }, 16 | ] 17 | const obj2style = style => { 18 | let str = [] 19 | Object.keys(style).forEach(key => { 20 | str.push(`${key}:${style[key]};`) 21 | }) 22 | return str.join(';'); 23 | } 24 | export { 25 | navList, 26 | obj2style 27 | } 28 | -------------------------------------------------------------------------------- /src/utils/fly.js: -------------------------------------------------------------------------------- 1 | import Fly from "flyio"; 2 | import wxEngine from 'flyio/../engine-wrapper' 3 | const fly = new Fly; 4 | 5 | //配置请求基地址 6 | fly.config.baseURL = "https://cnodejs.org/api/v1/" 7 | 8 | // //添加请求拦截器 9 | // fly.interceptors.request.use((config, promise) => { 10 | // //给所有请求添加自定义header 11 | // config.headers["X-Tag"] = "flyio"; 12 | // //可以通过promise.reject/resolve直接中止请求 13 | // //promise.resolve("fake data") 14 | // return config; 15 | // }) 16 | 17 | //添加响应拦截器,响应拦截器会在then/catch处理之前执行 18 | fly.interceptors.response.use( 19 | (response, promise) => { 20 | //只将请求结果的data字段返回 21 | return response.data 22 | }, 23 | (err, promise) => { 24 | //发生网络错误后会走到这里 25 | //promise.resolve("ssss") 26 | } 27 | ) 28 | export default fly 29 | -------------------------------------------------------------------------------- /static/button/index.wxml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | // 字体组件 4 | import icon from '@/components/icons.js' 5 | Vue.use(icon) 6 | 7 | // 导入过滤器 8 | import * as filters from '@/common/js/filters' 9 | 10 | Object.keys(filters).forEach(key => { 11 | Vue.use(filters[key]) 12 | }) 13 | Vue.use(filters) 14 | 15 | Vue.config.productionTip = false 16 | App.mpType = 'app' 17 | 18 | const app = new Vue(App) 19 | app.$mount() 20 | 21 | export default { 22 | // 这个字段走 app.json 23 | config: { 24 | // 页面前带有 ^ 符号的,会被编译成首页,其他页面可以选填,我们会自动把 webpack entry 里面的入口页面加进去 25 | pages: ['^pages/index/main', 'pages/article/main', 'pages/user/main'], 26 | window: { 27 | backgroundTextStyle: 'light', 28 | navigationBarBackgroundColor: '#fff', 29 | navigationBarTitleText: 'cnode社区', 30 | navigationBarTextStyle: 'black' 31 | }, 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/components/icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 33 | 36 | -------------------------------------------------------------------------------- /src/components/type-block.vue: -------------------------------------------------------------------------------- 1 | 12 | 23 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于mpVue开发的小程序版本的cnode社区 2 | 3 | ------ 4 | 5 | 基于mpVue开发的小程序版本的cnode社区,感谢美团开源的mpVue,基本上可以0学习成本快速开发一个小程序。 6 | 7 | 8 | **感谢以下插件**: 9 | 10 | > * [flyio](https://github.com/wendux/fly/blob/master/README-CH.md) - 同时支持浏览器、小程序、Node、Weex的基于Promise的跨平台http请求库。可以让您在多个端上尽可能大限度的实现代码复用 11 | > * [minapp-api-promise](https://github.com/bigmeow/minapp-api-promise) - 将所有异步微信小程序API promise化,支持then/catch、async/await的方式调用小程序API;支持请求队列,支持对原生API进行拦截。 12 | > * [mpvue-wxParse](https://github.com/F-loat/mpvue-wxParse) - 富文本组件 13 | 14 | 15 | **效果预览**: 16 | 17 | ![cmd-markdown-logo](http://ww3.sinaimg.cn/large/0060lm7Tly1fpy6k5k5tkg30b60ip1kx.gif) 18 | ![cmd-markdown-logo](http://ww1.sinaimg.cn/large/0060lm7Tly1fpy6rdhr8mg30b60iuhdt.gif) 19 | 20 | **待办事宜**: 21 | - [ ] 登录 22 | - [ ] 点赞 23 | - [ ] 收藏 24 | - [ ] 发布 25 | - [ ] 评论 26 | 27 | **下载启动步骤**: 28 | 29 | 1. git clone https://github.com/jaxQin/mpvue-cnode.git; 30 | 2. 如下 31 | ``` bash 32 | # install dependencies 33 | npm install 34 | 35 | # serve with hot reload at localhost:8080 36 | npm run dev 37 | 38 | # build for production with minification 39 | npm run build 40 | 41 | # build for production and view the bundle analyzer report 42 | npm run build --report 43 | ``` 44 | 3.小程序开发工具指向下面的dist目录 45 | 46 | *欢迎互相交流,希望您顺手点个star谢谢您* 47 | -------------------------------------------------------------------------------- /static/button/index.wxss: -------------------------------------------------------------------------------- 1 | .i-btn{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;white-space:nowrap;user-select:none;font-size:14px;border-radius:2px;border:0!important;position:relative;text-decoration:none;height:44px;line-height:44px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);color:#fff!important;background:#f7f7f7!important;color:#495060!important;margin:10px}.i-btn-long{border-radius:0;margin:0;box-shadow:none}.i-btn-large{height:48px;line-height:48px}.i-btn-small{height:40px;line-height:40px}.i-btn-primary{color:#fff!important;background:#2d8cf0!important}.i-btn-ghost{color:#fff!important;background:#fff!important;color:#495060!important}.i-btn-success{color:#fff!important;background:#19be6b!important}.i-btn-warning{color:#fff!important;background:#f90!important}.i-btn-error{color:#fff!important;background:#ed3f14!important}.i-btn-info{color:#fff!important;background:#2db7f5!important}.i-btn-circle{border-radius:44px}.i-btn-large.i-btn-circle{border-radius:48px}.i-btn-small.i-btn-circle{border-radius:40px}.i-btn-loading{opacity:.6}.i-btn-loading-inner{display:inline-block;margin-right:12px;vertical-align:middle;width:14px;height:14px;background:0 0;border-radius:50%;border:2px solid #fff;border-color:#fff #fff #fff transparent;animation:btn-spin .6s linear;animation-iteration-count:infinite}.i-btn-disabled{color:#bbbec4!important;background:#f7f7f7!important}@keyframes btn-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} -------------------------------------------------------------------------------- /src/components/avatar.vue: -------------------------------------------------------------------------------- 1 | 8 | 41 | 56 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: '/', 11 | productionSourceMap: false, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8080, 27 | // 在小程序开发者工具中不需要自动打开浏览器 28 | autoOpenBrowser: false, 29 | assetsSubDirectory: 'static', 30 | assetsPublicPath: '/', 31 | proxyTable: {}, 32 | // CSS Sourcemaps off by default because relative paths are "buggy" 33 | // with this option, according to the CSS-Loader README 34 | // (https://github.com/webpack/css-loader#sourcemaps) 35 | // In our experience, they generally work as expected, 36 | // just be aware of this issue when enabling this option. 37 | cssSourceMap: false 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /static/button/index.js: -------------------------------------------------------------------------------- 1 | Component({ 2 | externalClasses: ['i-class'], 3 | 4 | properties: { 5 | // default, primary, ghost, info, success, warning, error 6 | type: { 7 | type: String, 8 | value: '', 9 | }, 10 | // default, large, small 11 | size: { 12 | type: String, 13 | value: '', 14 | }, 15 | // circle, square 16 | shape: { 17 | type: String, 18 | value: 'square' 19 | }, 20 | disabled: { 21 | type: Boolean, 22 | value: false, 23 | }, 24 | loading: { 25 | type: Boolean, 26 | value: false, 27 | }, 28 | long: { 29 | type: Boolean, 30 | value: false 31 | }, 32 | openType: String, 33 | appParameter: String, 34 | hoverStopPropagation: Boolean, 35 | hoverStartTime: { 36 | type: Number, 37 | value: 20 38 | }, 39 | hoverStayTime: { 40 | type: Number, 41 | value: 70 42 | }, 43 | lang: { 44 | type: String, 45 | value: 'en' 46 | }, 47 | sessionFrom: { 48 | type: String, 49 | value: '' 50 | }, 51 | sendMessageTitle: String, 52 | sendMessagePath: String, 53 | sendMessageImg: String, 54 | showMessageCard: Boolean 55 | }, 56 | 57 | methods: { 58 | handleTap () { 59 | if (this.data.disabled) return false; 60 | 61 | this.triggerEvent('click'); 62 | } 63 | } 64 | }); 65 | -------------------------------------------------------------------------------- /src/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 58 | 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-mpvue", 3 | "version": "1.0.0", 4 | "description": "A Mpvue project", 5 | "author": "jaxQin <841571741@qq.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "flyio": "^0.4.3", 14 | "lodash": "^4.17.5", 15 | "minapp-api-promise": "^1.0.1", 16 | "mpvue": "^1.0.6", 17 | "mpvue-wxparse": "^0.4.5", 18 | "sass-resources-loader": "^1.3.3", 19 | "vuex": "^2.3.1" 20 | }, 21 | "devDependencies": { 22 | "babel-core": "^6.22.1", 23 | "babel-loader": "^7.1.1", 24 | "babel-plugin-transform-runtime": "^6.22.0", 25 | "babel-preset-env": "^1.3.2", 26 | "babel-preset-stage-2": "^6.22.0", 27 | "babel-register": "^6.22.0", 28 | "chalk": "^2.0.1", 29 | "connect-history-api-fallback": "^1.3.0", 30 | "copy-webpack-plugin": "^4.0.1", 31 | "css-loader": "^0.28.0", 32 | "cssnano": "^3.10.0", 33 | "eventsource-polyfill": "^0.9.6", 34 | "express": "^4.14.1", 35 | "extract-text-webpack-plugin": "^2.0.0", 36 | "file-loader": "^0.11.1", 37 | "friendly-errors-webpack-plugin": "^1.1.3", 38 | "glob": "^7.1.2", 39 | "html-webpack-plugin": "^2.28.0", 40 | "http-proxy-middleware": "^0.17.3", 41 | "mpvue-loader": "^1.0.8", 42 | "mpvue-template-compiler": "^1.0.6", 43 | "mpvue-webpack-target": "^1.0.0", 44 | "node-sass": "^4.8.3", 45 | "optimize-css-assets-webpack-plugin": "^2.0.0", 46 | "ora": "^1.2.0", 47 | "postcss-loader": "^2.0.6", 48 | "postcss-mpvue-wxss": "^1.0.0", 49 | "px2rpx-loader": "^0.1.8", 50 | "rimraf": "^2.6.0", 51 | "sass-loader": "^6.0.7", 52 | "semver": "^5.3.0", 53 | "shelljs": "^0.7.6", 54 | "url-loader": "^0.5.8", 55 | "vue-style-loader": "^3.0.1", 56 | "webpack": "^2.6.1", 57 | "webpack-bundle-analyzer": "^2.2.1", 58 | "webpack-dev-middleware-hard-disk": "^1.10.0", 59 | "webpack-merge": "^4.1.0", 60 | "webpack-mpvue-asset-plugin": "^0.0.1" 61 | }, 62 | "engines": { 63 | "node": ">= 4.0.0", 64 | "npm": ">= 3.0.0" 65 | }, 66 | "browserslist": [ 67 | "> 1%", 68 | "last 2 versions", 69 | "not ie <= 8" 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /src/components/simple-article.vue: -------------------------------------------------------------------------------- 1 | 20 | 37 | 83 | -------------------------------------------------------------------------------- /src/common/js/filters.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: jaxQin 3 | * @Date: 2018-03-29 11:03:43 4 | * @Last Modified by: jaxQin 5 | * @Last Modified time: 2018-03-29 15:20:55 6 | */ 7 | 8 | 'use strict'; 9 | import { navList } from '@/common/js/basic'; 10 | import Vue from 'vue' 11 | import _ from 'lodash'; 12 | const listMap = _.keyBy(navList, 'type') 13 | 14 | // 格式化时间 15 | Date.prototype.format = function(format) { 16 | var o = { 17 | "M+": this.getMonth() + 1, //month 18 | "d+": this.getDate(), //day 19 | "h+": this.getHours(), //hour 20 | "m+": this.getMinutes(), //minute 21 | "s+": this.getSeconds(), //second 22 | "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 23 | "S": this.getMilliseconds() //millisecond 24 | } 25 | if (/(y+)/.test(format)) format = format.replace(RegExp.$1, 26 | (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 27 | for (var k in o) 28 | if (new RegExp("(" + k + ")").test(format)) 29 | format = format.replace(RegExp.$1, 30 | RegExp.$1.length == 1 ? o[k] : 31 | ("00" + o[k]).substr(("" + o[k]).length)); 32 | return format; 33 | } 34 | const getTimeInfo = (str) => { 35 | if (!str) { 36 | return '' 37 | } 38 | const date = new Date(str); 39 | const time = new Date().getTime() - date.getTime(); //现在的时间-传入的时间 = 相差的时间(单位 = 毫秒) 40 | if (time < 0) { 41 | return ''; 42 | } else if (time / 1000 < 60) { 43 | return '刚刚'; 44 | } else if ((time / 60000) < 60) { 45 | return parseInt((time / 60000)) + '分钟前'; 46 | } else if ((time / 3600000) < 24) { 47 | return parseInt(time / 3600000) + '小时前'; 48 | } else if ((time / 86400000) < 31) { 49 | return parseInt(time / 86400000) + '天前'; 50 | } else if ((time / 2592000000) < 12) { 51 | return parseInt(time / 2592000000) + '月前'; 52 | } else { 53 | return parseInt(time / 31536000000) + '年前'; 54 | } 55 | } 56 | const filters = { 57 | install(Vue, val) { 58 | Vue.prototype.getTopicType = function(val='share') { //全局函数1 59 | return listMap[val].title 60 | }; 61 | } 62 | } 63 | const formatTime = { 64 | install(Vue, val) { 65 | Vue.prototype.formatTime = function(val) { //全局函数1 66 | val = new Date(val) 67 | return val.format('yyyy-MM-dd hh:mm:ss') 68 | }; 69 | } 70 | } 71 | const fromNow = { 72 | install(Vue, val) { 73 | Vue.prototype.fromNow = function(val) { //全局函数1 74 | return getTimeInfo(val) 75 | }; 76 | } 77 | } 78 | 79 | export { filters, formatTime, fromNow } 80 | -------------------------------------------------------------------------------- /src/components/slider-nav.vue: -------------------------------------------------------------------------------- 1 | 7 | 90 | 116 | -------------------------------------------------------------------------------- /src/components/content.vue: -------------------------------------------------------------------------------- 1 | 34 | 102 | 156 | -------------------------------------------------------------------------------- /src/pages/article/article.vue: -------------------------------------------------------------------------------- 1 | 55 | 102 | 189 | -------------------------------------------------------------------------------- /src/pages/user/user.vue: -------------------------------------------------------------------------------- 1 | 31 | 173 | 227 | --------------------------------------------------------------------------------