├── babel.config.js ├── public ├── favicon.ico └── index.html ├── examples ├── assets │ ├── bg.png │ ├── fb.jpg │ ├── google.jpg │ └── logo.png ├── main.js ├── example │ ├── example-dark.vue │ ├── example-insert.vue │ ├── example-after.vue │ ├── example.vue │ ├── example-swap.vue │ ├── example-key.vue │ ├── example-save.vue │ ├── example-custom-close.vue │ ├── example-custom.vue │ ├── example-events.vue │ ├── example-custom-tab-buttons.vue │ └── example-chrome.vue └── App.vue ├── .editorconfig ├── .gitignore ├── packages ├── render-temp.vue ├── index.js └── vue-tabs-chrome.vue ├── .npmignore ├── deploy.sh ├── vue.config.js ├── package.json └── README.md /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viewweiwu/vue-tabs-chrome/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /examples/assets/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viewweiwu/vue-tabs-chrome/HEAD/examples/assets/bg.png -------------------------------------------------------------------------------- /examples/assets/fb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viewweiwu/vue-tabs-chrome/HEAD/examples/assets/fb.jpg -------------------------------------------------------------------------------- /examples/assets/google.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viewweiwu/vue-tabs-chrome/HEAD/examples/assets/google.jpg -------------------------------------------------------------------------------- /examples/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viewweiwu/vue-tabs-chrome/HEAD/examples/assets/logo.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | quote_type = single 7 | -------------------------------------------------------------------------------- /examples/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import VueTabsChrome from '../packages' 4 | 5 | Vue.use(VueTabsChrome) 6 | 7 | Vue.config.productionTip = false 8 | 9 | new Vue({ 10 | render: h => h(App) 11 | }).$mount('#app') 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /lib 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /packages/render-temp.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | examples/ 4 | public/ 5 | dist/ 6 | vue.config.js 7 | babel.config.js 8 | deploy.sh 9 | *.map 10 | *.html 11 | 12 | # local env files 13 | .env.local 14 | .env.*.local 15 | 16 | # Log files 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | 21 | # Editor directories and files 22 | .idea 23 | .vscode 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw* -------------------------------------------------------------------------------- /packages/index.js: -------------------------------------------------------------------------------- 1 | import VueTabsChrome from './vue-tabs-chrome' 2 | 3 | const install = function (Vue) { 4 | if (install.installed) return 5 | install.installed = true 6 | Vue.component(VueTabsChrome.name, VueTabsChrome) 7 | } 8 | 9 | if (typeof window !== 'undefined' && window.Vue) { 10 | install(window.Vue) 11 | } 12 | 13 | VueTabsChrome.install = install 14 | 15 | export { VueTabsChrome } 16 | 17 | export default VueTabsChrome 18 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 当发生错误时中止脚本 4 | set -e 5 | 6 | # 构建 7 | npm run build 8 | 9 | # cd 到构建输出的目录下 10 | cd dist 11 | 12 | # 部署到自定义域域名 13 | # echo 'www.example.com' > CNAME 14 | 15 | git init 16 | git add -A 17 | git commit -m 'deploy' 18 | 19 | # 部署到 https://.github.io 20 | # git push -f git@github.com:/.github.io.git master 21 | 22 | # 部署到 https://.github.io/ 23 | git push -f https://github.com/viewweiwu/vue-tabs-chrome.git master:gh-pages 24 | 25 | cd - -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | function resolve (dir) { 3 | return path.join(__dirname, dir) 4 | } 5 | module.exports = { 6 | lintOnSave: false, 7 | css: { 8 | extract: false 9 | }, 10 | publicPath: process.env.NODE_ENV === 'production' 11 | ? '/vue-tabs-chrome/' 12 | : '/', 13 | pages: { 14 | index: { 15 | entry: 'examples/main.js', 16 | template: 'public/index.html', 17 | filename: 'index.html' 18 | } 19 | }, 20 | chainWebpack: (config) => { 21 | config.resolve.alias 22 | .set('@', resolve('examples/assets')) 23 | config.module 24 | .rule('js').include 25 | .add('/packages') 26 | .end() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | vue-tabs-chrome 12 | 13 | 14 | 15 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/example/example-dark.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 44 | -------------------------------------------------------------------------------- /examples/example/example-insert.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 44 | -------------------------------------------------------------------------------- /examples/example/example-after.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 50 | -------------------------------------------------------------------------------- /examples/example/example.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 55 | -------------------------------------------------------------------------------- /examples/example/example-swap.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 61 | -------------------------------------------------------------------------------- /examples/example/example-key.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 68 | -------------------------------------------------------------------------------- /examples/example/example-save.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-tabs-chrome", 3 | "version": "0.10.0", 4 | "author": "viewweiwu", 5 | "private": false, 6 | "license": "MIT", 7 | "main": "lib/vue-tabs-chrome.umd.min.js", 8 | "scripts": { 9 | "serve": "vue-cli-service serve", 10 | "build": "vue-cli-service build", 11 | "lint": "vue-cli-service lint", 12 | "lib": "vue-cli-service build --target lib --name vue-tabs-chrome --dest lib packages/index.js" 13 | }, 14 | "dependencies": { 15 | "core-js": "^2.6.5", 16 | "draggabilly": "^2.2.0", 17 | "vue": "^2.6.10" 18 | }, 19 | "devDependencies": { 20 | "@vue/cli-plugin-babel": "^3.8.0", 21 | "@vue/cli-plugin-eslint": "^3.8.0", 22 | "@vue/cli-service": "^3.8.0", 23 | "@vue/eslint-config-standard": "^4.0.0", 24 | "babel-eslint": "^10.0.1", 25 | "eslint": "^5.16.0", 26 | "eslint-plugin-vue": "^5.0.0", 27 | "less": "^3.0.4", 28 | "less-loader": "^4.1.0", 29 | "lint-staged": "^8.1.5", 30 | "pug": "^3.0.1", 31 | "pug-loader": "^2.4.0", 32 | "pug-plain-loader": "^1.0.0", 33 | "vue-highlightjs": "^1.3.3", 34 | "vue-template-compiler": "^2.6.10" 35 | }, 36 | "eslintConfig": { 37 | "root": true, 38 | "env": { 39 | "node": true 40 | }, 41 | "extends": [ 42 | "plugin:vue/essential", 43 | "@vue/standard" 44 | ], 45 | "rules": {}, 46 | "parserOptions": { 47 | "parser": "babel-eslint" 48 | } 49 | }, 50 | "postcss": { 51 | "plugins": { 52 | "autoprefixer": {} 53 | } 54 | }, 55 | "browserslist": [ 56 | "> 1%", 57 | "last 2 versions" 58 | ], 59 | "gitHooks": { 60 | "pre-commit": "lint-staged" 61 | }, 62 | "lint-staged": { 63 | "*.{js,vue}": [ 64 | "vue-cli-service lint", 65 | "git add" 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /examples/example/example-custom-close.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 62 | 63 | 83 | -------------------------------------------------------------------------------- /examples/example/example-custom.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 44 | 45 | 99 | -------------------------------------------------------------------------------- /examples/example/example-events.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 87 | -------------------------------------------------------------------------------- /examples/example/example-custom-tab-buttons.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 76 | 77 | 111 | -------------------------------------------------------------------------------- /examples/App.vue: -------------------------------------------------------------------------------- 1 | 87 | 88 | 104 | 105 | 195 | -------------------------------------------------------------------------------- /examples/example/example-chrome.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 170 | 171 | 274 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-tabs-chrome 2 | 3 | A Vue2 component for Chrome-like tabs.
4 | Drag-and-drop support provided by Draggabilly by @desandro. 5 | 6 | If you are using Vue3, please see here. 7 | https://github.com/viewweiwu/vue3-tabs-chrome 8 | 9 | ## Live Demo 10 | 11 | [https://viewweiwu.github.io/vue-tabs-chrome/](https://viewweiwu.github.io/vue-tabs-chrome/) 12 | 13 | ### Code Sandbox Example 14 | 15 | example: https://codesandbox.io/s/kind-wave-00ipv?file=/src/App.vue 16 | 17 | use VueRouter: https://codesandbox.io/s/twilight-forest-mm55be?file=/src/App.vue 18 | 19 | ### CDN 20 | 21 | [https://codepen.io/viewweiwu/pen/GRmKaZZ](https://codepen.io/viewweiwu/pen/GRmKaZZ) 22 | 23 | ## Install 24 | 25 | ``` 26 | npm i vue-tabs-chrome -S 27 | ``` 28 | 29 | ## Usage 30 | 31 | ```html 32 | 35 | 70 | ``` 71 | 72 | ## Attributes 73 | 74 | | Attributes | Description | Type | Default | 75 | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | ------- | 76 | | tabs | tabs configuration. Details are mentioned below. | Array | [] | 77 | | value / v-model | binding value | String | - | 78 | | props | configuration options, Details are mentioned below. | 79 | | insert-to-after | Insert to tag's after | Boolean | false | 80 | | is-mousedown-active | set tab is active when mousedown | Boolean | true | 81 | | render-label | render label | Function(tab, index) | - | 82 | | auto-hidden-close-icon-width | auto hidden close tab width. if tabWidth < 120, close icon can not show. If you don’t want this feature, you can set the value to 0. | Number | 120 | 83 | | on-close | when tab close btn click. if return false, it cannot be closed. | Function(tab, key, index) | - | 84 | | tab-close-width | tab close icon width. | Number | 16 | 85 | 86 | ## Tabs Attributes 87 | 88 | | Attributes | Description | Type | Default | 89 | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------- | 90 | | label | tab label | String | - | 91 | | key | tab key | String | - | 92 | | class | tab class | String | - | 93 | | closable | tab closable | Boolean | true | 94 | | dragable | tab tragable | Boolean | true | 95 | | swappable | tab swappable | Boolean | true | 96 | | favicon | tab favicon. Custom favicon renderer. It uses Vue's render function. It accepts two arguments: the first is h, the second is an object. including tab and index | Function, required image | - | 97 | 98 | ## Props Attributes 99 | 100 | | Attributes | Description | Type | Default | 101 | | ---------- | ---------------------------------------------------------- | ------ | ------- | 102 | | label | specify which key of tab object is used as the tab's label | String | 'label' | 103 | | key | specify which key of tab object is used as the tab's key | String | 'key' | 104 | 105 | ## Methods 106 | 107 | | Method | Description | Parameters | 108 | | --------- | ----------- | --------------------------- | 109 | | addTab | add tab | (tab1, [, ...tab, ...tabN]) | 110 | | removeTab | remove tab | (tabKey or index) | 111 | | getTabs | get tabs | - | 112 | 113 | ## Events 114 | 115 | | Event Name | Description | Parameters | 116 | | ----------- | ------------------------------------------------------------------------------------------------------ | ------------------- | 117 | | click | Triggered when the user's pointer is pressed and unpressed and has not moved enough to start dragging. | (event, tab, index) | 118 | | swap | Swap tab | (tab, targetTab) | 119 | | remove | Remove tab | (tab, index) | 120 | | contextmenu | Contextmenu event | (event, tab, index) | 121 | | dragstart | Tab dragstart event | (event, tab, index) | 122 | | dragging | Tab dragstart event | (event, tab, index) | 123 | | dragend | Tab dragend event | (event, tab) | 124 | 125 | ## Slots 126 | 127 | | Attributes | Description | 128 | | ---------- | -------------- | 129 | | after | Tab after slot | 130 | | close-icon | Close icon | 131 | 132 | ## Change log 133 | 134 | ## 0.10.0 135 | 136 | 1. feat: Add Custom Close Button. 137 | 138 | ## v0.9.2 139 | 140 | 1. fix: 'v0.9.1' doesn't work 141 | 142 | ## v0.9.1 143 | 144 | 1. fix: 'dragable' needs to respond to the 'click' event. 145 | 146 | ## v0.9.0 147 | 148 | 1. feat: tab can set dragable. 149 | 2. feat: tab can set swappable. 150 | 3. feat: can be introduced with "Vue.components" instead of "Vue.use". 151 | 4. feat: new example UI. 152 | 5. feat: new 'Chrome UI' example. 153 | 6. feat: new 'swap & drag' example. 154 | 7. remove: remove 'Save to Localstorage' example. 155 | 156 | ## 2020/9/21 157 | 158 | fix: tab[key] => tab[this.tabKey] 159 | 160 | ## 2020/9/21 161 | 162 | feat: add after slots 163 | feat: add drag events 164 | 165 | ## 2020/9/7 166 | 167 | fix: closable not work 168 | feat: auto hidden close tab width 169 | 170 | ## 2020/8/19 171 | 172 | add new feature: tab close event listener & tab custom class 173 | 174 | ## 2020/2/10 175 | 176 | add new feature: tab closable 177 | 178 | ## License 179 | 180 | MIT 181 | -------------------------------------------------------------------------------- /packages/vue-tabs-chrome.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 422 | 423 | 659 | --------------------------------------------------------------------------------