Note that it's **not** recommended to use `v-if` and `v-for` together. Refer to [style guide](/v2/style-guide/#Avoid-v-if-with-v-for-essential) for details.
+
When they exist on the same node, `v-for` has a higher priority than `v-if`. That means the `v-if` will be run on each iteration of the loop separately. This can be useful when you want to render nodes for only _some_ items, like below:
``` html
diff --git a/src/v2/guide/syntax.md b/src/v2/guide/syntax.md
index a0693af2c2..afb7843152 100644
--- a/src/v2/guide/syntax.md
+++ b/src/v2/guide/syntax.md
@@ -154,7 +154,7 @@ Dynamic arguments are expected to evaluate to a string, with the exception of `n
#### Dynamic Argument Expression Constraints
-Dynamic argument expressions have some syntax constraints because certain characters are invalid inside HTML attribute names, such as spaces and quotes.
+Dynamic argument expressions have some syntax constraints because certain characters are invalid inside HTML attribute names, such as spaces and quotes. You also need to avoid uppercase keys when using in-DOM templates.
For example, the following is invalid:
@@ -165,6 +165,13 @@ For example, the following is invalid:
The workaround is to either use expressions without spaces or quotes, or replace the complex expression with a computed property.
+In addition, if you are using in-DOM templates (templates directly written in an HTML file), you have to be aware that browsers will coerce attribute names into lowercase:
+
+``` html
+
+>
diff --git a/themes/vue/layout/partials/vuemastery_banner.ejs b/themes/vue/layout/partials/vuemastery_banner.ejs
deleted file mode 100644
index 384f71a89c..0000000000
--- a/themes/vue/layout/partials/vuemastery_banner.ejs
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
-
diff --git a/themes/vue/source/css/_header.styl b/themes/vue/source/css/_header.styl
index 231427f9be..b63e8c62c9 100644
--- a/themes/vue/source/css/_header.styl
+++ b/themes/vue/source/css/_header.styl
@@ -1,5 +1,15 @@
$header-height = 40px
+red-dot-before(leftPos = -8px)
+ content: ""
+ width: 0
+ height: 0
+ border 2px solid $red
+ border-radius 50%
+ position: absolute
+ top: calc(50% - 1px)
+ left: leftPos
+
#header
background-color: #fff
height: $header-height
@@ -47,6 +57,8 @@ body.docs
top: 50%
margin-top: -4px
left: 8px
+ &.new::before
+ red-dot-before(8px)
.nav-link
padding-bottom: 3px
@@ -55,6 +67,8 @@ body.docs
border-bottom: 3px solid $green
&.team
margin-left: 10px
+ &.new::before
+ red-dot-before()
.new-label
position: absolute
@@ -130,4 +144,4 @@ body.docs
@media print
#header
- display: none
\ No newline at end of file
+ display: none
diff --git a/themes/vue/source/css/_themes-example.styl b/themes/vue/source/css/_themes-example.styl
new file mode 100644
index 0000000000..cc4d92ddfe
--- /dev/null
+++ b/themes/vue/source/css/_themes-example.styl
@@ -0,0 +1,65 @@
+$media-width = 1300px
+$item-margin-bottom = 10px
+$item-box-shadow = 0 2rem 1.5rem -1.5rem rgba(33,37,41,.15), 0 0 1.5rem 0.5rem rgba(33,37,41,.05)
+$item-box-shadow-hover = 0 2.25rem 1.5rem -1.5rem rgba(33,37,41,.2),0 0 1.5rem .5rem rgba(33,37,41,.05);
+
+.themes-grid
+ display: flex
+ flex-wrap: wrap
+ justify-content space-between
+ .item-preview
+ width: 290px
+ margin-bottom 25px
+ .item-preview-img
+ transition: .15s box-shadow,.15s transform
+ border-radius: .5rem
+ box-shadow $item-box-shadow
+ overflow: hidden
+ display block
+ &:hover
+ transform: translateY(-0.25rem)
+ box-shadow: $item-box-shadow-hover
+ img
+ max-width: 100%
+ height: auto
+ border-radius: .5rem
+ vertical-align: middle
+ border-style: none
+ .item-preview-title-container
+ display flex
+ justify-content space-between
+ align-items center
+ h3.item-preview-title
+ margin-top: .7rem
+ margin-bottom: 0
+ &.free::after
+ content: "FREE";
+ display: inline-block
+ font-size: 10px
+ font-weight: 600
+ color: #fff
+ background-color: $green
+ line-height: 14px
+ padding: 0 4px
+ border-radius: 3px
+ margin-left: 5px
+ vertical-align: middle
+ position: relative
+ top: -1px
+ .item-preview-price
+ margin-top: .7rem
+ .item-preview-description
+ font-size: .9rem
+ .see-more-container
+ display: flex
+ justify-content center
+ width: 100%
+ .see-more-link
+ color: $green
+
+@media screen and (max-width: $media-width)
+ .themes-grid
+ justify-content center
+ .item-preview
+ justify-content center
+ width: 380px
diff --git a/themes/vue/source/css/_vuemastery.styl b/themes/vue/source/css/_vue-mastery.styl
similarity index 100%
rename from themes/vue/source/css/_vuemastery.styl
rename to themes/vue/source/css/_vue-mastery.styl
diff --git a/themes/vue/source/css/_vuemastery-banner.styl b/themes/vue/source/css/_vuemastery-banner.styl
deleted file mode 100644
index e330217d11..0000000000
--- a/themes/vue/source/css/_vuemastery-banner.styl
+++ /dev/null
@@ -1,197 +0,0 @@
-.vuemastery-banner
- display none
- background #4fc08d
- background-image linear-gradient(to right, #35495E, #35495E 50%, #4fc08d 50%)
- overflow hidden
- position relative
-
- &:before
- content ''
- background #35495E
- background-image linear-gradient(to right, #4fc08d, #4fc08d 80%, #35495E 100%)
- position absolute
- top 0
- bottom 0
- left 0
- width 0
- transition width .15s ease-out .1s
-
- &:hover
- &:before
- transition width .15s ease-in
- width 50%
- p
- transition-delay 0
- color #fff
-
- .vuemastery-banner--wrapper::before
- width 100vw
- transition width .15s ease-in .10s
-
- a
- display flex
- height 80px
- justify-content center
-
-.vuemastery-banner--wrapper
- display flex
- height 100%
- align-items center
- background #4fc08d
- margin-left -50px
- padding-left 50px
- position relative
-
- &:before
- content ''
- pointer-events none
- background #35495E
- background-image linear-gradient(to right, #35495E, #35495E 80%, #4fc08d 100%)
- position absolute
- top 0
- bottom 0
- left 0
- width 0
- transition width .15s ease-out
-
- &:hover
- + .vuemastery-banner--close
- &:before,
- &:after
- transform-origin 100%
-
- p
- margin -3px 50px 0 20px
- font-size 1.17rem
- font-weight 600
- color #2c3e50
- position relative
- transition-delay .15s
-
- span
- font-size 1rem
- display block
- color #fff
-
-.vuemastery-banner--logo
- height 102%
- margin-top: -1px
- margin-left 125px
- position relative
- z-index 2
-
-.vuemastery-banner--close
- position absolute
- top 20px
- right 25px
- height 40px
- width 40px
- -webkit-tap-highlight-color transparent
- border-radius 50%
- cursor pointer
-
- &:before,
- &:after
- content ''
- position absolute
- top 19px
- left 14px
- width 25px
- height 2px
- background-color #fff
- transform-origin 50%
- transform rotate(-45deg)
- transition all .2s ease-out
-
- &:after
- transform rotate(45deg)
-
- &:hover
- &:before,
- &:after
- transform rotate(180deg)
-
-.vuemastery-weekend-promo
- #mobile-bar,
- #mobile-bar.top
- position relative
- background-color #fff
-
- &.docs:not(.vuemastery-menu-fixed)
- padding-top 0
- #header
- position relative
- width auto
- #nav
- position absolute
-
- &.vuemastery-menu-fixed
- #mobile-bar
- position fixed
-
-@media screen and (min-width: 901px)
- .vuemastery-weekend-promo
- &.docs:not(.vuemastery-menu-fixed)
- #main.fix-sidebar .sidebar
- position absolute
- top 141px
-
- #sidebar-sponsors-platinum-right
- position absolute
- top: 170px;
-
- &.vuemastery-menu-fixed.docs
- .vuemastery-banner
- margin-bottom 0
-
-@media screen and (max-width: 900px)
- .vuemastery-banner
- .vuemastery-banner--logo
- margin-left 0
-
- .vuemastery-weekend-promo
- &.vuemastery-menu-fixed
- .vuemastery-banner
- margin-bottom 40px
-
-
-@media screen and (max-width: 700px)
- .vuemastery-banner
- a
- height 40px
- overflow hidden
-
- .vuemastery-banner--logo
- margin-left 0
- justify-content flex-start
-
- p, span
- font-size .8rem
- color #fff
-
- .vuemastery-banner--close
- top 0px
- right 0px
-
- &:before,
- &:after
- top 19px
- left 14px
- width 15px
- height 2px
-
-@media screen and (max-width: 425px)
- .vuemastery-banner
- p
- max-width 185px
- span
- display none
-
-@media screen and (max-width 286px)
- .vuemastery-banner p
- font-size 0.6rem
- margin -3px 28px 0 0px
-
-@media print
- .vuemastery-banner
- display none
\ No newline at end of file
diff --git a/themes/vue/source/css/index.styl b/themes/vue/source/css/index.styl
index aedfe80698..3795a04679 100644
--- a/themes/vue/source/css/index.styl
+++ b/themes/vue/source/css/index.styl
@@ -3,7 +3,7 @@
@import "_sidebar"
@import "_sponsors-index"
@import "_modal"
-@import "_vuemastery-banner"
+@import "_themes-example"
$width = 900px
$space = 40px
diff --git a/themes/vue/source/css/page.styl b/themes/vue/source/css/page.styl
index 500485e8af..c80a2ed9d6 100644
--- a/themes/vue/source/css/page.styl
+++ b/themes/vue/source/css/page.styl
@@ -13,8 +13,8 @@
@import "_style-guide"
@import "_modal"
@import "_scrimba"
-@import "_vuemastery"
-@import "_vuemastery-banner"
+@import "_vue-mastery"
+@import "_themes-example"
#header
box-shadow: 0 0 1px rgba(0,0,0,.25)
diff --git a/themes/vue/source/js/common.js b/themes/vue/source/js/common.js
index 945afeeb86..c80ab5315c 100644
--- a/themes/vue/source/js/common.js
+++ b/themes/vue/source/js/common.js
@@ -2,6 +2,7 @@
initHashLevelRedirects()
initMobileMenu()
initVideoModal()
+ initNewNavLinks()
if (PAGE_TYPE) {
initVersionSelect()
initApiSpecLinks()
@@ -189,6 +190,50 @@
}
}
+ /**
+ * Initializes a list of links to mark as "updated" by adding a red dot next to them
+ */
+
+ function initNewNavLinks() {
+ var linkExpirePeriod = 60 * 24 * 3600 * 1000 // 2 months
+ var links = [
+ {
+ title: 'Learn',
+ updatedOn: new Date("Fri Mar 1 2019")
+ },
+ {
+ title: 'Examples',
+ updatedOn: new Date("Fri Mar 1 2019")
+ }
+ ]
+ var today = new Date().getTime()
+ var updatedLinks = links
+ .filter(function (link) {
+ return link.updatedOn.getTime() + linkExpirePeriod > today
+ })
+ .map(function (link) {
+ return link.title
+ })
+
+ var navLinks = document.querySelectorAll('#nav a.nav-link')
+ var newLinks = []
+ navLinks.forEach(function (link) {
+ if (updatedLinks.indexOf(link.textContent) !== -1) {
+ newLinks.push(link)
+ }
+ })
+ newLinks.forEach(function (link) {
+ var classes = link.classList
+ var linkKey = `visisted-${link.textContent}`
+ if (localStorage.getItem(linkKey) || classes.contains('current')) {
+ classes.remove('updated-link')
+ localStorage.setItem(linkKey, 'true')
+ } else {
+ classes.add('new')
+ }
+ })
+ }
+
/**
* Mobile burger menu button and gesture for toggling sidebar
*/
@@ -329,7 +374,6 @@
} else {
headers = content.querySelectorAll('h3')
each.call(headers, function (h) {
- console.log(h)
sectionContainer.appendChild(makeLink(h))
allHeaders.push(h)
})
@@ -364,9 +408,16 @@
})
.forEach(makeHeaderClickable)
- smoothScroll.init({
+ new SmoothScroll('a[href*="#"]', {
speed: 400,
- offset: 0
+ speedAsDuration: true,
+ offset: function (anchor, toggle) {
+ let dataTypeAttr = anchor.attributes['data-type']
+ if(dataTypeAttr && dataTypeAttr.nodeValue === 'theme-product-title') {
+ return 300
+ }
+ return 0
+ }
})
}
diff --git a/themes/vue/source/js/smooth-scroll.min.js b/themes/vue/source/js/smooth-scroll.min.js
index d9529950e0..f831786ae2 100644
--- a/themes/vue/source/js/smooth-scroll.min.js
+++ b/themes/vue/source/js/smooth-scroll.min.js
@@ -1,2 +1,2 @@
-/*! smooth-scroll v10.2.1 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */
-!(function(e,t){"function"==typeof define&&define.amd?define([],t(e)):"object"==typeof exports?module.exports=t(e):e.smoothScroll=t(e)})("undefined"!=typeof global?global:this.window||this.global,(function(e){"use strict";var t,n,o,r,a,c,l,i={},u="querySelector"in document&&"addEventListener"in e,s={selector:"[data-scroll]",selectorHeader:null,speed:500,easing:"easeInOutCubic",offset:0,callback:function(){}},d=function(){var e={},t=!1,n=0,o=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(t=arguments[0],n++);for(var r=function(n){for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t&&"[object Object]"===Object.prototype.toString.call(n[o])?e[o]=d(!0,e[o],n[o]):e[o]=n[o])};n
=0&&t.item(n)!==this;);return n>-1});e&&e!==document;e=e.parentNode)if(e.matches(t))return e;return null},m=function(e){"#"===e.charAt(0)&&(e=e.substr(1));for(var t,n=String(e),o=n.length,r=-1,a="",c=n.charCodeAt(0);++r=1&&t<=31||127==t||0===r&&t>=48&&t<=57||1===r&&t>=48&&t<=57&&45===c?"\\"+t.toString(16)+" ":t>=128||45===t||95===t||t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122?n.charAt(r):"\\"+n.charAt(r)}return"#"+a},p=function(e,t){var n;return"easeInQuad"===e&&(n=t*t),"easeOutQuad"===e&&(n=t*(2-t)),"easeInOutQuad"===e&&(n=t<.5?2*t*t:-1+(4-2*t)*t),"easeInCubic"===e&&(n=t*t*t),"easeOutCubic"===e&&(n=--t*t*t+1),"easeInOutCubic"===e&&(n=t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1),"easeInQuart"===e&&(n=t*t*t*t),"easeOutQuart"===e&&(n=1- --t*t*t*t),"easeInOutQuart"===e&&(n=t<.5?8*t*t*t*t:1-8*--t*t*t*t),"easeInQuint"===e&&(n=t*t*t*t*t),"easeOutQuint"===e&&(n=1+--t*t*t*t*t),"easeInOutQuint"===e&&(n=t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t),n||t},g=function(e,t,n){var o=0;if(e.offsetParent)do o+=e.offsetTop,e=e.offsetParent;while(e);return o=Math.max(o-t-n,0),Math.min(o,v()-b())},b=function(){return Math.max(document.documentElement.clientHeight,e.innerHeight||0)},v=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},y=function(e){return e&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(e):{}},O=function(e){return e?f(e)+e.offsetTop:0},S=function(t,n,o){o||(t.focus(),document.activeElement.id!==t.id&&(t.setAttribute("tabindex","-1"),t.focus(),t.style.outline="none"),e.scrollTo(0,n))};i.animateScroll=function(n,o,c){var i=y(o?o.getAttribute("data-options"):null),u=d(t||s,c||{},i),f="[object Number]"===Object.prototype.toString.call(n),h=f||!n.tagName?null:n;if(f||h){var m=e.pageYOffset;u.selectorHeader&&!r&&(r=document.querySelector(u.selectorHeader)),a||(a=O(r));var b,E,I=f?n:g(h,a,parseInt(u.offset,10)),H=I-m,A=v(),j=0,C=function(t,r,a){var c=e.pageYOffset;(t==r||c==r||e.innerHeight+c>=A)&&(clearInterval(a),S(n,r,f),u.callback(n,o))},M=function(){j+=16,b=j/parseInt(u.speed,10),b=b>1?1:b,E=m+H*p(u.easing,b),e.scrollTo(0,Math.floor(E)),C(E,I,l)},w=function(){clearInterval(l),l=setInterval(M,16)};0===e.pageYOffset&&e.scrollTo(0,0),w()}};var E=function(t){var r;try{r=m(decodeURIComponent(e.location.hash))}catch(t){r=m(e.location.hash)}n&&(n.id=n.getAttribute("data-scroll-id"),i.animateScroll(n,o),n=null,o=null)},I=function(r){if(0===r.button&&!r.metaKey&&!r.ctrlKey&&(o=h(r.target,t.selector),o&&"a"===o.tagName.toLowerCase()&&o.hostname===e.location.hostname&&o.pathname===e.location.pathname&&/#/.test(o.href))){var a;try{a=m(decodeURIComponent(o.hash))}catch(e){a=m(o.hash)}if("#"===a){r.preventDefault(),n=document.body;var c=n.id?n.id:"smooth-scroll-top";return n.setAttribute("data-scroll-id",c),n.id="",void(e.location.hash.substring(1)===c?E():e.location.hash=c)}n=document.querySelector(a),n&&(n.setAttribute("data-scroll-id",n.id),n.id="",o.hash===e.location.hash&&(r.preventDefault(),E()))}},H=function(e){c||(c=setTimeout((function(){c=null,a=O(r)}),66))};return i.destroy=function(){t&&(document.removeEventListener("click",I,!1),e.removeEventListener("resize",H,!1),t=null,n=null,o=null,r=null,a=null,c=null,l=null)},i.init=function(n){u&&(i.destroy(),t=d(s,n||{}),r=t.selectorHeader?document.querySelector(t.selectorHeader):null,a=O(r),document.addEventListener("click",I,!1),e.addEventListener("hashchange",E,!1),r&&e.addEventListener("resize",H,!1))},i}));
\ No newline at end of file
+/*! smooth-scroll v15.2.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */
+!(function(t,e){"function"==typeof define&&define.amd?define([],(function(){return e(t)})):"object"==typeof exports?module.exports=e(t):t.SmoothScroll=e(t)})("undefined"!=typeof global?global:"undefined"!=typeof window?window:this,(function(C){"use strict";var L={ignore:"[data-scroll-ignore]",header:null,topOnEmptyHash:!0,speed:500,speedAsDuration:!1,durationMax:null,durationMin:null,clip:!0,offset:0,easing:"easeInOutCubic",customEasing:null,updateURL:!0,popstate:!0,emitEvents:!0},H=function(){var n={};return Array.prototype.forEach.call(arguments,(function(t){for(var e in t){if(!t.hasOwnProperty(e))return;n[e]=t[e]}})),n},r=function(t){"#"===t.charAt(0)&&(t=t.substr(1));for(var e,n=String(t),o=n.length,a=-1,r="",i=n.charCodeAt(0);++ao.durationMax?o.durationMax:o.durationMin&&a=S)return w.cancelScroll(!0),o=e,a=u,0===(n=i)&&document.body.focus(),a||(n.focus(),document.activeElement!==n&&(n.setAttribute("tabindex","-1"),n.focus(),n.style.outline="none"),C.scrollTo(0,o)),Q("scrollStop",c,i,s),!(A=d=null)},O=function(t){var e,n,o;d||(d=t),v+=t-d,f=l+y*(n=r=1<(r=0===E?0:v/E)?1:r,"easeInQuad"===(e=c).easing&&(o=n*n),"easeOutQuad"===e.easing&&(o=n*(2-n)),"easeInOutQuad"===e.easing&&(o=n<.5?2*n*n:(4-2*n)*n-1),"easeInCubic"===e.easing&&(o=n*n*n),"easeOutCubic"===e.easing&&(o=--n*n*n+1),"easeInOutCubic"===e.easing&&(o=n<.5?4*n*n*n:(n-1)*(2*n-2)*(2*n-2)+1),"easeInQuart"===e.easing&&(o=n*n*n*n),"easeOutQuart"===e.easing&&(o=1- --n*n*n*n),"easeInOutQuart"===e.easing&&(o=n<.5?8*n*n*n*n:1-8*--n*n*n*n),"easeInQuint"===e.easing&&(o=n*n*n*n*n),"easeOutQuint"===e.easing&&(o=1+--n*n*n*n*n),"easeInOutQuint"===e.easing&&(o=n<.5?16*n*n*n*n*n:1+16*--n*n*n*n*n),e.customEasing&&(o=e.customEasing(n)),o||n),C.scrollTo(0,Math.floor(f)),b(f,g)||(A=C.requestAnimationFrame(O),d=t)};0===C.pageYOffset&&C.scrollTo(0,0),m=i,h=c,u||history.pushState&&h.updateURL&&history.pushState({smoothScroll:JSON.stringify(h),anchor:m.id},document.title,m===document.documentElement?"#top":"#"+m.id),Q("scrollStart",c,i,s),w.cancelScroll(!0),C.requestAnimationFrame(O)}};var e=function(t){if(!("matchMedia"in C&&C.matchMedia("(prefers-reduced-motion)").matches)&&0===t.button&&!t.metaKey&&!t.ctrlKey&&"closest"in t.target&&(a=t.target.closest(o))&&"a"===a.tagName.toLowerCase()&&!t.target.closest(I.ignore)&&a.hostname===C.location.hostname&&a.pathname===C.location.pathname&&/#/.test(a.href)){var e=r(a.hash),n=I.topOnEmptyHash&&"#"===e?document.documentElement:document.querySelector(e);(n=n||"#top"!==e?n:document.documentElement)&&(t.preventDefault(),(function(t){if(history.replaceState&&t.updateURL&&!history.state){var e=C.location.hash;e=e||"",history.replaceState({smoothScroll:JSON.stringify(t),anchor:e||C.pageYOffset},document.title,e||C.location.href)}})(I),w.animateScroll(n,a))}},n=function(t){if(null!==history.state&&history.state.smoothScroll&&history.state.smoothScroll===JSON.stringify(I)){var e=history.state.anchor;"string"==typeof e&&e&&!(e=document.querySelector(r(history.state.anchor)))||w.animateScroll(e,null,{updateURL:!1})}};return w.destroy=function(){I&&(document.removeEventListener("click",e,!1),C.removeEventListener("popstate",n,!1),w.cancelScroll(),A=M=a=I=null)},w.init=function(t){if(!("querySelector"in document&&"addEventListener"in C&&"requestAnimationFrame"in C&&"closest"in C.Element.prototype))throw"Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.";w.destroy(),I=H(L,t||{}),M=I.header?document.querySelector(I.header):null,document.addEventListener("click",e,!1),I.updateURL&&I.popstate&&C.addEventListener("popstate",n,!1)},w.init(t),w}}));