├── .browserslistrc
├── public
├── favicon.ico
└── index.html
├── postcss.config.js
├── src
├── assets
│ └── logo.png
├── static
│ ├── video
│ │ └── icon_play.png
│ └── css
│ │ └── iconfont.css
├── store.js
├── router.js
├── main.js
├── App.vue
├── components
│ └── HelloWorld.vue
└── views
│ └── Home.vue
├── babel.config.js
├── .babelrc
├── .gitignore
├── .eslintrc.js
├── README.md
├── package.json
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superliebe/fangdouyin/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superliebe/fangdouyin/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/static/video/icon_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/superliebe/fangdouyin/HEAD/src/static/video/icon_play.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ],
5 | sourceType: 'unambiguous'
6 | }
7 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | "@babel/plugin-transform-runtime"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 |
4 | Vue.use(Vuex);
5 |
6 | export default new Vuex.Store({
7 | state: {},
8 | mutations: {},
9 | actions: {}
10 | });
11 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential"],
7 | rules: {
8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
10 | },
11 | parserOptions: {
12 | parser: "babel-eslint"
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Router from "vue-router";
3 | import Home from "./views/Home.vue";
4 |
5 | Vue.use(Router);
6 |
7 | export default new Router({
8 | routes: [
9 | {
10 | path: "/",
11 | name: "home",
12 | component: Home
13 | },{
14 | path: "/home",
15 | name: "home",
16 | component: Home
17 | },
18 | ]
19 | });
20 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 | import router from "./router";
4 | import store from "./store";
5 | // 引入组件样式
6 | import Vant from 'vant';
7 | import 'vant/lib/index.css';
8 | import './static/css/iconfont.css'
9 |
10 | import utils from 'km-vue-utils'
11 | Vue.use(utils);
12 | Vue.prototype.$utils = utils;
13 | Vue.use(Vant);
14 |
15 |
16 | Vue.config.productionTip = false;
17 |
18 | new Vue({
19 | router,
20 | store,
21 | render: h => h(App)
22 | }).$mount("#app");
23 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue仿抖音
2 |
3 | ## 2019年12月最新更新
4 | 新增留言功能,优化安卓微信环境境下播放不流畅问题
5 |
6 | ## 基本介绍
7 | 制作仿抖音视频列表遇到很多坑,特别是安卓微信内置浏览器,让人脑壳疼,核心代码不多 便于理解
8 |
9 | 图标css使用的事iconfot字体库,优化页面加载速度 http://at.alicdn.com/t/font_1048614_mi5i5ba1uag.css
10 |
11 | 组件用到了vant 中的swiper滑动组件
12 |
13 | ## video原生参数介绍
14 | ```
15 | h5 原生 video 属性
16 | webkit-playsinline ios 小窗播放,使视频不脱离文本流,安卓则无效
17 | 微信内置x5内核,
18 | x5-video-player-type="h5-page" 启用H5播放器,是wechat安卓版特性,添加此属性,微信浏览器会自动将视频置为全屏
19 | x5-video-player-fullscreen="true" 全屏设置,设置为 true 是防止横屏
20 | x5-video-orientation 控制横竖屏 landscape 横屏,portrain竖屏; 默认portrain
21 | poster:封面
22 | src:播放地址
23 | loop防止播放视频结束后,显示腾讯的广告
24 | ```
25 | ## 安装步奏
26 | ```
27 | cnpm install
28 | ```
29 |
30 | ### 安装后运行
31 | ```
32 | cnpm run serve
33 | ```
34 |
35 | ### Customize configuration
36 | See [Configuration Reference](https://cli.vuejs.org/config/).
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fangdouyin",
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 | "core-js": "^2.6.5",
12 | "km-vue-utils": "^0.0.1",
13 | "vant": "^2.2.15",
14 | "vue": "^2.6.10",
15 | "vue-router": "^3.0.3",
16 | "vuex": "^3.0.1",
17 | "weixin-js-sdk": "^1.6.0"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^3.1.1",
21 | "@vue/cli-plugin-eslint": "^3.1.1",
22 | "@vue/cli-service": "^3.1.1",
23 | "@vue/eslint-config-prettier": "^5.0.0",
24 | "babel-eslint": "^10.0.1",
25 | "eslint": "^5.16.0",
26 | "eslint-plugin-prettier": "^3.1.0",
27 | "eslint-plugin-vue": "^5.0.0",
28 | "node-sass": "^4.12.0",
29 | "prettier": "^1.18.2",
30 | "sass-loader": "^8.0.0",
31 | "vue-template-compiler": "^2.6.10"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | vue仿抖音
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation.
10 |
11 |
Installed CLI Plugins
12 |
30 |
Essential Links
31 |
54 |
Ecosystem
55 |
86 |
87 |
88 |
89 |
97 |
98 |
99 |
115 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const resolve = dir => {return path.join(__dirname, dir)}
3 | let target = 'http://localhost:8090/';
4 | // let target = 'https://blog.csdn.net/superKM';
5 | if (process.env.NODE_ENV === 'production') {
6 | target = '';
7 | }
8 | module.exports = {
9 | // 选项...
10 | publicPath: process.env.NODE_ENV === 'production' ? './' : '/',//部署服务器路径
11 | // 输出文件目录
12 | outputDir: "dist",
13 | assetsDir: "static",//放置生成的静态资源的目录
14 | indexPath: "index.html",//指定生成的 index.html 的输出路径
15 | filenameHashing: true,
16 | // pages: undefined,
17 | pages: {
18 | //pages 里配置的路径和文件名在你的文档目录必须存在 否则启动服务会报错
19 | index: {
20 | //除了 entry 之外都是可选的
21 | entry: 'src/main.js', // page 的入口,每个“page”应该有一个对应的 JavaScript 入口文件
22 | template: 'public/index.html', // 模板来源
23 | filename: 'index.html', // 在 dist/index.html 的输出
24 | title: 'Index Page', // 当使用 title 选项时,在 template 中使用:<%= htmlWebpackPlugin.options.title %>
25 | chunks: ['chunk-vendors', 'chunk-common', 'index'] // 在这个页面中包含的块,默认情况下会包含,提取出来的通用 chunk 和 vendor chunk
26 | }
27 | },
28 | // eslint-loader 是否在保存的时候检查
29 | lintOnSave: false,
30 | runtimeCompiler: true,
31 | transpileDependencies: ['webpack-dev-server/client'],
32 | //生产环境关闭map
33 | productionSourceMap: false,
34 | crossorigin: undefined,
35 | integrity: false,
36 | // webpack配置
37 | // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
38 | chainWebpack: config => {
39 | config.entry.app = ['babel-polyfill', './src/main.js'];
40 | // 修复HMR
41 | config.resolve.symlinks(true);
42 | config.resolve.alias //别名
43 | .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
44 | .set('_v', resolve('src/views'))
45 | .set('vendor', resolve('src/vendor'));
46 | },
47 | //统一配置打包插件
48 | configureWebpack: {
49 | plugins: []
50 | },
51 | // vue-loader 配置项
52 | // vueLoader: {},
53 | // 生产环境是否生成 sourceMap 文件
54 | css: {
55 | // 是否使用css分离插件 ExtractTextPlugin
56 | extract: true,
57 | // 开启 CSS source maps?
58 | sourceMap: false,
59 | // css预设器配置项
60 | loaderOptions: {},
61 | // 启用 CSS modules for all css / pre-processor files.
62 | modules: false
63 | },
64 | // use thread-loader for babel & TS in production build
65 | // enabled by default if the machine has more than 1 cores
66 | parallel: require('os').cpus().length > 1,
67 | pwa: {},
68 | devServer: {
69 | /**
70 | * 这一块是devServer的配置,可以参考https://webpack.js.org/configuration/dev-server/
71 | * (可选,根据自己情况来设置)
72 | */
73 | // 开发环境配置
74 | host: '0.0.0.0',
75 | port: 8080,
76 | https: false,
77 | hotOnly: false,
78 | open: false, //配置自动启动浏览器
79 | // 设置代理
80 | proxy: {
81 | // 如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。
82 | "/api": {
83 | //你要跨域的域名(包含host、端口号,切记:一定要带上http头);
84 | //同一个域名只能设置一次跨域,否则重复报错!
85 | target: target,
86 | ws: true,
87 | changOrigin: true, //是否跨域,设置为true;(必须)
88 | /**(可选设置----如果访问域名根目录,那这里必须设置重定向了)
89 | * 是否要把'/api'目录重定向去哪里,跟目录还是其他(可选)
90 | * 如果设置了,那在axios的路径中/article替换成https://baike.baidu.com/相当于根目录一样!
91 | * */
92 | },
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/src/static/css/iconfont.css:
--------------------------------------------------------------------------------
1 | @font-face {font-family: "iconfont";
2 | src: url('//at.alicdn.com/t/font_1048614_4nq25dmhzfk.eot?t=1575364271230'); /* IE9 */
3 | src: url('//at.alicdn.com/t/font_1048614_4nq25dmhzfk.eot?t=1575364271230#iefix') format('embedded-opentype'), /* IE6-IE8 */
4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
5 | url('//at.alicdn.com/t/font_1048614_4nq25dmhzfk.woff?t=1575364271230') format('woff'),
6 | url('//at.alicdn.com/t/font_1048614_4nq25dmhzfk.ttf?t=1575364271230') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url('//at.alicdn.com/t/font_1048614_4nq25dmhzfk.svg?t=1575364271230#iconfont') format('svg'); /* iOS 4.1- */
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-iconfontforward:before {
19 | content: "\e606";
20 | }
21 |
22 | .icon-fasong:before {
23 | content: "\e700";
24 | }
25 |
26 | .icon-lianjie:before {
27 | content: "\e67a";
28 | }
29 |
30 | .icon-gouwuche:before {
31 | content: "\e600";
32 | }
33 |
34 | .icon-pengyouquan:before {
35 | content: "\e601";
36 | }
37 |
38 | .icon-shoucang:before {
39 | content: "\e603";
40 | }
41 |
42 | .icon-zanwupinglun:before {
43 | content: "\e646";
44 | }
45 |
46 | .icon-weixin:before {
47 | content: "\e7b0";
48 | }
49 |
50 | .icon-gouwuche1:before {
51 | content: "\e63e";
52 | }
53 |
54 | .icon-liuyan:before {
55 | content: "\e639";
56 | }
57 |
58 | .icon-jiahao:before {
59 | content: "\e75e";
60 | }
61 |
62 | .icon-duihao:before {
63 | content: "\e722";
64 | }
65 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
23 |
24 |
![]()
25 |
26 |

28 |
29 |
30 |
52 |
53 |
54 |
55 | @{{item.author}}
56 |
57 |
58 | {{item.des}}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 首页
68 |
69 |
70 |

71 |
72 |
73 | 我的
74 |
75 |
76 |
77 |
78 |
分享到
79 |
80 | -
81 |
82 |
83 | -
84 |
85 |
86 | -
87 |
88 |
89 |
90 |
91 |
取消
92 |
93 |
94 |
161 |
162 |
163 |
172 |
173 |
174 |
175 |
591 |
1218 |
--------------------------------------------------------------------------------
101 |
102 |
103 | -
105 |
106 |
107 |
108 |
109 |
110 | @{{item.nickname}}
111 |
112 |
114 |
115 |
116 | {{item.love_count}}
117 |
118 |
119 |
120 | {{item.comment_content}}{{item.create_time}}
121 |
122 |
123 |
124 |
125 |
127 |
128 |
129 |
130 |
131 |
132 | @{{item2.nickname}}
133 |
135 |
137 |
138 |
139 | {{item2.love_count}}
140 |
141 |
142 |
143 | 回复 {{item2.be_commented_nickname}}:
144 | {{item2.comment_content}}
145 | {{item2.create_time}}
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
158 |
159 |