first commit

This commit is contained in:
2025-10-16 00:03:05 +08:00
commit fc46a5093e
39 changed files with 9253 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
{
"presets": [
["es2015", { "modules": false }],
"stage-3"
],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"plugins": [ "istanbul" ]
}
}
}
+9
View File
@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
+4
View File
@@ -0,0 +1,4 @@
.DS_Store
node_modules/
npm-debug.log
.idea/
+34
View File
@@ -0,0 +1,34 @@
本项目源于:https://github.com/jirengu-inc/animating-resume。向作者表示深深的敬意。
## 使用方法
1. 安装Node.js环境:https://nodejs.org/
2. 安装git: https://git-scm.com/
3. 执行以下命令:
``` bash
git clone https://github.com/sitexa/anires.git
cd anires
npm install
npm run dev
```
## 部署方法
1. 编辑 config/index.js,修改第 10 行的 assetsPublicPath,值为 `项目名/public`。如果你没有修改项目名 anires,则可跳过此步骤。
2. 编译、上传
```
bash
npm run build
git add .
git commit -m "update"
git push
```
3. 开启 GitHub Pages 功能, 或者,把生成的目标文件```public/*```放在你的web服务器上。
4,访问地址:https://your-github-username.github.io/anires/public
+1
View File
@@ -0,0 +1 @@
theme: jekyll-theme-cayman
+40
View File
@@ -0,0 +1,40 @@
// https://github.com/shelljs/shelljs
require('./check-versions')()
process.env.NODE_ENV = 'production'
var ora = require('ora')
var path = require('path')
var chalk = require('chalk')
var shell = require('shelljs')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')
var spinner = ora('building for production...')
spinner.start()
var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
shell.rm('-rf', assetsPath)
shell.mkdir('-p', assetsPath)
shell.config.silent = true
shell.cp('-R', 'static/*', assetsPath)
shell.config.silent = false
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
+45
View File
@@ -0,0 +1,45 @@
var chalk = require('chalk')
var semver = require('semver')
var packageConfig = require('../package.json')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
var versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
{
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
}
]
module.exports = function () {
var warnings = []
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
+9
View File
@@ -0,0 +1,9 @@
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
+81
View File
@@ -0,0 +1,81 @@
require('./check-versions')()
var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
var app = express()
var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
devMiddleware.waitUntilValid(function () {
console.log('> Listening at ' + uri + '\n')
})
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err)
return
}
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
})
+64
View File
@@ -0,0 +1,64 @@
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
// generate loader string to be used with extract text plugin
function generateLoaders (loaders) {
var sourceLoader = loaders.map(function (loader) {
var extraParamChar
if (/\?/.test(loader)) {
loader = loader.replace(/\?/, '-loader?')
extraParamChar = '&'
} else {
loader = loader + '-loader'
extraParamChar = '?'
}
return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
}).join('!')
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: sourceLoader,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader', sourceLoader].join('!')
}
}
// http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
return {
css: generateLoaders(['css']),
postcss: generateLoaders(['css']),
less: generateLoaders(['css', 'less']),
sass: generateLoaders(['css', 'sass?indentedSyntax']),
scss: generateLoaders(['css', 'sass']),
stylus: generateLoaders(['css', 'stylus']),
styl: generateLoaders(['css', 'stylus'])
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
loader: loader
})
}
return output
}
+17
View File
@@ -0,0 +1,17 @@
var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'
module.exports = {
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
}),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
}
+63
View File
@@ -0,0 +1,63 @@
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
modules: [
resolve('src'),
resolve('node_modules')
],
alias: {
'src': resolve('src'),
'assets': resolve('src/assets'),
'components': resolve('src/components')
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
+35
View File
@@ -0,0 +1,35 @@
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// cheap-module-eval-source-map is faster for development
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new FriendlyErrorsPlugin()
]
})
+102
View File
@@ -0,0 +1,102 @@
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var env = config.build.env
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
})
if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
+6
View File
@@ -0,0 +1,6 @@
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
+38
View File
@@ -0,0 +1,38 @@
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')
module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../public/index.html'),
assetsRoot: path.resolve(__dirname, '../public'),
assetsSubDirectory: 'static',
assetsPublicPath: '/anires/public/',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
NODE_ENV: '"production"'
}
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="refresh" content="0; url=https://www.sitexa.org/anires/public/" />
<title>跳转中</title>
</head>
<body>
跳转中...
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>个人简历</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
+7641
View File
File diff suppressed because it is too large Load Diff
+54
View File
@@ -0,0 +1,54 @@
{
"name": "animation-resume",
"version": "1.0.0",
"description": "animation resume",
"author": " <>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js"
},
"dependencies": {
"marked": "^0.3.9",
"prismjs": "^1.6.0",
"vue": "^2.1.10"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-stage-2": "^6.22.0",
"babel-preset-stage-3": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0",
"css-loader": "^0.26.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^2.0.0-rc.2",
"file-loader": "^0.10.0",
"friendly-errors-webpack-plugin": "^1.1.3",
"function-bind": "^1.1.0",
"html-webpack-plugin": "^2.28.0",
"http-proxy-middleware": "^0.17.3",
"opn": "^4.0.2",
"ora": "^1.1.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.7",
"vue-loader": "^10.3.0",
"vue-style-loader": "^2.0.0",
"vue-template-compiler": "^2.1.10",
"webpack": "^2.2.1",
"webpack-bundle-analyzer": "^2.2.1",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.16.1",
"webpack-merge": "^2.6.1"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
}
+1
View File
@@ -0,0 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><title>个人简历</title><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"><link href=/anires/public/static/css/app.97f24077373dbd5f86744ecd100255e7.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/anires/public/static/js/manifest.22a4ae013e2ceb48b7dd.js></script><script type=text/javascript src=/anires/public/static/js/vendor.045b08f12500b7884e7e.js></script><script type=text/javascript src=/anires/public/static/js/app.c4b2e14682ed119846b5.js></script></body></html>
@@ -0,0 +1,74 @@
#app[data-v-22ce9519] {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
html[data-v-22ce9519] {
min-height: 100vh;
}
*[data-v-22ce9519] {
box-sizing: border-box;
}
pre[data-v-35c047fd]{
}
@media (max-width:500px){
pre[data-v-35c047fd]{
}
}
.code[data-v-35c047fd] {
display: none;
}
@media (max-width:500px){
.resumeEditor[data-v-647e008b]{
}
}
.htmlMode[data-v-647e008b] {
animation: flip 2s;
}
@keyframes flip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@media (max-width:500px){
.thankEditor[data-v-29ad1df6]{
}
}
.htmlMode[data-v-29ad1df6] {
animation: flip 2s;
}
@keyframes flip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
*{margin: 0; padding: 0;}
*{box-sizing: border-box;}
*::before{box-sizing: border-box;}
*::after{box-sizing: border-box;}
#app[data-v-53c8d54c] {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh; position: relative;
}
html[data-v-53c8d54c] {
min-height: 100vh;
}
*[data-v-53c8d54c]{
box-sizing: border-box;
}
/*# sourceMappingURL=app.97f24077373dbd5f86744ecd100255e7.css.map*/
@@ -0,0 +1 @@
{"version":3,"sources":["webpack:///./src/App.vue","webpack:///./src/components/StyleEditor.vue","webpack:///./src/components/ResumeEditor.vue","webpack:///./src/components/ThankEditor.vue","webpack:///./src/assets/reset.css","webpack:///./src/Mobile.vue"],"names":[],"mappings":";AACA;EACE,oDAAoD;EACpD,oCAAoC;EACpC,mCAAmC;CACpC;AACD;EACE,kBAAkB;CACnB;AACD;EACE,uBAAuB;CACxB;;ACVD;CACC;AACD;AACA;CACC;CACA;AACD;EACE,cAAc;CACf;;ACRD;AACA;CACC;CACA;AACD;EACE,mBAAmB;CACpB;AACD;AACA;IACI,WAAW;CACd;AACD;IACI,WAAW;CACd;CACA;;ACdD;AACA;CACC;CACA;AACD;EACE,mBAAmB;CACpB;AACD;AACA;IACI,WAAW;CACd;AACD;IACI,WAAW;CACd;CACA;ACfD,EAAE,UAAU,CAAC,WAAW,CAAC;AACzB,EAAE,uBAAuB,CAAC;AAC1B,UAAU,uBAAuB,CAAC;AAClC,SAAS,uBAAuB,CAAC;;ACFjC;EACE,oDAAoD;EACpD,oCAAoC;EACpC,mCAAmC;EACnC,kBAAkB,CAAC,mBAAmB;CACvC;AACD;EACE,kBAAkB;CACnB;AACD;EACE,uBAAuB;CACxB","file":"static/css/app.97f24077373dbd5f86744ecd100255e7.css","sourcesContent":["\n#app[data-v-22ce9519] {\n font-family: 'Avenir', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\nhtml[data-v-22ce9519] {\n min-height: 100vh;\n}\n*[data-v-22ce9519] {\n box-sizing: border-box;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/App.vue","\npre[data-v-35c047fd]{\n}\n@media (max-width:500px){\npre[data-v-35c047fd]{\n}\n}\n.code[data-v-35c047fd] {\n display: none;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/StyleEditor.vue","\n@media (max-width:500px){\n.resumeEditor[data-v-647e008b]{\n}\n}\n.htmlMode[data-v-647e008b] {\n animation: flip 2s;\n}\n@keyframes flip {\nfrom {\n opacity: 0;\n}\nto {\n opacity: 1;\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/ResumeEditor.vue","\n@media (max-width:500px){\n.thankEditor[data-v-29ad1df6]{\n}\n}\n.htmlMode[data-v-29ad1df6] {\n animation: flip 2s;\n}\n@keyframes flip {\nfrom {\n opacity: 0;\n}\nto {\n opacity: 1;\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/ThankEditor.vue","*{margin: 0; padding: 0;}\n*{box-sizing: border-box;}\n*::before{box-sizing: border-box;}\n*::after{box-sizing: border-box;}\n\n\n\n// WEBPACK FOOTER //\n// ./src/assets/reset.css","\n#app[data-v-53c8d54c] {\n font-family: 'Avenir', Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n min-height: 100vh; position: relative;\n}\nhtml[data-v-53c8d54c] {\n min-height: 100vh;\n}\n*[data-v-53c8d54c]{\n box-sizing: border-box;\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/Mobile.vue"],"sourceRoot":""}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,i){for(var u,a,f,s=0,l=[];s<t.length;s++)a=t[s],o[a]&&l.push(o[a][0]),o[a]=0;for(u in c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(r&&r(t,c,i);l.length;)l.shift()();if(i)for(s=0;s<i.length;s++)f=n(n.s=i[s]);return f};var t={},o={2:0};n.e=function(e){function r(){u.onerror=u.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var i=document.getElementsByTagName("head")[0],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,n.nc&&u.setAttribute("nonce",n.nc),u.src=n.p+"static/js/"+e+"."+{0:"045b08f12500b7884e7e",1:"c4b2e14682ed119846b5"}[e]+".js";var a=setTimeout(r,12e4);return u.onerror=u.onload=r,i.appendChild(u),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="/anires/public/",n.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.22a4ae013e2ceb48b7dd.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+405
View File
@@ -0,0 +1,405 @@
<template>
<div id="app">
<div id="content">
<StyleEditor ref="styleEditor" :code="currentStyle"></StyleEditor>
<ResumeEditor ref="resumeEditor" :markdown="currentMarkdown" :enableHtml="enableHtml"></ResumeEditor>
</div>
<div id="foot">
<ThankEditor ref="thankEditor" :markdown="currentThankMarkdown" :enableHtml="enableHtml"></ThankEditor>
</div>
</div>
</template>
<script>
import StyleEditor from './components/StyleEditor'
import ResumeEditor from './components/ResumeEditor'
import ThankEditor from './components/ThankEditor'
import './assets/reset.css'
export default {
name: 'app',
components: {
StyleEditor,
ResumeEditor,
ThankEditor
},
data() {
return {
interval: 5,
currentStyle: '',
enableHtml: false,
fullStyle: [
`/*
* Inspired by http://strml.net/
* 源码地址 https://github.com/sitexa/anires
* 大家好,我是南方。
* 我来写一份简历!
*/
/* 给所有元素加上过渡效果 */
* {
transition: all .1s;
}
/* 设置背景颜色 */
html {
color: rgb(222,222,222); background: rgb(0,64,64);
}
#content{
height:70vh;
margin:0;
}
#foot{
height:29vh;
margin:0;
}
/* 设置边框 */
.styleEditor {
padding: .5em;
border: 1px solid;
margin: .5em;
overflow: auto;
width: 50vw; height: 70vh;
background: rgb(20,20,20);
}
/* 代码高亮 */
.token.selector{ color: rgb(130,150,0); }
.token.property{ color: rgb(190,140,0); }
.token.punctuation{ color: yellow; }
.token.function{ color: rgb(40,160,150); }
/* 加3D效果 */
html{
perspective: 1000px;
}
.styleEditor {
position: fixed; left: 0; top: 0;
-webkit-transition: none;
transition: none;
-webkit-transform: rotateY(10deg) translateZ(-100px) ;
transform: rotateY(10deg) translateZ(-100px) ;
}
/* 准备一个编辑器 */
.resumeEditor{
position: fixed; right: 0; top: 0;
padding: .5em; margin: .5em;
width: 50vw; height: 70vh;
border: 1px solid;
background: rgb(200,200,200); color: #222;
overflow: auto;
-webkit-transition: none;
transition: none;
-webkit-transform: rotateY(-10deg) translateZ(-100px) ;
transform: rotateY(-10deg) translateZ(-100px) ;
}
/* 开始写简历 */
`, `
/*将Markdown格式翻译成HTML
*再对HTML加点样式
*/
.resumeEditor{
padding: 2em;
}
.resumeEditor h2{
display: inline-block;
border-bottom: 1px solid;
margin: 1em 0 .5em;
}
.resumeEditor ul,.resumeEditor ol{
list-style: none;
}
.resumeEditor ul> li::before{
content: '•';
margin-right: .5em;
}
.resumeEditor ol {
counter-reset: section;
}
.resumeEditor ol li::before {
counter-increment: section;
content: counters(section, ".") " ";
margin-right: .5em;
}
.resumeEditor blockquote {
margin: 1em;
padding: .5em;
background: #ddd;
}
`, `/* 写封感谢信。
* 感谢大家对我的关注。
*/
.styleEditor{
width:50vw;height:70vh;
}
.resumeEditor{
width:50vw;height:70vh;
}
.thankEditor{
position: relative; left: 0; top: 0;
background: #E9D9BB;
color: #001C42;
overflow: auto;
}
.thankEditor {
width: 99vw; height: 45vh;
border: 1px solid #ccc;
font-size: .9em;
}
`,`
.thankEditor{
padding: .5em; margin: .5em; margin-top:1em;
}
.thankEditor ul,.thankEditor ol{
list-style: none;
}
.thankEditor ul> li::before{
content: '☞'; color: red;
margin-right: .5em;
}
.thankEditor ol {
counter-reset: section;
}
.thankEditor ol li::before {
counter-increment: section;
content: counters(section, "☞") " ";
margin-right: .5em;
}
.thankEditor{
width: 99vw; height: 45vh;
-webkit-transition: none;
transition: none;
-webkit-transform: rotateX(-10deg) translateZ(-200px);
transform: rotateX(-10deg) translateZ(-200px);
}
`],
currentMarkdown: '',
currentThankMarkdown: '',
fullMarkdown: `南方
====
坐标:湖南长沙。
资深软件工程师,资深产品经理,高级项目经理。现为自由职业。
技能
====
数据库设计
----
- 结构化数据库设计
- noSQL设计
后端开发
----
- 用户管理
- 单点登录
- 第三方登录
- 权限管理
- 交易系统
- 支付系统
- 社区系统
- 博客系统
- 公众号开发
- 小程序开发
- API接口开发
前端开发
----
- Web前端开发
- 移动终端(Native App, Hybrid App)
产品设计
----
- 智慧旅游项目
- 运动健康云平台
- 社区支持农业O2O项目
- 省级环境监控平台
- 高速公路异地处罚系统
- 环保局办公自动化系统
- 保险公司数据迁移项目
- 啤酒厂供应链项目
- 货运代理系统
- 集装箱管理系统
- 滞期费管理项目
技术及语言
----
- Java: SpringMVC, SpringCloud, Hibernate, iBatis, spark, sql2o, HikariCP, freemarker, okHttp, retrofit, RxJava
- Kotlin: ktor, exposed, anko
- Node.js: express, angular, ionic, react, cordova, meteor, electron, axios
- Swift: Vapor, ReactiveSwift
- Golang: hugo, beego, gorm, sqlx, matcha
- Python: tushare, pandas, numpy, matplotlib
- DotNet and PHP
- DB: SQLServer, Oracle, MySQL/MariaDB, MongoDB, graphQL, redis, memcached
- WebServer: apache, nginx, tomcat, netty, jetty
- OS: Ubuntu, CentOS, MacOS, Windows
- Others: Docker, git, Xmind,Axure
工作经历
----
1. 湖南融耀健康管理有限公司
2. 湖南三英特旅游智能技术有限公司
3. 合肥蓝盾科技有限公司
4. 上海易保网络有限公司
5. 厦门海环计算机软件有限公司
教育经历
----
1. 华东理工大学 环境工程学士
2. 厦门大学 系统工程硕士
文章
----
* [故土难离(我的父亲母亲)](https://www.meipian.cn/qacqfbz?uuid=d541c15eef694065bc9d1ac9a07925a2)
* [油腻腻的中年(小诗)](https://www.meipian.cn/wjaz3zh?uuid=ca1cd053b717451da781786de44e66e7)
* [生命(老四们的蝼蚁人生)](https://www.meipian.cn/vc4pr59?uuid=799c98f5a187405c94c86f7da7788869)
* [大健康商业模式](http://www.sitexa.org/technology/%E5%A4%A7%E5%81%A5%E5%BA%B7%E5%95%86%E4%B8%9A%E6%A8%A1%E5%BC%8F.html)
* [社区社交商业模型](http://www.sitexa.org/other/%E7%A4%BE%E5%8C%BA%E7%A4%BE%E4%BA%A4%E5%95%86%E4%B8%9A%E6%A8%A1%E5%9E%8B.html)
链接
----
* [GitHub](https://github.com/sitexa)
* [技术博客](http://www.sitexa.org)
* [南方时代](http://www.sitexa.net)
* [神秘湘鄂西](http://www.sitexa.cn)
* [我的简历故事(程序人生公众号文章)](https://mp.weixin.qq.com/s/5rsB956EPVm0FoFOe6xYTg)
勾引方式
----
* 微信:xnpeng
`, thanksMarkdown: `
鸣谢
----
* 这段时间,我有些诚煌诚恐。我的简历被很多人关注(49842),我码的那几篇文章也有很多人点击(20095),微信好友增加了2000多人。"程序人生"公众号文章(我的简历故事)阅读量超过十万+。
* 有很多企业向我发出了面试邀请,有很多创业团队向我伸出了橄榄枝,一些朋友给我提出非常好的建议,还有很多同学希望跟我进行技术交流,甚至有些企业问我能否承接外包业务。
* 于是,我受命下山,到了深圳、珠海、北京、天津等地,拜访了一些老板,结识了一些新朋友,见了一些同学和老同事,感触很多,收获很大。IT行业正在发生深刻的变化,新技术、新模式、新思维、新业态,层出不穷,各种探索,各种炒作,让人眼花缭乱。
* 我对自己也有了一个新的认识。我逐渐发现,我不是去找一份工作,而是在寻找一些机会,一些志同道合的伙伴,一份激动人心的事业。很荣幸,已经有几个朋友跟我达成了意向,准备组建团队。
* 到底做什么项目呢?我只能简单地说,社交+电商+区块链。肯定有人要说,这个题目太大了,是蹭热度。我不这样想。我以前对社交的思考中,一个重要的因素就是信任关系,而对电商的思考中,去中心化是一个核心考量。而区块链技术不正是解决信任机制和去中心化的利器么?
* 在此,我欢迎有兴趣的朋友加入我们,尽快推进项目的实施。(微信:xnpeng)
`
}
},
created() {
this.makeResume()
},
methods: {
makeResume: async function () {
await this.progressivelyShowStyle(0);
await this.progressivelyShowResume();
await this.progressivelyShowStyle(1);
await this.showHtml();
await this.progressivelyShowStyle(2);
await this.progressivelyShowThanks();
await this.progressivelyShowStyle(3)
},
showHtml() {
return new Promise((resolve, reject) => {
this.enableHtml = true
resolve()
})
},
progressivelyShowStyle(n) {
return new Promise((resolve, reject) => {
let interval = this.interval
let showStyle = (async function () {
let style = this.fullStyle[n]
if (!style) {
return
}
// 计算前 n 个 style 的字符总数
let length = this.fullStyle.filter((_, index) => index <= n).map((item) => item.length).reduce((p, c) => p + c, 0)
let prefixLength = length - style.length
if (this.currentStyle.length < length) {
let l = this.currentStyle.length - prefixLength
let char = style.substring(l, l + 1) || ' '
this.currentStyle += char
if (style.substring(l - 1, l) === '\n' && this.$refs.styleEditor) {
this.$nextTick(() => {
this.$refs.styleEditor.goBottom()
})
}
setTimeout(showStyle, interval)
} else {
resolve()
}
}).bind(this)
showStyle()
})
},
progressivelyShowResume() {
return new Promise((resolve, reject) => {
let length = this.fullMarkdown.length
let interval = this.interval
let showResume = () => {
if (this.currentMarkdown.length < length) {
this.currentMarkdown = this.fullMarkdown.substring(0, this.currentMarkdown.length + 1)
let lastChar = this.currentMarkdown[this.currentMarkdown.length - 1]
let prevChar = this.currentMarkdown[this.currentMarkdown.length - 2]
if (prevChar === '\n' && this.$refs.resumeEditor) {
this.$nextTick(() => this.$refs.resumeEditor.goBottom())
}
setTimeout(showResume, interval)
} else {
resolve()
}
}
showResume()
})
},
progressivelyShowThanks() {
return new Promise((resolve, reject) => {
let length = this.thanksMarkdown.length
let interval = this.interval
let showThanks = () => {
if (this.currentThankMarkdown.length < length) {
this.currentThankMarkdown = this.thanksMarkdown.substring(0, this.currentThankMarkdown.length + 1)
let lastChar = this.currentThankMarkdown[this.currentThankMarkdown.length - 1]
let prevChar = this.currentThankMarkdown[this.currentThankMarkdown.length - 2]
if (prevChar === '\n' && this.$refs.thankEditor) {
this.$nextTick(() => this.$refs.thankEditor.goBottom())
}
setTimeout(showThanks, interval)
} else {
resolve()
}
}
showThanks()
})
}
}
}
</script>
<style scoped>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
html {
min-height: 100vh;
}
* {
box-sizing: border-box;
}
</style>
+325
View File
@@ -0,0 +1,325 @@
<template>
<div id="app">
<StyleEditor ref="styleEditor" :code="currentStyle"></StyleEditor>
<ResumeEditor ref="resumeEditor" :markdown="currentMarkdown" :enableHtml="enableHtml"></ResumeEditor>
</div>
</template>
<script>
import StyleEditor from './components/StyleEditor'
import ResumeEditor from './components/ResumeEditor'
import './assets/reset.css'
export default {
name: 'app',
components: {
StyleEditor,
ResumeEditor
},
data() {
return {
interval: 5,
currentStyle: '',
enableHtml: false,
fullStyle: [
`/*
* Inspired by http://strml.net/
* 源码地址 https://github.com/sitexa/anires
* 大家好,我是南方。
* 我来写一份简历!
*/
/* 给所有元素加上过渡效果 */
* {
transition: all .2s;
}
/* 设置背景颜色 */
html {
color: rgb(222,222,222);
background: rgb(0,43,54);
}
/* 设置边框 */
.styleEditor {
padding: .5em;
border: 1px solid;
overflow: auto;
width: 90vw;
margin: 2.5vh 5vw;
height: 90vh;
}
/* 太高了 */
.styleEditor {
height: 45vh;
}
/* 代码高亮 */
.token.selector{
color: rgb(133,153,0);
}
.token.property{
color: rgb(187,137,0);
}
.token.punctuation{
color: yellow;
}
.token.function{
color: rgb(42,161,152);
}
/* 加3D效果 */
html{
perspective: 1000px;
}
.styleEditor {
position: fixed; left: 0; top: 0;
transform: rotateX(-10deg) translateZ(-50px) ;
}
/* 准备一个编辑器 */
.resumeEditor{
position: fixed;
top: 50%; left: 0;
padding: .5em; margin: 2.5vh;
width: 95vw; height: 45vh;
border: 1px solid;
background: white; color: #222;
overflow: auto;
}
/* 开始写简历 */
`,
`
/*将Markdown格式翻译成HTML
*再对HTML加点样式
*/
`, `
.resumeEditor{
padding: 2em;
}
.resumeEditor h2{
display: inline-block;
border-bottom: 1px solid;
margin: 1em 0 .5em;
}
.resumeEditor ul,.resumeEditor ol{
list-style: none;
}
.resumeEditor ul> li::before{
content: '•';
margin-right: .5em;
}
.resumeEditor ol {
counter-reset: section;
}
.resumeEditor ol li::before {
counter-increment: section;
content: counters(section, ".") " ";
margin-right: .5em;
}
.resumeEditor blockquote {
margin: 1em;
padding: .5em;
background: #ddd;
}
`],
currentMarkdown: '',
fullMarkdown: `南方
====
坐标:湖南长沙。
资深软件工程师,资深产品经理,高级项目经理。现为自由职业。
技能
====
数据库设计
----
- 结构化数据库设计
- noSQL设计
后端开发
----
- 用户管理
- 单点登录
- 第三方登录
- 权限管理
- 交易系统
- 支付系统
- 社区系统
- 博客系统
- 公众号开发
- 小程序开发
- API接口
前端开发
----
- Web前端开发
- 移动终端(Native App, Hybrid App)
产品设计
----
- 智慧旅游项目
- 运动健康云平台
- 社区支持农业O2O项目
- 省级环境监控平台
- 高速公路异地处罚系统
- 环保局办公自动化系统
- 保险公司数据迁移项目
- 啤酒厂供应链项目
- 货运代理系统
- 集装箱管理系统
- 滞期费管理项目
技术及语言
----
- Java: SpringMVC, SpringCloud, Hibernate, iBatis, spark, sql2o, HikariCP, freemarker, okHttp, retrofit, RxJava
- Kotlin: ktor, exposed, anko
- Node.js: express, angular, ionic, react, cordova, meteor, electron, axios
- Swift: Vapor, ReactiveSwift
- Golang: hugo, beego, gorm, sqlx, matcha
- Python: tushare, pandas, numpy, matplotlib
- DotNet and PHP
- DB: SQLServer, Oracle, MySQL/MariaDB, MongoDB, graphQL, redis, memcached
- WebServer: apache, nginx, tomcat, netty, jetty
- OS: Ubuntu, CentOS, MacOS, Windows
- Others: Docker, git, Xmind,Axure
工作经历
====
1. 湖南融耀健康管理有限公司
2. 湖南三英特旅游智能技术有限公司
3. 合肥蓝盾科技有限公司
4. 上海易保网络有限公司
5. 厦门海环计算机软件有限公司
教育经历
====
1. 华东理工大学 环境工程学士
2. 厦门大学 系统工程硕士
文章
====
* [故土难离(我的父亲母亲)](https://www.meipian.cn/qacqfbz?uuid=d541c15eef694065bc9d1ac9a07925a2)
* [油腻腻的中年(小诗)](https://www.meipian.cn/wjaz3zh?uuid=ca1cd053b717451da781786de44e66e7)
* [生命(老四们的蝼蚁人生)](https://www.meipian.cn/vc4pr59?uuid=799c98f5a187405c94c86f7da7788869)
* [大健康商业模式](http://www.sitexa.org/technology/%E5%A4%A7%E5%81%A5%E5%BA%B7%E5%95%86%E4%B8%9A%E6%A8%A1%E5%BC%8F.html)
* [社区社交商业模型](http://www.sitexa.org/other/%E7%A4%BE%E5%8C%BA%E7%A4%BE%E4%BA%A4%E5%95%86%E4%B8%9A%E6%A8%A1%E5%9E%8B.html)
链接
====
* [GitHub](https://github.com/sitexa)
* [技术博客](http://www.sitexa.org)
* [南方时代](http://www.sitexa.net)
* [神秘湘鄂西](http://www.sitexa.cn)
* [我的简历故事(程序人生公众号文章)](https://mp.weixin.qq.com/s/5rsB956EPVm0FoFOe6xYTg)
勾引方式
====
* 微信:xnpeng
鸣谢
----
* 这段时间,我有些诚煌诚恐。我的简历被很多人关注(49842),我码的那几篇文章也有很多人点击(20095),微信好友增加了2000多人。"程序人生"公众号文章(我的简历故事)阅读量超过十万+。
* 有很多企业向我发出了面试邀请,有很多创业团队向我伸出了橄榄枝,一些朋友给我提出非常好的建议,还有很多同学希望跟我进行技术交流,甚至有些企业问我能否承接外包业务。
* 于是,我受命下山,到了深圳、珠海、北京、天津等地,拜访了一些老板,结识了一些新朋友,见了一些同学和老同事,感触很多,收获很大。IT行业正在发生深刻的变化,新技术、新模式、新思维、新业态,层出不穷,各种探索,各种炒作,让人眼花缭乱。
* 我对自己也有了一个新的认识。我逐渐发现,我不是去找一份工作,而是在寻找一些机会,一些志同道合的伙伴,一份激动人心的事业。很荣幸,已经有几个朋友跟我达成了意向,准备组建团队。
* 到底做什么项目呢?我只能简单地说,社交+电商+区块链。肯定有人要说,这个题目太大了,是蹭热度。我不这样想。我以前对社交的思考中,一个重要的因素就是信任关系,而对电商的思考中,去中心化是一个核心考量。而区块链技术不正是解决信任机制和去中心化的利器么?
* 在此,我欢迎有兴趣的朋友加入我们,尽快推进项目的实施。
`
}
},
created() {
this.makeResume()
},
methods: {
makeResume: async function () {
await this.progressivelyShowStyle(0)
await this.progressivelyShowResume()
await this.progressivelyShowStyle(1)
await this.showHtml()
await this.progressivelyShowStyle(2)
},
showHtml: function () {
return new Promise((resolve, reject) => {
this.enableHtml = true
this.$nextTick(() => {
this.$refs.resumeEditor.goTop()
})
resolve()
})
},
progressivelyShowStyle(n) {
return new Promise((resolve, reject) => {
let interval = this.interval
let showStyle = (async function () {
let style = this.fullStyle[n]
if (!style) { return }
// 计算前 n 个 style 的字符总数
let length = this.fullStyle.filter((_, index) => index <= n).map((item) => item.length).reduce((p, c) => p + c, 0)
let prefixLength = length - style.length
if (this.currentStyle.length < length) {
let l = this.currentStyle.length - prefixLength
let char = style.substring(l, l + 1) || ' '
this.currentStyle += char
if (style.substring(l - 1, l) === '\n' && this.$refs.styleEditor) {
this.$nextTick(() => {
this.$refs.styleEditor.goBottom()
})
}
setTimeout(showStyle, interval)
} else {
resolve()
}
}).bind(this)
showStyle()
})
},
progressivelyShowResume() {
return new Promise((resolve, reject) => {
let length = this.fullMarkdown.length
let interval = this.interval
let showResume = () => {
if (this.currentMarkdown.length < length) {
this.currentMarkdown = this.fullMarkdown.substring(0, this.currentMarkdown.length + 1)
let lastChar = this.currentMarkdown[this.currentMarkdown.length - 1]
let prevChar = this.currentMarkdown[this.currentMarkdown.length - 2]
if (prevChar === '\n' && this.$refs.resumeEditor) {
this.$nextTick(() => this.$refs.resumeEditor.goBottom())
}
setTimeout(showResume, interval)
} else {
resolve()
}
}
showResume()
})
}
}
}
</script>
<style scoped>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh; position: relative;
}
html {
min-height: 100vh;
}
*{
box-sizing: border-box;
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

+4
View File
@@ -0,0 +1,4 @@
*{margin: 0; padding: 0;}
*{box-sizing: border-box;}
*::before{box-sizing: border-box;}
*::after{box-sizing: border-box;}
+48
View File
@@ -0,0 +1,48 @@
<template>
<div class="resumeEditor" :class="{htmlMode:enableHtml}" ref="container">
<div v-if="enableHtml" v-html="result"></div>
<pre v-else>{{result}}</pre>
</div>
</template>
<script>
import marked from 'marked'
export default {
props: ['markdown', 'enableHtml'],
name: 'ResumeEditor',
computed: {
result: function () {
return this.enableHtml ? marked(this.markdown) : this.markdown
}
},
methods: {
goBottom: function () {
this.$refs.container.scrollTop = 100000
},
goTop: function(){
this.$refs.container.scrollTop = 0
}
}
}
</script>
<style scoped>
@media (max-width:500px){
.resumeEditor{
}
}
.htmlMode {
animation: flip 2s;
}
@keyframes flip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
+40
View File
@@ -0,0 +1,40 @@
<template>
<div class="styleEditor" ref="container">
<div class="code" v-html="codeInStyleTag"></div>
<pre class="" v-html="highlightedCode"></pre>
</div>
</template>
<script>
import Prism from 'prismjs'
export default {
name: 'Editor',
props: ['code'],
computed: {
highlightedCode: function () {
return Prism.highlight(this.code, Prism.languages.css)
},
codeInStyleTag: function () {
return `<style>${this.code}</style>`
}
},
methods: {
goBottom() {
this.$refs.container.scrollTop = 100000
}
}
}
</script>
<style scoped>
pre{
}
@media (max-width:500px){
pre{
}
}
.code {
display: none;
}
</style>
+48
View File
@@ -0,0 +1,48 @@
<template>
<div class="thankEditor" :class="{htmlMode:enableHtml}" ref="container">
<div v-if="enableHtml" v-html="result"></div>
<pre v-else>{{result}}</pre>
</div>
</template>
<script>
import marked from 'marked'
export default {
props: ['markdown', 'enableHtml'],
name: 'ThankEditor',
computed: {
result: function () {
return this.enableHtml ? marked(this.markdown) : this.markdown
}
},
methods: {
goBottom: function () {
this.$refs.container.scrollTop = 100000
},
goTop: function(){
this.$refs.container.scrollTop = 0
}
}
}
</script>
<style scoped>
@media (max-width:500px){
.thankEditor{
}
}
.htmlMode {
animation: flip 2s;
}
@keyframes flip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
+10
View File
@@ -0,0 +1,10 @@
import Vue from 'vue'
import App from './App'
import Mobile from './Mobile'
var width = document.documentElement.clientWidth
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(width > 500 ? App : Mobile)
})
View File