├── .gitignore
├── README.md
├── index.js
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # VS Code dir
61 | .vscode
62 |
63 | # MacOS
64 | .DS_Store
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-responsive-components
2 |
3 | Create responsive components with ResizeObserver.
4 |
5 | ## Idea
6 |
7 | Check out [**my post on ITNEXT**](https://itnext.io/making-adaptive-vue-components-with-resizeobserver-123b5ebb20ae)
8 |
9 | ## Installation
10 |
11 | ```
12 | npm install vue-responsive-components
13 | ```
14 |
15 | ## (Optional) Add plugin globally
16 |
17 | ```javascript
18 | import Vue from "vue"
19 | import { VueResponsiveComponents } from "vue-responsive-components"
20 |
21 | Vue.use(VueResponsiveComponents)
22 | ```
23 |
24 | It will add `Responsive` component and `v-responsive` directive
25 |
26 | ## Usage
27 |
28 | #### `Responsive` component with scoped slot
29 |
30 | ```vue
31 |
32 |
35 |
36 |
![]()
37 |
{{post.text}}
38 |
39 |
40 |
41 |
42 |
50 |
51 |
70 | ```
71 |
72 | #### `v-responsive` directive
73 |
74 | > Thanks to [**this guy**](https://www.reddit.com/r/vuejs/comments/8eap88/making_responsive_vue_components_with/dxtx0bu/) for idea
75 |
76 | ```vue
77 |
78 |
79 |
80 |
![]()
81 |
{{post.text}}
82 |
83 |
84 |
85 |
95 | ```
96 |
97 | #### Mixin
98 |
99 | ```vue
100 |
101 |
102 |
![]()
103 |
{{post.text}}
104 |
105 |
106 |
107 |
118 | ```
119 |
120 | ## License
121 |
122 | MIT
123 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import throttle from "lodash.throttle"
2 | import ResizeObserver from "resize-observer-polyfill"
3 |
4 | export const ResponsiveMixin = {
5 | data() {
6 | return {
7 | el: {
8 | width: 0,
9 | height: 0,
10 | is: {}
11 | }
12 | }
13 | },
14 | mounted() {
15 | if (
16 | typeof process === "undefined" ||
17 | (!process.server && (this.breakpoints || this.$options.breakpoints))
18 | ) {
19 | this.$nextTick(() => {
20 | const handleResize = throttle(entries => {
21 | const cr = entries[0].contentRect
22 | ;(this.el.width = cr.width), (this.el.height = cr.height)
23 | const conds = Object.assign(
24 | {},
25 | this.breakpoints || {},
26 | this.$options.breakpoints || {}
27 | )
28 | for (const breakpoint in conds) {
29 | this.$set(this.el.is, breakpoint, conds[breakpoint](this.el))
30 | }
31 | }, 200)
32 |
33 | const observer = new ResizeObserver(handleResize)
34 | if (this.$el instanceof Element) {
35 | observer.observe(this.$el)
36 | }
37 | })
38 | }
39 | }
40 | }
41 |
42 | export const Responsive = {
43 | data() {
44 | return { init: false }
45 | },
46 | props: {
47 | noHide: { type: Boolean, default: false },
48 | breakpoints: { type: Object, default: undefined }
49 | },
50 | mixins: [ResponsiveMixin],
51 | render(h) {
52 | const slot =
53 | (this.$scopedSlots.default && this.$scopedSlots.default(this.el)) ||
54 | this.$slots.default
55 |
56 | return !this.noHide && !this.init
57 | ? h(
58 | "div",
59 | {
60 | style: { visibility: "hidden" }
61 | },
62 | [slot]
63 | )
64 | : slot
65 | },
66 | mounted() {
67 | this.init = true
68 | }
69 | }
70 |
71 | export const ResponsiveDirective = {
72 | inserted(el, conds) {
73 | if (typeof process === "undefined" || !process.server) {
74 | const handleResize = throttle(entries => {
75 | const cr = entries[0].contentRect
76 | for (const breakpoint in conds.value) {
77 | if (conds.value[breakpoint](cr)) {
78 | el.classList.add(breakpoint)
79 | } else {
80 | el.classList.remove(breakpoint)
81 | }
82 | }
83 | }, 200)
84 |
85 | const observer = new ResizeObserver(handleResize)
86 | observer.observe(el)
87 | }
88 | }
89 | }
90 |
91 | export const VueResponsiveComponents = Vue => {
92 | Vue.component("Responsive", Responsive)
93 | Vue.directive("responsive", ResponsiveDirective)
94 | }
95 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-responsive-components",
3 | "version": "0.2.3",
4 | "description": "Easily create responsive Vue.js components with ResizeObserver",
5 | "main": "index.js",
6 | "module": "index.js",
7 | "repository": "https://github.com/kelin2025/vue-responsive-components",
8 | "author": "Anton Kosykh ",
9 | "license": "MIT",
10 | "dependencies": {
11 | "lodash.throttle": "^4.1.1",
12 | "resize-observer-polyfill": "^1.5.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | lodash.throttle@^4.1.1:
6 | version "4.1.1"
7 | resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
8 |
9 | resize-observer-polyfill@^1.5.0:
10 | version "1.5.0"
11 | resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69"
12 |
--------------------------------------------------------------------------------