├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── example ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── README.md ├── build │ ├── build.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── index.html ├── package.json ├── src │ ├── app.vue │ ├── assets │ │ ├── icon_nav_article.png │ │ ├── icon_nav_button.png │ │ ├── icon_nav_cell.png │ │ ├── icon_nav_msg.png │ │ └── logo.png │ ├── main.js │ ├── route-config.js │ ├── style.css │ └── views │ │ ├── home.vue │ │ ├── page1.vue │ │ ├── page2.vue │ │ ├── page3.vue │ │ ├── page4.vue │ │ ├── page5.vue │ │ └── subroutes │ │ ├── sr1.vue │ │ ├── sr2.vue │ │ ├── sr3.vue │ │ └── sr4.vue └── static │ └── .gitkeep ├── index.js ├── lib └── index.js ├── package.json ├── umd └── vue-router-transition.min.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": [ 4 | "standard" 5 | ], 6 | "env": { 7 | "browser" : true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | .idea 31 | node_modules 32 | jspm_packages 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional REPL history 38 | .node_repl_history 39 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # nyc test coverage 20 | .nyc_output 21 | 22 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 23 | .grunt 24 | 25 | # node-waf configuration 26 | .lock-wscript 27 | 28 | # Compiled binary addons (http://nodejs.org/api/addons.html) 29 | build/Release 30 | 31 | # Dependency directories 32 | .idea 33 | example 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional REPL history 41 | .node_repl_history 42 | 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **【Deprecated】** ~~vue-router-transition~~ 2 | 3 | [![npm](https://img.shields.io/npm/v/vue-router-transition.svg?style=flat)](https://www.npmjs.com/package/vue-router-transition) 4 | [![npm](https://img.shields.io/npm/dt/vue-router-transition.svg?style=flat)](https://www.npmjs.com/package/vue-router-transition) 5 | 6 | A page transition plugin for vue-router [demo](http://vnot.me/vue-router-transition/) 7 | 8 | ## Usage 9 | 10 | ```js 11 | ... 12 | import VueRouter from 'vue-router' 13 | import VueRouterTransition from 'vue-router-transition' 14 | ... 15 | 16 | // install router 17 | Vue.use(VueRouter) 18 | Vue.use(VueRouterTransition, VueRouter) 19 | 20 | // in app.vue, apply directive `v-r-transition` 21 | 22 | 23 | // or 24 | 25 | 30 | 31 | 32 | Vue.transition('slideFromRightToLeft', {}) 33 | Vue.transition('slideFromLeftToRight', {}) 34 | ``` 35 | 36 | ## Your CSS 37 | ```css 38 | .view { 39 | transition: all .5s ease; 40 | } 41 | 42 | /* v-r-transition, default is {forward: 'forward', back: 'back'}*/ 43 | .forward-enter, .forward-leave { 44 | transform: translate3d(-100%, 0, 0); 45 | } 46 | .back-enter, .back-leave { 47 | transform: translate3d(100%, 0, 0); 48 | } 49 | ``` 50 | 51 | ## Page level transition 52 | For page level transition, define custom field `$$routerTransition` in the route config 53 | ```js 54 | '/message': { 55 | component: require('./views/subroutes/sr2.vue'), 56 | $$routerTransition: { 57 | forward: 'roll', 58 | back: 'roll' 59 | } 60 | } 61 | ``` 62 | -------------------------------------------------------------------------------- /example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /example/.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 | -------------------------------------------------------------------------------- /example/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 8 | extends: 'standard', 9 | // required to lint *.vue files 10 | plugins: [ 11 | 'html' 12 | ], 13 | // add your custom rules here 14 | 'rules': { 15 | // allow paren-less arrow functions 16 | 'arrow-parens': 0, 17 | // allow async-await 18 | 'generator-star-spacing': 0, 19 | // allow debugger during development 20 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | selenium-debug.log 6 | test/unit/coverage 7 | test/e2e/reports 8 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # vue-router-transition-example 2 | 3 | > vue router transition example 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # run unit tests 18 | npm run unit 19 | 20 | # run e2e tests 21 | npm run e2e 22 | 23 | # run all tests 24 | npm test 25 | ``` 26 | 27 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 28 | -------------------------------------------------------------------------------- /example/build/build.js: -------------------------------------------------------------------------------- 1 | // https://github.com/shelljs/shelljs 2 | require('shelljs/global') 3 | env.NODE_ENV = 'production' 4 | 5 | var path = require('path') 6 | var config = require('../config') 7 | var ora = require('ora') 8 | var webpack = require('webpack') 9 | var webpackConfig = require('./webpack.prod.conf') 10 | 11 | console.log( 12 | ' Tip:\n' + 13 | ' Built files are meant to be served over an HTTP server.\n' + 14 | ' Opening index.html over file:// won\'t work.\n' 15 | ) 16 | 17 | var spinner = ora('building for production...') 18 | spinner.start() 19 | 20 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) 21 | rm('-rf', assetsPath) 22 | mkdir('-p', assetsPath) 23 | cp('-R', 'static/', assetsPath) 24 | 25 | webpack(webpackConfig, function (err, stats) { 26 | spinner.stop() 27 | if (err) throw err 28 | process.stdout.write(stats.toString({ 29 | colors: true, 30 | modules: false, 31 | children: false, 32 | chunks: false, 33 | chunkModules: false 34 | }) + '\n') 35 | }) 36 | -------------------------------------------------------------------------------- /example/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /example/build/dev-server.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var express = require('express') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var proxyMiddleware = require('http-proxy-middleware') 6 | var webpackConfig = process.env.NODE_ENV === 'testing' 7 | ? require('./webpack.prod.conf') 8 | : require('./webpack.dev.conf') 9 | 10 | // default port where dev server listens for incoming traffic 11 | var port = process.env.PORT || config.dev.port 12 | // Define HTTP proxies to your custom API backend 13 | // https://github.com/chimurai/http-proxy-middleware 14 | var proxyTable = config.dev.proxyTable 15 | 16 | var app = express() 17 | var compiler = webpack(webpackConfig) 18 | 19 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 20 | publicPath: webpackConfig.output.publicPath, 21 | stats: { 22 | colors: true, 23 | chunks: false 24 | } 25 | }) 26 | 27 | var hotMiddleware = require('webpack-hot-middleware')(compiler) 28 | // force page reload when html-webpack-plugin template changes 29 | compiler.plugin('compilation', function (compilation) { 30 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 31 | hotMiddleware.publish({ action: 'reload' }) 32 | cb() 33 | }) 34 | }) 35 | 36 | // proxy api requests 37 | Object.keys(proxyTable).forEach(function (context) { 38 | var options = proxyTable[context] 39 | if (typeof options === 'string') { 40 | options = { target: options } 41 | } 42 | app.use(proxyMiddleware(context, options)) 43 | }) 44 | 45 | // handle fallback for HTML5 history API 46 | app.use(require('connect-history-api-fallback')()) 47 | 48 | // serve webpack bundle output 49 | app.use(devMiddleware) 50 | 51 | // enable hot-reload and state-preserving 52 | // compilation error display 53 | app.use(hotMiddleware) 54 | 55 | // serve pure static assets 56 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 57 | app.use(staticPath, express.static('./static')) 58 | 59 | module.exports = app.listen(port, function (err) { 60 | if (err) { 61 | console.log(err) 62 | return 63 | } 64 | console.log('Listening at http://localhost:' + port + '\n') 65 | }) 66 | -------------------------------------------------------------------------------- /example/build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | return path.posix.join(config.build.assetsSubDirectory, _path) 7 | } 8 | 9 | exports.cssLoaders = function (options) { 10 | options = options || {} 11 | // generate loader string to be used with extract text plugin 12 | function generateLoaders (loaders) { 13 | var sourceLoader = loaders.map(function (loader) { 14 | var extraParamChar 15 | if (/\?/.test(loader)) { 16 | loader = loader.replace(/\?/, '-loader?') 17 | extraParamChar = '&' 18 | } else { 19 | loader = loader + '-loader' 20 | extraParamChar = '?' 21 | } 22 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') 23 | }).join('!') 24 | 25 | if (options.extract) { 26 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) 27 | } else { 28 | return ['vue-style-loader', sourceLoader].join('!') 29 | } 30 | } 31 | 32 | // http://vuejs.github.io/vue-loader/configurations/extract-css.html 33 | return { 34 | css: generateLoaders(['css']), 35 | postcss: generateLoaders(['css']), 36 | less: generateLoaders(['css', 'less']), 37 | sass: generateLoaders(['css', 'sass?indentedSyntax']), 38 | scss: generateLoaders(['css', 'sass']), 39 | stylus: generateLoaders(['css', 'stylus']), 40 | styl: generateLoaders(['css', 'stylus']) 41 | } 42 | } 43 | 44 | // Generate loaders for standalone style files (outside of .vue) 45 | exports.styleLoaders = function (options) { 46 | var output = [] 47 | var loaders = exports.cssLoaders(options) 48 | for (var extension in loaders) { 49 | var loader = loaders[extension] 50 | output.push({ 51 | test: new RegExp('\\.' + extension + '$'), 52 | loader: loader 53 | }) 54 | } 55 | return output 56 | } 57 | -------------------------------------------------------------------------------- /example/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var projectRoot = path.resolve(__dirname, '../../') 5 | 6 | module.exports = { 7 | entry: { 8 | app: './src/main.js' 9 | }, 10 | output: { 11 | path: config.build.assetsRoot, 12 | publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, 13 | filename: '[name].js' 14 | }, 15 | resolve: { 16 | extensions: ['', '.js', '.vue'], 17 | fallback: [path.join(__dirname, '../node_modules')], 18 | alias: { 19 | 'src': path.resolve(__dirname, '../src'), 20 | 'assets': path.resolve(__dirname, '../src/assets'), 21 | 'components': path.resolve(__dirname, '../src/components'), 22 | 'vux-components': 'vux/src/components' 23 | } 24 | }, 25 | resolveLoader: { 26 | fallback: [path.join(__dirname, '../node_modules')] 27 | }, 28 | module: { 29 | preLoaders: [ 30 | { 31 | test: /\.vue$/, 32 | loader: 'eslint', 33 | include: projectRoot, 34 | exclude: /node_modules/ 35 | }, 36 | { 37 | test: /\.js$/, 38 | loader: 'eslint', 39 | include: projectRoot, 40 | exclude: /node_modules/ 41 | } 42 | ], 43 | loaders: [ 44 | { 45 | test: /vux.src.*?js$/, 46 | loader: 'babel' 47 | }, 48 | { 49 | test: /\.vue$/, 50 | loader: 'vue' 51 | }, 52 | { 53 | test: /\.js$/, 54 | loader: 'babel', 55 | include: projectRoot, 56 | exclude: /node_modules/ 57 | }, 58 | { 59 | test: /\.json$/, 60 | loader: 'json' 61 | }, 62 | { 63 | test: /\.html$/, 64 | loader: 'vue-html' 65 | }, 66 | { 67 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 68 | loader: 'url', 69 | query: { 70 | limit: 10000, 71 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 72 | } 73 | }, 74 | { 75 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 76 | loader: 'url', 77 | query: { 78 | limit: 10000, 79 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 80 | } 81 | } 82 | ] 83 | }, 84 | eslint: { 85 | formatter: require('eslint-friendly-formatter') 86 | }, 87 | vue: { 88 | loaders: utils.cssLoaders() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /example/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var config = require('../config') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var utils = require('./utils') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | 8 | // add hot-reload related code to entry chunks 9 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 10 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 11 | }) 12 | 13 | module.exports = merge(baseWebpackConfig, { 14 | module: { 15 | loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 16 | }, 17 | // eval-source-map is faster for development 18 | devtool: '#eval-source-map', 19 | plugins: [ 20 | new webpack.DefinePlugin({ 21 | 'process.env': config.dev.env 22 | }), 23 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 24 | new webpack.optimize.OccurenceOrderPlugin(), 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }) 33 | ] 34 | }) 35 | -------------------------------------------------------------------------------- /example/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var env = process.env.NODE_ENV === 'testing' 10 | ? require('../config/test.env') 11 | : config.build.env 12 | 13 | var webpackConfig = merge(baseWebpackConfig, { 14 | module: { 15 | loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) 16 | }, 17 | devtool: config.build.productionSourceMap ? '#source-map' : false, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 21 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 22 | }, 23 | vue: { 24 | loaders: utils.cssLoaders({ 25 | sourceMap: config.build.productionSourceMap, 26 | extract: true 27 | }) 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | } 38 | }), 39 | new webpack.optimize.OccurenceOrderPlugin(), 40 | // extract css into its own file 41 | new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')), 42 | // generate dist index.html with correct asset hash for caching. 43 | // you can customize output by editing /index.html 44 | // see https://github.com/ampedandwired/html-webpack-plugin 45 | new HtmlWebpackPlugin({ 46 | filename: process.env.NODE_ENV === 'testing' 47 | ? 'index.html' 48 | : config.build.index, 49 | template: 'index.html', 50 | inject: true, 51 | minify: { 52 | removeComments: true, 53 | collapseWhitespace: true, 54 | removeAttributeQuotes: true 55 | // more options: 56 | // https://github.com/kangax/html-minifier#options-quick-reference 57 | }, 58 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 59 | chunksSortMode: 'dependency' 60 | }), 61 | // split vendor js into its own file 62 | new webpack.optimize.CommonsChunkPlugin({ 63 | name: 'vendor', 64 | minChunks: function (module, count) { 65 | // any required modules inside node_modules are extracted to vendor 66 | return ( 67 | module.resource && 68 | /\.js$/.test(module.resource) && 69 | module.resource.indexOf( 70 | path.join(__dirname, '../node_modules') 71 | ) === 0 72 | ) 73 | } 74 | }), 75 | // extract webpack runtime and module manifest to its own file in order to 76 | // prevent vendor hash from being updated whenever app bundle is updated 77 | new webpack.optimize.CommonsChunkPlugin({ 78 | name: 'manifest', 79 | chunks: ['vendor'] 80 | }) 81 | ] 82 | }) 83 | 84 | if (config.build.productionGzip) { 85 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 86 | 87 | webpackConfig.plugins.push( 88 | new CompressionWebpackPlugin({ 89 | asset: '[path].gz[query]', 90 | algorithm: 'gzip', 91 | test: new RegExp( 92 | '\\.(' + 93 | config.build.productionGzipExtensions.join('|') + 94 | ')$' 95 | ), 96 | threshold: 10240, 97 | minRatio: 0.8 98 | }) 99 | ) 100 | } 101 | 102 | module.exports = webpackConfig 103 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/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: true, 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 | }, 19 | dev: { 20 | env: require('./dev.env'), 21 | port: 8080, 22 | assetsSubDirectory: 'static', 23 | assetsPublicPath: '/', 24 | proxyTable: {}, 25 | // CSS Sourcemaps off by default because relative paths are "buggy" 26 | // with this option, according to the CSS-Loader README 27 | // (https://github.com/webpack/css-loader#sourcemaps) 28 | // In our experience, they generally work as expected, 29 | // just be aware of this issue when enabling this option. 30 | cssSourceMap: false, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /example/config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue-router-transition-example 7 | 31 | 32 | 33 |
34 | 35 |
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-transition-example", 3 | "version": "1.0.0", 4 | "description": "vue router transition example", 5 | "author": "weinot ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "test": "", 11 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 12 | }, 13 | "dependencies": { 14 | "babel-runtime": "^6.0.0", 15 | "skyeye-vue-transition-animate": "^1.1.3", 16 | "vue": "^1.0.21", 17 | "vue-router": "^0.7.13", 18 | "vue-router-transition": "^1.0.0", 19 | "vue-transition-animate": "^1.1.0", 20 | "vux": "^0.1.2" 21 | }, 22 | "devDependencies": { 23 | "babel-core": "^6.0.0", 24 | "babel-eslint": "^6.1.2", 25 | "babel-loader": "^6.0.0", 26 | "babel-plugin-transform-runtime": "^6.0.0", 27 | "babel-preset-es2015": "^6.0.0", 28 | "babel-preset-stage-2": "^6.0.0", 29 | "connect-history-api-fallback": "^1.1.0", 30 | "css-loader": "^0.23.0", 31 | "eslint": "^2.10.2", 32 | "eslint-config-standard": "^5.1.0", 33 | "eslint-friendly-formatter": "^2.0.5", 34 | "eslint-loader": "^1.3.0", 35 | "eslint-plugin-html": "^1.3.0", 36 | "eslint-plugin-promise": "^1.0.8", 37 | "eslint-plugin-standard": "^1.3.2", 38 | "eventsource-polyfill": "^0.9.6", 39 | "express": "^4.13.3", 40 | "extract-text-webpack-plugin": "^1.0.1", 41 | "file-loader": "^0.8.4", 42 | "function-bind": "^1.0.2", 43 | "html-webpack-plugin": "^2.8.1", 44 | "http-proxy-middleware": "^0.12.0", 45 | "json-loader": "^0.5.4", 46 | "less": "^2.7.1", 47 | "less-loader": "^2.2.3", 48 | "ora": "^0.2.0", 49 | "shelljs": "^0.6.0", 50 | "url-loader": "^0.5.7", 51 | "vue-hot-reload-api": "^1.2.0", 52 | "vue-html-loader": "^1.0.0", 53 | "vue-loader": "^8.3.0", 54 | "vue-style-loader": "^1.0.0", 55 | "webpack": "^1.12.2", 56 | "webpack-dev-middleware": "^1.4.0", 57 | "webpack-hot-middleware": "^2.6.0", 58 | "webpack-merge": "^0.8.3" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/src/app.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 32 | -------------------------------------------------------------------------------- /example/src/assets/icon_nav_article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/src/assets/icon_nav_article.png -------------------------------------------------------------------------------- /example/src/assets/icon_nav_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/src/assets/icon_nav_button.png -------------------------------------------------------------------------------- /example/src/assets/icon_nav_cell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/src/assets/icon_nav_cell.png -------------------------------------------------------------------------------- /example/src/assets/icon_nav_msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/src/assets/icon_nav_msg.png -------------------------------------------------------------------------------- /example/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/src/assets/logo.png -------------------------------------------------------------------------------- /example/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import VueRouterTransition from '../../index' 4 | import VueTransitionAnimate from 'skyeye-vue-transition-animate' 5 | import { configRouter } from './route-config' 6 | 7 | // install router 8 | Vue.use(VueRouter) 9 | Vue.use(VueRouterTransition, VueRouter) 10 | Vue.use(VueTransitionAnimate) 11 | 12 | // create router 13 | const router = new VueRouter({ 14 | saveScrollPosition: true 15 | }) 16 | 17 | // configure router 18 | configRouter(router) 19 | 20 | // boostrap the app 21 | const App = Vue.extend(require('./app.vue')) 22 | router.start(App, 'app') 23 | -------------------------------------------------------------------------------- /example/src/route-config.js: -------------------------------------------------------------------------------- 1 | export function configRouter (router) { 2 | router.map({ 3 | '/': { 4 | component: require('./views/home.vue') 5 | }, 6 | '/page/1': { 7 | component: require('./views/page1.vue') 8 | }, 9 | '/page/2': { 10 | component: require('./views/page2.vue') 11 | }, 12 | '/page/3': { 13 | component: require('./views/page3.vue'), 14 | subRoutes: { 15 | '/': { 16 | component: require('./views/subroutes/sr1.vue') 17 | }, 18 | '/wechat': { 19 | component: require('./views/subroutes/sr1.vue') 20 | }, 21 | '/message': { 22 | component: require('./views/subroutes/sr2.vue'), 23 | $$routerTransition: { 24 | forward: 'roll', 25 | back: 'roll' 26 | } 27 | }, 28 | '/explore': { 29 | component: require('./views/subroutes/sr3.vue') 30 | }, 31 | '/news': { 32 | component: require('./views/subroutes/sr4.vue') 33 | } 34 | } 35 | }, 36 | '/page/4': { 37 | component: require('./views/page4.vue') 38 | }, 39 | '/page/5': { 40 | component: require('./views/page5.vue') 41 | } 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /example/src/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'vux-demo'; 3 | src: url('//at.alicdn.com/t/font_1466303154_3970063.eot'); /* IE9*/ 4 | src: url('//at.alicdn.com/t/font_1466303154_3970063.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('//at.alicdn.com/t/font_1466303154_3970063.woff') format('woff'), /* chrome、firefox */ 6 | url('//at.alicdn.com/t/font_1466303154_3970063.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ 7 | url('//at.alicdn.com/t/font_1466303154_3970063.svg#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .demo-icon { 11 | font-family: 'vux-demo'; 12 | font-size:20px; 13 | padding-right: 10px; 14 | color: #04BE02; 15 | } 16 | 17 | .demo-icon:before { 18 | content: attr(icon); 19 | } 20 | -------------------------------------------------------------------------------- /example/src/views/home.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 42 | 43 | 64 | -------------------------------------------------------------------------------- /example/src/views/page1.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 25 | -------------------------------------------------------------------------------- /example/src/views/page2.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | -------------------------------------------------------------------------------- /example/src/views/page3.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 49 | 50 | 78 | -------------------------------------------------------------------------------- /example/src/views/page4.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | -------------------------------------------------------------------------------- /example/src/views/page5.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | -------------------------------------------------------------------------------- /example/src/views/subroutes/sr1.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /example/src/views/subroutes/sr2.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /example/src/views/subroutes/sr3.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /example/src/views/subroutes/sr4.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /example/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/repairearth/vue-router-transition/a88a70d0dc247e45ffd1b24a7148bd969eb137c1/example/static/.gitkeep -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const HIS_KEY = '$$vue_router_history' 2 | const sessionStorage = window.sessionStorage 3 | const DIRECTION = { 4 | FORWARD: 'forward', 5 | BACK: 'back' 6 | } 7 | 8 | function VueRouterTransition (Vue, VueRouter, {indexPath = '/'} = {}) { 9 | const stackHistory = sessionStorage.getItem(HIS_KEY) 10 | let stack = [indexPath] 11 | 12 | if (stackHistory) { 13 | stack = JSON.parse(stackHistory) 14 | } 15 | 16 | const _ = Vue.util 17 | const routerViewDef = Vue.elementDirective('router-view') 18 | const originalRouterViewDef = _.extend({}, routerViewDef) 19 | const _onTransitionValidated = VueRouter.prototype._onTransitionValidated 20 | const transitionDef = 21 | // 0.12 22 | Vue.directive('_transition') || 23 | // 1.0 24 | Vue.internalDirectives.transition 25 | 26 | // override vue-router and internal transition directive 27 | _.extend(VueRouter.prototype, { 28 | _onTransitionValidated (transition) { 29 | const { from, to } = transition 30 | const fromPath = from.path 31 | const toPath = to.path 32 | const fromStackIndex = stack.indexOf(fromPath) 33 | const toStackIndex = stack.indexOf(toPath) 34 | let direction 35 | 36 | if (toStackIndex > -1) { 37 | direction = toStackIndex > fromStackIndex ? DIRECTION.FORWARD : DIRECTION.BACK 38 | } else { 39 | direction = DIRECTION.FORWARD 40 | stack.push(toPath) 41 | sessionStorage.setItem(HIS_KEY, JSON.stringify(stack)) 42 | } 43 | 44 | this.app.$$transitionInfo = { 45 | direction, 46 | routerTransition: to.$$routerTransition 47 | } 48 | 49 | _onTransitionValidated.apply(this, arguments) 50 | } 51 | }) 52 | 53 | _.extend(routerViewDef, { 54 | transition (target, cb) { 55 | const self = this 56 | const { vm } = this 57 | 58 | if (vm.$$routerTransition) { 59 | const { $$transitionInfo } = vm.$root 60 | const routerTransition = $$transitionInfo.routerTransition || vm.$$routerTransition 61 | 62 | vm.$$transition = routerTransition[$$transitionInfo.direction] 63 | 64 | Vue.nextTick(() => { 65 | originalRouterViewDef.transition.call(self, target, cb) 66 | }) 67 | } else { 68 | originalRouterViewDef.transition.call(self, target, cb) 69 | } 70 | } 71 | }) 72 | 73 | _.extend(transitionDef, { 74 | bind () { 75 | const { el, vm } = this 76 | if (el.__r_transition__) { 77 | /* istanbul ignore if */ 78 | if (vm._defineMeta) { 79 | // 0.12 80 | vm._defineMeta('$$transition', el.__r_transition__.forward) 81 | } else { 82 | // 1.0 83 | _.defineReactive(vm, '$$transition', el.__r_transition__.forward) 84 | } 85 | this.literal = false 86 | this.expression = '$$transition' 87 | } 88 | } 89 | }) 90 | 91 | // create `r-transition` directive 92 | Vue.directive('r-transition', { 93 | priority: 1101, 94 | update (value) { 95 | this.el.__r_transition__ = this.vm.$$routerTransition = _.isPlainObject(value) && value || { 96 | forward: DIRECTION.FORWARD, 97 | back: DIRECTION.BACK 98 | } 99 | } 100 | }) 101 | } 102 | 103 | export default VueRouterTransition 104 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var HIS_KEY = '$$vue_router_history'; 7 | var sessionStorage = window.sessionStorage; 8 | var DIRECTION = { 9 | FORWARD: 'forward', 10 | BACK: 'back' 11 | }; 12 | 13 | function VueRouterTransition(Vue, VueRouter) { 14 | var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 15 | 16 | var _ref$indexPath = _ref.indexPath; 17 | var indexPath = _ref$indexPath === undefined ? '/' : _ref$indexPath; 18 | 19 | var stackHistory = sessionStorage.getItem(HIS_KEY); 20 | var stack = [indexPath]; 21 | 22 | if (stackHistory) { 23 | stack = JSON.parse(stackHistory); 24 | } 25 | 26 | var _ = Vue.util; 27 | var routerViewDef = Vue.elementDirective('router-view'); 28 | var originalRouterViewDef = _.extend({}, routerViewDef); 29 | var _onTransitionValidated2 = VueRouter.prototype._onTransitionValidated; 30 | var transitionDef = 31 | // 0.12 32 | Vue.directive('_transition') || 33 | // 1.0 34 | Vue.internalDirectives.transition; 35 | 36 | // override vue-router and internal transition directive 37 | _.extend(VueRouter.prototype, { 38 | _onTransitionValidated: function _onTransitionValidated(transition) { 39 | var from = transition.from; 40 | var to = transition.to; 41 | 42 | var fromPath = from.path; 43 | var toPath = to.path; 44 | var fromStackIndex = stack.indexOf(fromPath); 45 | var toStackIndex = stack.indexOf(toPath); 46 | var direction = void 0; 47 | 48 | if (toStackIndex > -1) { 49 | direction = toStackIndex > fromStackIndex ? DIRECTION.FORWARD : DIRECTION.BACK; 50 | } else { 51 | direction = DIRECTION.FORWARD; 52 | stack.push(toPath); 53 | sessionStorage.setItem(HIS_KEY, JSON.stringify(stack)); 54 | } 55 | 56 | this.app.$$transitionInfo = { 57 | direction: direction, 58 | routerTransition: to.$$routerTransition 59 | }; 60 | 61 | _onTransitionValidated2.apply(this, arguments); 62 | } 63 | }); 64 | 65 | _.extend(routerViewDef, { 66 | transition: function transition(target, cb) { 67 | var self = this; 68 | var vm = this.vm; 69 | 70 | 71 | if (vm.$$routerTransition) { 72 | var $$transitionInfo = vm.$root.$$transitionInfo; 73 | 74 | var routerTransition = $$transitionInfo.routerTransition || vm.$$routerTransition; 75 | 76 | vm.$$transition = routerTransition[$$transitionInfo.direction]; 77 | 78 | Vue.nextTick(function () { 79 | originalRouterViewDef.transition.call(self, target, cb); 80 | }); 81 | } else { 82 | originalRouterViewDef.transition.call(self, target, cb); 83 | } 84 | } 85 | }); 86 | 87 | _.extend(transitionDef, { 88 | bind: function bind() { 89 | var el = this.el; 90 | var vm = this.vm; 91 | 92 | if (el.__r_transition__) { 93 | /* istanbul ignore if */ 94 | if (vm._defineMeta) { 95 | // 0.12 96 | vm._defineMeta('$$transition', el.__r_transition__.forward); 97 | } else { 98 | // 1.0 99 | _.defineReactive(vm, '$$transition', el.__r_transition__.forward); 100 | } 101 | this.literal = false; 102 | this.expression = '$$transition'; 103 | } 104 | } 105 | }); 106 | 107 | // create `r-transition` directive 108 | Vue.directive('r-transition', { 109 | priority: 1101, 110 | update: function update(value) { 111 | this.el.__r_transition__ = this.vm.$$routerTransition = _.isPlainObject(value) && value || { 112 | forward: DIRECTION.FORWARD, 113 | back: DIRECTION.BACK 114 | }; 115 | } 116 | }); 117 | } 118 | 119 | exports.default = VueRouterTransition; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-transition", 3 | "version": "1.0.9", 4 | "description": "A page transition plugin for vue-router", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "build": "npm run lint && npm run build-cjs && npm run build-umd", 8 | "build-cjs": "rimraf lib && babel ./index.js -d lib", 9 | "build-umd": "rimraf umd && webpack -p", 10 | "lint": "eslint --format node_modules/eslint-friendly-formatter ./index.js", 11 | "lint:fix": "npm run lint -- --fix" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/weinot/vue-router-transition.git" 16 | }, 17 | "keywords": [ 18 | "vue", 19 | "vue-router", 20 | "transition" 21 | ], 22 | "author": "vnot", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/weinot/vue-router-transition/issues" 26 | }, 27 | "homepage": "https://github.com/weinot/vue-router-transition#readme", 28 | "devDependencies": { 29 | "babel-cli": "^6.11.4", 30 | "babel-core": "^6.11.4", 31 | "babel-eslint": "^6.1.2", 32 | "babel-loader": "^6.2.4", 33 | "babel-preset-es2015": "^6.9.0", 34 | "babel-preset-stage-0": "^6.5.0", 35 | "eslint": "^3.1.1", 36 | "eslint-config-standard": "^5.3.5", 37 | "eslint-friendly-formatter": "^2.0.6", 38 | "eslint-plugin-promise": "^2.0.0", 39 | "eslint-plugin-standard": "^2.0.0", 40 | "webpack": "^1.12.9" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /umd/vue-router-transition.min.js: -------------------------------------------------------------------------------- 1 | !function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.VueRouterTransition=i():t.VueRouterTransition=i()}(this,function(){return function(t){function i(e){if(n[e])return n[e].exports;var r=n[e]={exports:{},id:e,loaded:!1};return t[e].call(r.exports,r,r.exports,i),r.loaded=!0,r.exports}var n={};return i.m=t,i.c=n,i.p="",i(0)}([function(t,i){"use strict";function n(t,i){var n=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],a=n.indexPath,s=void 0===a?"/":a,d=r.getItem(e),u=[s];d&&(u=JSON.parse(d));var f=t.util,c=t.elementDirective("router-view"),p=f.extend({},c),_=i.prototype._onTransitionValidated,l=t.directive("_transition")||t.internalDirectives.transition;f.extend(i.prototype,{_onTransitionValidated:function(t){var i=t.from,n=t.to,a=i.path,s=n.path,d=u.indexOf(a),f=u.indexOf(s),c=void 0;f>-1?c=f>d?o.FORWARD:o.BACK:(c=o.FORWARD,u.push(s),r.setItem(e,JSON.stringify(u))),this.app.$$transitionInfo={direction:c,routerTransition:n.$$routerTransition},_.apply(this,arguments)}}),f.extend(c,{transition:function(i,n){var e=this,r=this.vm;if(r.$$routerTransition){var o=r.$root.$$transitionInfo,a=o.routerTransition||r.$$routerTransition;r.$$transition=a[o.direction],t.nextTick(function(){p.transition.call(e,i,n)})}else p.transition.call(e,i,n)}}),f.extend(l,{bind:function(){var t=this.el,i=this.vm;t.__r_transition__&&(i._defineMeta?i._defineMeta("$$transition",t.__r_transition__.forward):f.defineReactive(i,"$$transition",t.__r_transition__.forward),this.literal=!1,this.expression="$$transition")}}),t.directive("r-transition",{priority:1101,update:function(t){this.el.__r_transition__=this.vm.$$routerTransition=f.isPlainObject(t)&&t||{forward:o.FORWARD,back:o.BACK}}})}Object.defineProperty(i,"__esModule",{value:!0});var e="$$vue_router_history",r=window.sessionStorage,o={FORWARD:"forward",BACK:"back"};i["default"]=n}])}); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | entry: './index.js', 4 | 5 | output: { 6 | library: 'VueRouterTransition', 7 | libraryTarget: 'umd', 8 | path: 'umd', 9 | filename: 'vue-router-transition.min.js' 10 | }, 11 | 12 | module: { 13 | loaders: [{ 14 | test: /\.js$/, 15 | exclude: /node_modules/, 16 | loader: 'babel', 17 | query: { 18 | cacheDirectory: true, 19 | presets: ['es2015', 'stage-0'] 20 | } 21 | }], 22 | resolve: { 23 | extensions: ['', '.js'] 24 | } 25 | }, 26 | eslint: { 27 | formatter: require('eslint-friendly-formatter'), 28 | emitWarning: false 29 | } 30 | } --------------------------------------------------------------------------------