├── static ├── .gitkeep ├── up.png ├── chat.png ├── edit.png ├── good1.png ├── good2.png ├── home.png ├── star1.png ├── star2.png ├── user-o.png └── notice-o.png ├── .vscode └── settings.json ├── src ├── const.js ├── style │ └── common.scss ├── App.vue ├── pages │ ├── list │ │ ├── main.js │ │ └── index.vue │ ├── me │ │ ├── main.js │ │ └── index.vue │ ├── notice │ │ ├── main.js │ │ └── index.vue │ ├── publish │ │ ├── main.js │ │ └── index.vue │ ├── user │ │ ├── main.js │ │ └── index.vue │ ├── detail │ │ ├── main.js │ │ └── index.vue │ └── index │ │ ├── main.js │ │ └── index.vue ├── components │ ├── authorHead.vue │ ├── sendReply.vue │ ├── login.vue │ └── card.vue ├── main.js └── utils │ └── index.js ├── img ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png └── show.jpg ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── .postcssrc.js ├── .editorconfig ├── .gitignore ├── index.html ├── .babelrc ├── project.config.json ├── README.md └── package.json /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.enabled": false 3 | } -------------------------------------------------------------------------------- /src/const.js: -------------------------------------------------------------------------------- 1 | export const api = 'https://cnodejs.org/api/v1' 2 | -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/5.png -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /img/show.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/img/show.jpg -------------------------------------------------------------------------------- /src/style/common.scss: -------------------------------------------------------------------------------- 1 | $color: rgb(65, 184, 131); // 主色调 2 | 3 | $borderColor: #888; -------------------------------------------------------------------------------- /static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/up.png -------------------------------------------------------------------------------- /static/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/chat.png -------------------------------------------------------------------------------- /static/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/edit.png -------------------------------------------------------------------------------- /static/good1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/good1.png -------------------------------------------------------------------------------- /static/good2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/good2.png -------------------------------------------------------------------------------- /static/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/home.png -------------------------------------------------------------------------------- /static/star1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/star1.png -------------------------------------------------------------------------------- /static/star2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/star2.png -------------------------------------------------------------------------------- /static/user-o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/user-o.png -------------------------------------------------------------------------------- /static/notice-o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flytam/mpvue-cnode/HEAD/static/notice-o.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/pages/list/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 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 | -------------------------------------------------------------------------------- /src/pages/me/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | export default { 7 | config: { 8 | navigationBarTitleText: '我' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/notice/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | export default { 7 | config: { 8 | navigationBarTitleText: '通知' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/publish/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | export default { 7 | config: { 8 | navigationBarTitleText: '发布主题' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/user/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | export default { 7 | config: { 8 | navigationBarTitleText: '个人主页' 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/detail/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 | navigationBarTitleText: '主题详情' 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /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 | export default { 7 | config: { 8 | window: { enablePullDownRefresh: true } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.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 | 15 | temp_wemark/ 16 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mpvue-cnode 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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": "wx4f6a5800a8abe179", 13 | "projectname": "mpvue-cnode", 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/components/authorHead.vue: -------------------------------------------------------------------------------- 1 | 9 | 22 | 23 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mpvue-cnode 2 | 3 | > 使用mp-vue开发的微信小程序版的cnode。本人第一个vue编写的项目,也是目前唯一一个,也可能是最后一个的vue项目 4 | 5 | 6 | API来自于[cnode社区](https://cnodejs.org/api) 7 | 8 | 线上demo 9 | 10 | ![](./img/show.jpg) 11 | 12 | ## 预览流程 13 | 14 | ``` bash 15 | npm install 16 | 17 | npm run dev 18 | 19 | //使用微信开发者工具打开,关闭域名和https检查即可 20 | ``` 21 | 22 | 23 | 24 | 目录结构 25 | - src 26 | - pages 27 | - index 主页 28 | - detail 帖子详情页 29 | - me 我的主页 30 | - publish 发帖页 31 | - notice 通知页 32 | - login 登录页 33 | - user 用户主页 34 | - list 帖子列表展示页 35 | - components 36 | - card 单一帖子头组件 37 | - authorHead 作者信息头 38 | - login 登录组件 39 | - sendreply 回复、评论组件 40 | - const.js 常量 41 | - utils 一些工具函数 42 | - static 静态图片部分 43 | 44 | 部分效果图 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | - License 53 | 54 | MIT 55 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import flyio from 'flyio/dist/npm/wx' 4 | Vue.prototype.$http = new flyio 5 | Vue.config.productionTip = false 6 | App.mpType = 'app' 7 | const app = new Vue(App) 8 | app.$mount() 9 | 10 | export default { 11 | // 这个字段走 app.json 12 | config: { 13 | // 页面前带有 ^ 符号的,会被编译成首页,其他页面可以选填,我们会自动把 webpack entry 里面的入口页面加进去 14 | pages: ['pages/detail/main', '^pages/index/main','pages/publish/main','pages/me/main','pages/notice/main','pages/user/main','pages/list/main'], 15 | window: { 16 | backgroundTextStyle: 'light', 17 | navigationBarBackgroundColor: '#fff', 18 | navigationBarTitleText: 'cNode', 19 | navigationBarTextStyle: 'black' 20 | }, 21 | tabBar: { 22 | selectedColor: '#41b883', 23 | list: [{ 24 | pagePath: 'pages/index/main', 25 | text: '首页', 26 | iconPath:'static/home.png', 27 | selectedIconPath:'static/home.png' 28 | }, { 29 | pagePath: 'pages/notice/main', 30 | text: '通知', 31 | iconPath:'static/notice-o.png', 32 | selectedIconPath:'static/notice-o.png' 33 | }, { 34 | pagePath: 'pages/publish/main', 35 | text: '发帖', 36 | iconPath:'static/edit.png', 37 | selectedIconPath:'static/edit.png' 38 | }, { 39 | pagePath: 'pages/me/main', 40 | text: '我', 41 | iconPath:'static/user-o.png', 42 | selectedIconPath:'static/user-o.png' 43 | }] 44 | }, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | import { POINT_CONVERSION_COMPRESSED } from "constants"; 2 | 3 | function formatNumber(n) { 4 | const str = n.toString() 5 | return str[1] ? str : `0${str}` 6 | } 7 | 8 | export function formatTime(date) { 9 | const year = date.getFullYear() 10 | const month = date.getMonth() + 1 11 | const day = date.getDate() 12 | 13 | const hour = date.getHours() 14 | const minute = date.getMinutes() 15 | const second = date.getSeconds() 16 | 17 | const t1 = [year, month, day].map(formatNumber).join('/') 18 | const t2 = [hour, minute, second].map(formatNumber).join(':') 19 | 20 | return `${t1} ${t2}` 21 | } 22 | // 计算离当前多久 23 | export function passTime(time) { 24 | const now = Date.now(), passDateTime = new Date(time).getTime(); 25 | const t = (now - passDateTime) / 1000 / 60;// 分钟 26 | let result; 27 | if (t / 60 / 24 /30 / 12 >1 ){ 28 | return result = `${Math.floor(t / 60 / 24 / 30 / 12)}年前`; 29 | }else if (t / 60 / 24 / 30 > 1) { 30 | return result = `${Math.floor(t / 60 / 24 / 30)}月前`; 31 | } else if (t / 60 / 24 >1) { 32 | return result = `${Math.floor(t / 60 / 24)}天前`; 33 | } else if (t / 60 > 1) { 34 | // 小时 35 | return result = `${Math.floor(t / 60)}小时前`; 36 | } else { 37 | // 分钟 38 | return result = `${Math.floor(t)}分钟前`; 39 | } 40 | } 41 | 42 | // 获取当前的路由 43 | export function getURL() { 44 | return getCurrentPages().slice(-1)[0].route 45 | } 46 | 47 | 48 | export function debounce(fn, interval = 300) { 49 | let timeout = null; 50 | return function () { 51 | clearTimeout(timeout); 52 | timeout = setTimeout(() => { 53 | fn.apply(this, arguments); 54 | }, interval); 55 | }; 56 | } -------------------------------------------------------------------------------- /src/pages/list/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 65 | 74 | -------------------------------------------------------------------------------- /src/components/sendReply.vue: -------------------------------------------------------------------------------- 1 | 9 | 54 | 83 | -------------------------------------------------------------------------------- /src/components/login.vue: -------------------------------------------------------------------------------- 1 | 12 | 58 | 86 | -------------------------------------------------------------------------------- /src/pages/user/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 60 | 61 | 82 | 83 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mpvue-cnode", 3 | "version": "1.0.0", 4 | "description": "cnode developed by mp-vue", 5 | "author": "tanjiahui <673800357@qq.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "rimraf dist && node build/build.js" 11 | }, 12 | "dependencies": { 13 | "flyio": "^0.5.5", 14 | "mpvue": "^1.0.9", 15 | "mpvue-wemark": "^1.1.2", 16 | "vuex": "^2.3.1" 17 | }, 18 | "devDependencies": { 19 | "babel-core": "^6.22.1", 20 | "babel-loader": "^7.1.1", 21 | "babel-plugin-transform-runtime": "^6.22.0", 22 | "babel-preset-env": "^1.3.2", 23 | "babel-preset-stage-2": "^6.22.0", 24 | "babel-register": "^6.22.0", 25 | "chalk": "^2.0.1", 26 | "connect-history-api-fallback": "^1.3.0", 27 | "copy-webpack-plugin": "^4.0.1", 28 | "css-loader": "^0.28.0", 29 | "cssnano": "^3.10.0", 30 | "eventsource-polyfill": "^0.9.6", 31 | "express": "^4.14.1", 32 | "extract-text-webpack-plugin": "^2.0.0", 33 | "file-loader": "^0.11.1", 34 | "friendly-errors-webpack-plugin": "^1.1.3", 35 | "glob": "^7.1.2", 36 | "html-webpack-plugin": "^2.28.0", 37 | "http-proxy-middleware": "^0.17.3", 38 | "mpvue-loader": "^1.0.12", 39 | "mpvue-template-compiler": "^1.0.9", 40 | "mpvue-webpack-target": "^1.0.0", 41 | "node-sass": "^4.9.0", 42 | "optimize-css-assets-webpack-plugin": "^2.0.0", 43 | "ora": "^1.2.0", 44 | "portfinder": "^1.0.13", 45 | "postcss-loader": "^2.0.6", 46 | "postcss-mpvue-wxss": "^1.0.0", 47 | "px2rpx-loader": "^0.1.8", 48 | "rimraf": "^2.6.0", 49 | "sass-loader": "^7.0.1", 50 | "sass-resources-loader": "^1.3.3", 51 | "semver": "^5.3.0", 52 | "shelljs": "^0.7.6", 53 | "uglifyjs-webpack-plugin": "^1.2.4", 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/pages/me/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 66 | 67 | 89 | -------------------------------------------------------------------------------- /src/components/card.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 60 | 61 | 111 | -------------------------------------------------------------------------------- /src/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 104 | 105 | 138 | 139 | -------------------------------------------------------------------------------- /src/pages/publish/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 95 | 96 | 144 | -------------------------------------------------------------------------------- /src/pages/notice/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 122 | 123 | 169 | 170 | -------------------------------------------------------------------------------- /src/pages/detail/index.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 238 | 239 | 350 | --------------------------------------------------------------------------------