├── .babelrc ├── .editorconfig ├── .gitignore ├── README.md ├── dist ├── tab-swiper.js └── tab-swiper.js.map ├── index.html ├── package.json ├── src ├── App.vue ├── assets │ ├── logo.png │ └── swiper.gif ├── components │ └── tab-swiper-warp │ │ ├── index.vue │ │ ├── swiper-item │ │ └── index.vue │ │ └── swiper-tab │ │ └── index.vue ├── index.js └── main.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-3" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | yarn-error.log 5 | 6 | # Editor directories and files 7 | .idea 8 | *.suo 9 | *.ntvs* 10 | *.njsproj 11 | *.sln 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## vue-tab-swiper-yan 2 | 轻量的触摸滑动组件 3 | ## installation 4 | ``` 5 | npm i vue-tab-swiper-yan --save //安装 6 | ``` 7 | 8 | ``` 9 | //注册组件 10 | import vueSwiper from 'vue-tab-swiper-yan'; 11 | Vue.use(vueSwiper) 12 | ``` 13 | ## Usage 14 | ```html 15 | 16 | 17 | 18 | 19 | 20 | 1 21 | 22 | 23 | 2 24 | 25 | 26 | 3 27 | 28 | 29 | 30 | 31 | 32 | 1 33 | 34 | 35 | 2 36 | 37 | 38 | 3 39 | 40 | 41 | 42 | ``` 43 | ## example 44 |  45 | ## Props 46 | 47 | | Prop | Data Type | Default | Description | 48 | | -------- | -----: | :----: | :----: | 49 | | loop | Boolean | false | 是否可以无限滑动 | 50 | 51 | 存在两个slot插槽 tab 和 content 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /dist/tab-swiper.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("tabSwiper",[],e):"object"==typeof exports?exports.tabSwiper=e():t.tabSwiper=e()}("undefined"!=typeof self?self:this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/dist/",e(e.s=5)}([function(t,e){function n(t,e){var n=t[1]||"",o=t[3];if(!o)return n;if(e&&"function"==typeof btoa){var i=r(o);return[n].concat(o.sources.map(function(t){return"/*# sourceURL="+o.sourceRoot+t+" */"})).concat([i]).join("\n")}return[n].join("\n")}function r(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var r=n(e,t);return e[2]?"@media "+e[2]+"{"+r+"}":r}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{for(var a=[],o=0;othis.pageWidth/3&&(this.loop||e>0&&r<0||e<0&&Math.abs(r)<(this.transwarpDom.querySelectorAll(".tabItem").length-1)*this.pageWidth)){var o=e>0?this.pageWidth:-this.pageWidth;this.doSlide(o,!0)}else this.doSlide(0,!0)},doSlide:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=this.originalLeft+t;if(this.transwarpDom.style.transform="translate3d("+r+"px,0px,0px)",this.transwarpDom.style.transition=n?"transform .3s":"initial",this.loop&&n){var o=this.transwarpDom.querySelectorAll(".tabItem").length;Math.abs(r)>(o-3)*this.pageWidth?setTimeout(function(){e.doSlide((o-3)*e.pageWidth)},300):r>0&&setTimeout(function(){e.doSlide(-(o-3)*e.pageWidth)},300)}}}}},function(t,e,n){"use strict";e.a={name:"swiperItem"}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(6),o=n(11),i=function(t,e){t.component(r.a.name,r.a),t.component(o.a.name,o.a)};e.default=i},function(t,e,n){"use strict";function r(t){n(7)}var o=n(3),i=n(10),a=n(2),s=r,u=a(o.a,i.a,!1,s,"data-v-ddfd19f2",null);e.a=u.exports},function(t,e,n){var r=n(8);"string"==typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);n(1)("d409edc6",r,!0,{})},function(t,e,n){e=t.exports=n(0)(!1),e.push([t.i,".tabSwiperWarp[data-v-ddfd19f2]{width:100%;overflow:hidden}.transwarp[data-v-ddfd19f2]{font-size:0;transform:translateZ(0);white-space:nowrap;display:inline-block;padding:40px 0;box-sizing:border-box;width:100%;position:relative}",""])},function(t,e){t.exports=function(t,e){for(var n=[],r={},o=0;o\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\nvar options = null\nvar ssrIdKey = 'data-vue-ssr-id'\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \r\n\r\n\n\n\n// WEBPACK FOOTER //\n// src/components/tab-swiper-warp/index.vue","\r\n \r\n \r\n \r\n\r\n\r\n\r\n\r\n\r\n\n\n\n// WEBPACK FOOTER //\n// src/components/tab-swiper-warp/swiper-item/index.vue","import tabSwiperWarp from '../src/components/tab-swiper-warp/index.vue'\r\nimport swiperItem from '../src/components/tab-swiper-warp/swiper-item/index.vue'\r\nconst install =function(Vue,options){\r\n Vue.component(tabSwiperWarp.name,tabSwiperWarp)\r\n Vue.component(swiperItem.name,swiperItem)\r\n}\r\nexport default install\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","function injectStyle (ssrContext) {\n require(\"!!vue-loader/node_modules/vue-style-loader!css-loader?minimize!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-ddfd19f2\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/selector?type=styles&index=0!./index.vue\")\n}\nvar normalizeComponent = require(\"!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/selector?type=script&index=0!./index.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/selector?type=script&index=0!./index.vue\"\n/* template */\nimport __vue_template__ from \"!!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-ddfd19f2\\\",\\\"hasScoped\\\":true,\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/_vue-loader@13.7.3@vue-loader/lib/selector?type=template&index=0!./index.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-ddfd19f2\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/tab-swiper-warp/index.vue\n// module id = 6\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a 65 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuanfengYan/vue-tab-swiper-yan/c221859e2ebf0a3a86cab961313db836670a2101/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/swiper.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuanfengYan/vue-tab-swiper-yan/c221859e2ebf0a3a86cab961313db836670a2101/src/assets/swiper.gif -------------------------------------------------------------------------------- /src/components/tab-swiper-warp/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 152 | 153 | 180 | 181 | -------------------------------------------------------------------------------- /src/components/tab-swiper-warp/swiper-item/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 20 | 21 | -------------------------------------------------------------------------------- /src/components/tab-swiper-warp/swiper-tab/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import tabSwiperWarp from '../src/components/tab-swiper-warp/index.vue' 2 | import swiperItem from '../src/components/tab-swiper-warp/swiper-item/index.vue' 3 | import swiperTab from '../src/components/tab-swiper-warp/swiper-tab/index.vue' 4 | const install =function(Vue,options){ 5 | Vue.component(tabSwiperWarp.name,tabSwiperWarp) 6 | Vue.component(swiperItem.name,swiperItem) 7 | Vue.component(swiperTab.name,swiperTab) 8 | } 9 | export default install 10 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import Plugin from './index.js' 4 | Vue.use(Plugin) 5 | new Vue({ 6 | el: '#app', 7 | render: h => h(App) 8 | }) 9 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/main.js', 6 | // entry: './src/index.js', 7 | output: { 8 | path: path.resolve(__dirname, './dist'), 9 | publicPath: '/dist/', 10 | filename: 'build.js', 11 | // filename: 'tab-swiper.js',//修改打包输出文件 12 | library: 'tabSwiper', //新增 13 | libraryTarget: 'umd', //新增 14 | umdNamedDefine: true //新增 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.css$/, 20 | use: [ 21 | 'vue-style-loader', 22 | 'css-loader' 23 | ], 24 | }, { 25 | test: /\.vue$/, 26 | loader: 'vue-loader', 27 | options: { 28 | loaders: { 29 | } 30 | // other vue-loader options go here 31 | } 32 | }, 33 | { 34 | test: /\.js$/, 35 | loader: 'babel-loader', 36 | exclude: /node_modules/ 37 | }, 38 | { 39 | test: /\.(png|jpg|gif|svg)$/, 40 | loader: 'file-loader', 41 | options: { 42 | name: '[name].[ext]?[hash]' 43 | } 44 | } 45 | ] 46 | }, 47 | resolve: { 48 | alias: { 49 | 'vue$': 'vue/dist/vue.esm.js' 50 | }, 51 | extensions: ['*', '.js', '.vue', '.json'] 52 | }, 53 | devServer: { 54 | historyApiFallback: true, 55 | noInfo: true, 56 | overlay: true 57 | }, 58 | performance: { 59 | hints: false 60 | }, 61 | devtool: '#eval-source-map' 62 | } 63 | 64 | if (process.env.NODE_ENV === 'production') { 65 | module.exports.devtool = '#source-map' 66 | // http://vue-loader.vuejs.org/en/workflow/production.html 67 | module.exports.plugins = (module.exports.plugins || []).concat([ 68 | new webpack.DefinePlugin({ 69 | 'process.env': { 70 | NODE_ENV: '"production"' 71 | } 72 | }), 73 | new webpack.optimize.UglifyJsPlugin({ 74 | sourceMap: true, 75 | compress: { 76 | warnings: false 77 | } 78 | }), 79 | new webpack.LoaderOptionsPlugin({ 80 | minimize: true 81 | }) 82 | ]) 83 | } 84 | --------------------------------------------------------------------------------