diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..09f46ce8c4
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,3 @@
+Note
+====
+This repository is for Vue 1.x and 2.x only. Issues and pull requests related to 3.x are managed in the v3 doc repo: https://github.com/vuejs/docs-next.
diff --git a/.nvmrc b/.nvmrc
deleted file mode 100644
index 988d5e9ef1..0000000000
--- a/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-v8.9.4
\ No newline at end of file
diff --git a/README.md b/README.md
index db4b5ba602..bed7c6049c 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,13 @@
-# vuejs.org
+# v2.vuejs.org
+
+> Important: This repository is for Vue 1.x and 2.x only. Issues and pull requests related to 3.x are managed in the [v3 doc repo](https://github.com/vuejs/docs-next).
This site is built with [hexo](http://hexo.io/). Site content is written in Markdown format located in `src`. Pull requests welcome!
+## Writing
+
+See the [Vue Docs Writing Guide](https://github.com/vuejs/v2.vuejs.org/blob/master/writing-guide.md) for our rules and recommendations on writing and maintaining documentation.
+
## Developing
``` bash
@@ -17,12 +23,20 @@ If you are the maintainer of a community translation fork and would like to depl
## On Translations
-Translation for this documentation project are currently maintained in separate repositories forked from this original one.
+Translations for this documentation project are currently maintained in separate repositories forked from this original one.
+
+### Arabic
+
+Arabic translation is maintained by [Interstellar Club](https://github.com/InterstellarClub)
+
+* Translation Repo - [/interstellarClub/ar.vuejs.org](https://github.com/interstellarClub/ar.vuejs.org)
+* Primary Maintainers :
+ * [Ilyes Chouia](https://github.com/celyes)
+ * [Ahmed Aissaoui](https://github.com/Aissaoui-Ahmed)
### French
French translation is maintained by Vuejs-FR.
-
* Translation Repo - [/vuejs-fr/vuejs.org](https://github.com/vuejs-fr/vuejs.org)
### Italian
@@ -38,6 +52,7 @@ Japanese translation is maintained by [Vue.js japan user group](https://github.c
* Secondary Maintainers:
* [re-fort](https://github.com/re-fort)
* [potato4d](https://github.com/potato4d)
+ * [oohira](https://github.com/oohira)
### Korean
@@ -72,9 +87,25 @@ Russian translation is maintained by Translation Gang.
### Spanish
-Spanish translation is maintained by [1950Labs](https://1950labs.com) and Vue.js Montevideo ([Leonel More](https://twitter.com/leonelmore), [Sebastian Camacho](https://twitter.com/sxcamacho), and [Diana Rodriguez](https://vue.beingadev.rocks).
-
* Translation Repo - [/1950Labs/vuejs.org](https://github.com/1950Labs/vuejs.org)
+* Spanish translation is maintained by:
+
+[1950Labs](https://1950labs.com) & [Vue.js Montevideo](https://www.meetup.com/Montevideo-Vue-JS-Meetup/):
+
+- [Leonel More](https://github.com/leonelmore) | [Twitter](https://twitter.com/leonelmore)
+- [Sebastián Camacho](https://github.com/sxcamacho) | [Twitter](https://twitter.com/sxcamacho)
+- [Diana Rodríguez](https://github.com/alphacentauri82) | [Twitter](https://twitter.com/cotufa82)
+- [Alejandro Parada](https://github.com/alejandro8605)
+- [José Javier Señaris](https://github.com/pepesenaris) | [Twitter](https://twitter.com/pepesenaris)
+- [Federico Kauffman](https://github.com/fedekau) | [Twitter](https://twitter.com/fedekauffman)
+- [Fabián Larrañaga](https://github.com/FLarra) | [Twitter](https://twitter.com/FLarraa)
+- [Pablo Marcano](https://github.com/Pablosky12) | [Twitter](https://twitter.com/stiv_ml)
+- [Nicolás Tinte](https://github.com/Tintef) | [Twitter](https://twitter.com/NicoTinte)
+- [Diego Barreiro](https://github.com/faliure)
+- [Matías Verdier](https://github.com/MatiasVerdier) | [Twitter](https://twitter.com/matiasvj)
+- [Pablo Kz](https://github.com/pabloKz)
+- [Leonardo Fagundez](https://github.com/lfgdzdev) | [Twitter](https://twitter.com/Lfgdz)
+
### Vietnamese
@@ -83,9 +114,15 @@ Vietnamese translation is maintained by [Vue.js Vietnam User group](https://gith
* Translation Repo: [/vuejs-vn/vuejs.org](https://github.com/vuejs-vn/vuejs.org)
* Primary maintainer - [phanan](https://github.com/phanan)
+### Bahasa Indonesia
+
+Bahasa Indonesia translation is maintained by [Vue.js Indonesia](https://github.com/vuejs-id/).
+
+* Translation Repo: [/vuejs-id/docs](https://github.com/vuejs-id/docs)
+
### Want to help with the translation?
-If you feel okay with translating sorta alone, you can fork the repo, create a "work-in-progress" issue to inform others that you're doing the translation, and go for it.
+If you feel okay with translating quite alone, you can fork the repo, post a comment on the [Community Translation Announcements](https://github.com/vuejs/v2.vuejs.org/issues/2015) issue page to inform others that you're doing the translation and go for it.
If you are more of a team player, Translation Gang might be for you. Let us know somehow that you're ready to join this international open-source translators community. Feel free to contact [Grigoriy Beziuk](https://gbezyuk.github.io) or anybody else from [the team](https://github.com/orgs/translation-gang/people).
diff --git a/_config.yml b/_config.yml
index a0ba1bd4c2..38ce868cd3 100644
--- a/_config.yml
+++ b/_config.yml
@@ -1,6 +1,6 @@
# Hexo Configuration
-## Docs: http://zespia.tw/hexo/docs/configuration.html
-## Source: https://github.com/tommy351/hexo/
+## Docs: https://hexo.io/docs/
+## Source: https://github.com/hexojs/hexo
# Site
title: Vue.js
@@ -12,7 +12,7 @@ language:
# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
-url: https://vuejs.org
+url: https://v2.vuejs.org
root: /
permalink: :year/:month/:day/:title/
tag_dir: tags
@@ -29,7 +29,8 @@ new_post_name: :title.md # File name of new posts
default_layout: post
auto_spacing: false # Add spaces between asian characters and western characters
titlecase: false # Transform title into titlecase
-external_link: true # Open external links in new tab
+external_link:
+ enable: true # Open external links in new tab
max_open_file: 100
multi_thread: true
filename_case: 0
@@ -77,9 +78,14 @@ pagination_dir: page
# Disqus
disqus_shortname:
+# Include/Exclude Files/Folders
+exclude:
+## Exclude example code from Nunjucks
+ - "v2/examples/vue-20-*/*"
+
# Extensions
-## Plugins: https://github.com/tommy351/hexo/wiki/Plugins
-## Themes: https://github.com/tommy351/hexo/wiki/Themes
+## Plugins: https://github.com/hexojs/hexo/wiki/Plugins
+## Themes: https://github.com/hexojs/hexo/wiki/Themes
theme: vue
exclude_generator:
@@ -97,49 +103,49 @@ markdown:
# Offline
## Config passed to sw-precache
## https://github.com/JLHwung/hexo-offline
-offline:
- maximumFileSizeToCacheInBytes: 10485760
- staticFileGlobs:
- - public/**/*.{js,html,css,png,jpg,jpeg,gif,svg,eot,ttf,woff,woff2,json,xml}
- stripPrefix: public
- verbose: true
- runtimeCaching:
- # Ad Sources - should be networkFirst
- - urlPattern: /*
- handler: networkFirst
- options:
- origin: sendgrid.sp1.convertro.com
- - urlPattern: /*
- handler: networkFirst
- options:
- origin: ad.doubleclick.net
- # CDNs - should be cacheFirst, since they should be used specific versions so should not change
- - urlPattern: /*
- handler: cacheFirst
- options:
- origin: cdn.jsdelivr.net
- - urlPattern: /*
- handler: cacheFirst
- options:
- origin: fonts.googleapis.com
- - urlPattern: /*
- handler: cacheFirst
- options:
- origin: fonts.gstatic.com
- - urlPattern: /*
- handler: cacheFirst
- options:
- origin: cdnjs.cloudflare.com
- - urlPattern: /*
- handler: cacheFirst
- options:
- origin: maxcdn.bootstrapcdn.com
+# offline:
+# maximumFileSizeToCacheInBytes: 10485760
+# staticFileGlobs:
+# - public/**/*.{js,html,css,png,jpg,jpeg,gif,svg,eot,ttf,woff,woff2,json,xml}
+# stripPrefix: public
+# verbose: true
+# runtimeCaching:
+# # Ad Sources - should be networkFirst
+# - urlPattern: /*
+# handler: networkFirst
+# options:
+# origin: sendgrid.sp1.convertro.com
+# - urlPattern: /*
+# handler: networkFirst
+# options:
+# origin: ad.doubleclick.net
+# # CDNs - should be cacheFirst, since they should be used specific versions so should not change
+# - urlPattern: /*
+# handler: cacheFirst
+# options:
+# origin: cdn.jsdelivr.net
+# - urlPattern: /*
+# handler: cacheFirst
+# options:
+# origin: fonts.googleapis.com
+# - urlPattern: /*
+# handler: cacheFirst
+# options:
+# origin: fonts.gstatic.com
+# - urlPattern: /*
+# handler: cacheFirst
+# options:
+# origin: cdnjs.cloudflare.com
+# - urlPattern: /*
+# handler: cacheFirst
+# options:
+# origin: maxcdn.bootstrapcdn.com
# Deployment
-## Docs: http://zespia.tw/hexo/docs/deployment.html
+## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: git
- repository: git@github.com:vuejs/vuejs.org.git
+ repository: git@github.com:vuejs/v2.vuejs.org.git
feed:
type: atom
diff --git a/_scripts/pre-deploy.js b/_scripts/pre-deploy.js
new file mode 100644
index 0000000000..bf435118ed
--- /dev/null
+++ b/_scripts/pre-deploy.js
@@ -0,0 +1,61 @@
+// udpate to latest built files of Vue
+require('./sync-sponsors')
+
+const fs = require('fs')
+const zlib = require('zlib')
+const axios = require('axios')
+const execSync = require('child_process').execSync
+
+const themeconfPath = 'themes/vue/_config.yml'
+const installPath = 'src/v2/guide/installation.md'
+const themeconfig = fs.readFileSync(themeconfPath, 'utf-8')
+const installation = fs.readFileSync(installPath, 'utf-8')
+
+// get latest Vue version
+console.log(`Checking latest Vue version...`)
+const localVersion = themeconfig.match(/vue_version: (.*)/)[1]
+const version = execSync('npm view vue@v2-latest version').toString().trim()
+
+if (localVersion === version) {
+ console.log(`Version is up-to-date.`)
+ process.exit(0)
+}
+
+console.log(`Latest version: ${version}. Downloading dist files...`)
+
+// replace version in theme config
+fs.writeFileSync(
+ themeconfPath,
+ themeconfig.replace(/vue_version: .*/, 'vue_version: ' + version)
+)
+
+// grab it from unpkg
+Promise.all([download(`vue.js`), download(`vue.min.js`)])
+ .then(([devSize, prodSize]) => {
+ // replace installation page version and size
+ fs.writeFileSync(
+ installPath,
+ installation
+ .replace(/vue_version: .*/, 'vue_version: ' + version)
+ .replace(/gz_size:.*/g, `gz_size: "${prodSize}"`)
+ .replace(/\/vue@[\d\.]+/g, `/vue@${version}`)
+ )
+ console.log(
+ `\nSuccessfully updated Vue version (${version}) and gzip file size (${prodSize}kb).\n`
+ )
+ })
+ .catch((err) => {
+ console.error(err)
+ process.exit(1)
+ })
+
+function download(file) {
+ return axios({
+ url: `http://unpkg.com/vue@${version}/dist/${file}`,
+ method: 'get'
+ }).then((res) => {
+ fs.writeFileSync(`themes/vue/source/js/${file}`, res.data)
+ const zipped = zlib.gzipSync(Buffer.from(res.data))
+ return (zipped.length / 1024).toFixed(2)
+ })
+}
diff --git a/_scripts/sync-sponsors.js b/_scripts/sync-sponsors.js
new file mode 100644
index 0000000000..60c726da62
--- /dev/null
+++ b/_scripts/sync-sponsors.js
@@ -0,0 +1,18 @@
+// sync latest data from sponsor.vuejs.org
+const fs = require('fs')
+const path = require('path')
+const axios = require('axios')
+const yaml = require('js-yaml')
+
+const configPath = path.resolve(__dirname, '../themes/vue/_config.yml')
+
+;(async () => {
+ const { data } = await axios(`https://sponsors.vuejs.org/data.json`)
+ const yml = yaml.dump(data)
+ const config = fs.readFileSync(configPath, 'utf-8')
+ const updated = config.replace(
+ /(# START SPONSORS)[^]*(# END SPONSORS)/,
+ `$1\n${yml}$2`
+ )
+ fs.writeFileSync(configPath, updated)
+})()
diff --git a/assets/why-vue/arabic.js.srt b/assets/why-vue/arabic.js.srt
index 0388f0dd2d..af61b3d07c 100644
--- a/assets/why-vue/arabic.js.srt
+++ b/assets/why-vue/arabic.js.srt
@@ -411,7 +411,7 @@ H2 إلى قائمة غير مرتبة،
94
00:03:57,460 --> 00:03:59,850
-دعنا نلغي العنصر الأخير من المصفوفة
+دعنا نلغي العنصر الأخير من المصفوفة
95
00:03:59,850 --> 00:04:01,828
diff --git a/package.json b/package.json
index 030bfdfb41..b88a44c727 100644
--- a/package.json
+++ b/package.json
@@ -1,32 +1,31 @@
{
- "name": "vuejs.org",
+ "name": "v2.vuejs.org",
"private": true,
"hexo": {
- "version": "3.8.0"
+ "version": "6.2.0"
},
"scripts": {
- "start": "hexo server",
- "build": "node pre-deploy.js && hexo clean && hexo generate",
+ "dev": "node _scripts/sync-sponsors.js && hexo server",
+ "build": "node _scripts/pre-deploy.js && hexo clean && hexo generate",
"deploy": "npm run build && hexo deploy"
},
"engines": {
- "node": ">=8.9.0"
+ "node": ">=14.0.0"
},
"dependencies": {
- "hexo": "^3.6.0",
- "hexo-deployer-git": "0.3.1",
+ "axios": "^0.27.2",
+ "hexo": "^6.2.0",
"hexo-generator-alias": "git+https://github.com/chrisvfritz/vuejs.org-hexo-generator-alias.git",
- "hexo-generator-archive": "^0.1.5",
- "hexo-generator-category": "^0.1.3",
- "hexo-generator-feed": "^1.2.2",
- "hexo-generator-index": "^0.2.1",
- "hexo-generator-tag": "^0.2.0",
- "hexo-offline": "^1.0.0",
- "hexo-renderer-ejs": "^0.3.1",
- "hexo-renderer-marked": "^0.3.0",
- "hexo-renderer-stylus": "^0.3.3",
- "hexo-server": "^0.3.1",
+ "hexo-generator-archive": "^1.0.0",
+ "hexo-generator-category": "^1.0.0",
+ "hexo-generator-feed": "^3.0.0",
+ "hexo-generator-index": "^2.0.0",
+ "hexo-generator-tag": "^1.0.0",
+ "hexo-renderer-ejs": "^2.0.0",
+ "hexo-renderer-marked": "^0.3.2",
+ "hexo-renderer-stylus": "^2.1.0",
+ "hexo-server": "^3.0.0",
"hoek": "^6.1.2",
- "request": "^2.85.0"
+ "js-yaml": "^4.1.0"
}
}
diff --git a/pre-deploy.js b/pre-deploy.js
deleted file mode 100644
index 1abac6b4fa..0000000000
--- a/pre-deploy.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// udpate to latest built files of Vue
-
-const fs = require('fs')
-const zlib = require('zlib')
-const request = require('request')
-const execSync = require('child_process').execSync
-
-const themeconfPath = 'themes/vue/_config.yml'
-const installPath = 'src/v2/guide/installation.md'
-const themeconfig = fs.readFileSync(themeconfPath, 'utf-8')
-const installation = fs.readFileSync(installPath, 'utf-8')
-
-// get latest Vue version
-console.log(`Checking latest Vue version...`)
-const localVersion = themeconfig.match(/vue_version: (.*)/)[1]
-const version = execSync('npm view vue version').toString().trim()
-
-if (localVersion === version) {
- console.log(`Version is up-to-date.`)
- process.exit(0)
-}
-
-console.log(`Latest version: ${version}. Downloading dist files...`)
-
-// replace version in theme config
-fs.writeFileSync(
- themeconfPath,
- themeconfig.replace(/vue_version: .*/, 'vue_version: ' + version)
-)
-
-// grab it from unpkg
-Promise.all([
- download(`vue.js`),
- download(`vue.min.js`)
-]).then(([ devSize, prodSize ]) => {
- // replace installation page version and size
- fs.writeFileSync(
- installPath,
- installation
- .replace(/vue_version: .*/, 'vue_version: ' + version)
- .replace(/gz_size:.*/g, `gz_size: "${prodSize}"`)
- .replace(/\/vue@[\d\.]+\//g, `/vue@${version}/`)
- )
- console.log(`\nSuccessfully updated Vue version and gzip file size.\n`)
-}).catch(err => {
- console.error(err)
- process.exit(1)
-})
-
-function download (file) {
- return new Promise((resolve, reject) => {
- request({
- url: `http://unpkg.com/vue@${version}/dist/${file}`,
- encoding: null
- }, (err, res, body) => {
- if (err) {
- return reject(err)
- }
- if (res.statusCode != 200) {
- return reject(
- `unexpected response code when downloading from unpkg: ${res.statusCode}` +
- `\n${body.toString()}`
- )
- }
- fs.writeFile(`themes/vue/source/js/${file}`, body, err => {
- if (err) return reject(err)
- zlib.gzip(body, (err, zipped) => {
- if (err) return reject(err)
- resolve((zipped.length / 1024).toFixed(2))
- })
- })
- })
- })
-}
diff --git a/src/_posts/common-gotchas.md b/src/_posts/common-gotchas.md
index a8abf2314e..c4ed741291 100644
--- a/src/_posts/common-gotchas.md
+++ b/src/_posts/common-gotchas.md
@@ -15,7 +15,7 @@ Most of the time, when you change a Vue instance's data, the view updates. But t
2. When you modify an Array by directly setting an index (e.g. `arr[0] = val`) or modifying its `length` property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method `arr.$set(index, value)` which is syntax sugar for `arr.splice(index, 1, value)`.
-Further reading: [Reactivity in Depth](/guide/reactivity.html) and [Array Change Detection](http://vuejs.org/guide/list.html#Array-Change-Detection).
+Further reading: [Reactivity in Depth](/guide/reactivity.html) and [Array Change Detection](/guide/list.html#Array-Change-Detection).
### When is the DOM updated?
@@ -33,6 +33,6 @@ Further reading: [Component Option Caveats](/guide/components.html#Component-Opt
All Vue.js templates are valid, parsable HTML markup, and Vue.js relies on spec-compliant parsers to process its templates. However, as specified in the standard, HTML is case-insensitive when matching tag and attribute names. This means camelCase attributes like `:myProp="123"` will be matched as `:myprop="123"`. As a rule of thumb, you should use camelCase in JavaScript and kebab-case in templates. For example a prop defined in JavaScript as `myProp` should be bound in templates as `:my-prop`.
-Further reading: [camelCase vs. kebab-case](http://vuejs.org/guide/components.html#camelCase-vs-kebab-case).
+Further reading: [camelCase vs. kebab-case](/guide/components.html#camelCase-vs-kebab-case).
We are also discussing the possibility of eliminating this inconsistency by resolving props and components in a case-insensitive manner. Join the conversation [here](https://github.com/vuejs/vue/issues/2308).
diff --git a/src/_posts/why-no-template-url.md b/src/_posts/why-no-template-url.md
index f6fbabe2dd..8ffacabbbb 100644
--- a/src/_posts/why-no-template-url.md
+++ b/src/_posts/why-no-template-url.md
@@ -13,8 +13,8 @@ First, it allows us to write our template in a separate HTML file. This gives us
Second, because `templateURL` loads the template via Ajax at runtime, you don't need a build step in order to split up your files. This is convenient during development, but comes at a serious cost when you want to deploy it to production. Before HTTP/2 is universally supported, the number of HTTP requests is still probably the most critical factor in your app's initial load performance. Now imagine you use `templateURL` for every component in your app - the browser needs to perform dozens of HTTP requests before even being able to display anything! In case you don't know, most browsers limit the number of parallel requests it can perform to a single server. When you exceed that limit, your app's initial rendering will suffer for every extra round trip the browser has to wait for. Sure, there are build tools that can help you pre-register all those templates in `$templateCache` - but that shows us a build step is, in fact, inevitable for any serious frontend development.
-So, without `templateURL`, how do we deal with the development experience problem? Writing templates as inline JavaScript strings is terrible, faking templates with `
+
+
+{% endraw %}
diff --git a/src/support-vuejs/index.md b/src/support-vuejs/index.md
index e010c9081d..679571bc4c 100644
--- a/src/support-vuejs/index.md
+++ b/src/support-vuejs/index.md
@@ -1,3 +1,4 @@
---
sponsors: true
+type: sponsors
---
diff --git a/src/v2/api/index.md b/src/v2/api/index.md
index bf5b600a1b..2e073bbcb6 100644
--- a/src/v2/api/index.md
+++ b/src/v2/api/index.md
@@ -246,11 +246,11 @@ type: api
- **See also:** [Async Update Queue](../guide/reactivity.html#Async-Update-Queue)
-### Vue.set( target, key, value )
+### Vue.set( target, propertyName/index, value )
- **Arguments:**
- `{Object | Array} target`
- - `{string | number} key`
+ - `{string | number} propertyName/index`
- `{any} value`
- **Returns:** the set value.
@@ -263,11 +263,11 @@ type: api
- **See also:** [Reactivity in Depth](../guide/reactivity.html)
-### Vue.delete( target, key )
+### Vue.delete( target, propertyName/index )
- **Arguments:**
- `{Object | Array} target`
- - `{string | number} key/index`
+ - `{string | number} propertyName/index`
> Only in 2.2.0+: Also works with Array + index.
@@ -510,12 +510,12 @@ type: api
A list/hash of attributes that are exposed to accept data from the parent component. It has an Array-based simple syntax and an alternative Object-based syntax that allows advanced configurations such as type checking, custom validation and default values.
With Object-based syntax, you can use following options:
- - **type:** can be one of the following native constructors: `String`, `Number`, `Boolean`, `Array`, `Object`, `Date`, `Function`, `Symbol`, any custom constructor function or an array of those. Will check if a prop has a given type, and will throw a warning if it doesn't. [More information](../guide/components-props.html#Prop-Types) on prop types.
- - **default:** `any`
+ - `type`: can be one of the following native constructors: `String`, `Number`, `Boolean`, `Array`, `Object`, `Date`, `Function`, `Symbol`, any custom constructor function or an array of those. Will check if a prop has a given type, and will throw a warning if it doesn't. [More information](../guide/components-props.html#Prop-Types) on prop types.
+ - `default`: `any`
Specifies a default value for the prop. If the prop is not passed, this value will be used instead. Object or array defaults must be returned from a factory function.
- - **required:** `Boolean`
+ - `required`: `Boolean`
Defines if the prop is required. In a non-production environment, a console warning will be thrown if this value is truthy and the prop is not passed.
- - **validator:** `Function`
+ - `validator`: `Function`
Custom validator function that takes the prop value as the sole argument. In a non-production environment, a console warning will be thrown if this function returns a falsy value (i.e. the validation fails). You can read more about prop validation [here](../guide/components-props.html#Prop-Validation).
- **Example:**
@@ -674,16 +674,17 @@ type: api
},
// string method name
b: 'someMethod',
- // deep watcher
+ // the callback will be called whenever any of the watched object properties change regardless of their nested depth
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// the callback will be called immediately after the start of the observation
d: {
- handler: function (val, oldVal) { /* ... */ },
+ handler: 'someMethod',
immediate: true
},
+ // you can pass array of callbacks, they will be called one-by-one
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
@@ -942,7 +943,7 @@ type: api
- **Details:**
- Called when an error from any descendent component is captured. The hook receives three arguments: the error, the component instance that triggered the error, and a string containing information on where the error was captured. The hook can return `false` to stop the error from propagating further.
+ Called when an error from any descendant component is captured. The hook receives three arguments: the error, the component instance that triggered the error, and a string containing information on where the error was captured. The hook can return `false` to stop the error from propagating further.
You can modify component state in this hook. However, it is important to have conditionals in your template or render function that short circuits other content when an error has been captured; otherwise the component will be thrown into an infinite render loop.
@@ -1058,8 +1059,6 @@ type: api
- **Details:**
-
`provide` and `inject` are primarily provided for advanced plugin / component library use cases. It is NOT recommended to use them in generic application code.
-
This pair of options are used together to allow an ancestor component to serve as a dependency injector for all its descendants, regardless of how deep the component hierarchy is, as long as they are in the same parent chain. If you are familiar with React, this is very similar to React's context feature.
The `provide` option should be an object or a function that returns an object. This object contains the properties that are available for injection into its descendants. You can use ES2015 Symbols as keys in this object, but only in environments that natively support `Symbol` and `Reflect.ownKeys`.
@@ -1383,9 +1382,15 @@ type: api
- **Read only**
+- **Reactive?** No
+
- **Details:**
- Used to programmatically access content [distributed by slots](../guide/components.html#Content-Distribution-with-Slots). Each [named slot](../guide/components.html#Named-Slots) has its own corresponding property (e.g. the contents of `slot="foo"` will be found at `vm.$slots.foo`). The `default` property contains any nodes not included in a named slot.
+ Used to programmatically access content [distributed by slots](../guide/components.html#Content-Distribution-with-Slots). Each [named slot](../guide/components.html#Named-Slots) has its own corresponding property (e.g. the contents of `v-slot:foo` will be found at `vm.$slots.foo`). The `default` property contains either nodes not included in a named slot or contents of `v-slot:default`.
+
+ Please note that slots are **not** reactive. If you need a component to re-render based on changes to data passed to a slot, we suggest considering a different strategy that relies on a reactive instance option, such as `props` or `data`.
+
+ **Note:** `v-slot:foo` is supported in v2.6+. For older versions, you can use the [deprecated syntax](../guide/components-slots.html#Deprecated-Syntax).
Accessing `vm.$slots` is most useful when writing a component with a [render function](../guide/render-function.html).
@@ -1393,15 +1398,15 @@ type: api
```html
-
- About Me
-
+
+
About Me
+
Here's some page content, which will be included in vm.$slots.default, because it's not inside a named slot.
-
- Copyright 2016 Evan You
-
+
+
Copyright 2016 Evan You
+
If I have some content down here, it will also be included in vm.$slots.default.
.
@@ -1423,7 +1428,7 @@ type: api
```
- **See also:**
- - [`` Component](#slot-1)
+ - [`` Component](#slot)
- [Content Distribution with Slots](../guide/components.html#Content-Distribution-with-Slots)
- [Render Functions - Slots](../guide/render-function.html#Slots)
@@ -1448,7 +1453,7 @@ type: api
2. All `$slots` are now also exposed on `$scopedSlots` as functions. If you work with render functions, it is now recommended to always access slots via `$scopedSlots`, whether they currently use a scope or not. This will not only make future refactors to add a scope simpler, but also ease your eventual migration to Vue 3, where all slots will be functions.
- **See also:**
- - [`` Component](#slot-1)
+ - [`` Component](#slot)
- [Scoped Slots](../guide/components.html#Scoped-Slots)
- [Render Functions - Slots](../guide/render-function.html#Slots)
@@ -1532,7 +1537,7 @@ type: api
// function
vm.$watch(
function () {
- // everytime the expression `this.a + this.b` yields a different result,
+ // every time the expression `this.a + this.b` yields a different result,
// the handler will be called. It's as if we were watching a computed
// property without defining the computed property itself
return this.a + this.b
@@ -1574,11 +1579,40 @@ type: api
// `callback` is fired immediately with current value of `a`
```
-### vm.$set( target, key, value )
+ Note that with `immediate` option you won't be able to unwatch the given property on the first callback call.
+
+ ``` js
+ // This will cause an error
+ var unwatch = vm.$watch(
+ 'value',
+ function () {
+ doSomething()
+ unwatch()
+ },
+ { immediate: true }
+ )
+ ```
+
+ If you still want to call an unwatch function inside the callback, you should check its availability first:
+
+ ``` js
+ var unwatch = vm.$watch(
+ 'value',
+ function () {
+ doSomething()
+ if (unwatch) {
+ unwatch()
+ }
+ },
+ { immediate: true }
+ )
+ ```
+
+### vm.$set( target, propertyName/index, value )
- **Arguments:**
- `{Object | Array} target`
- - `{string | number} key`
+ - `{string | number} propertyName/index`
- `{any} value`
- **Returns:** the set value.
@@ -1589,11 +1623,11 @@ type: api
- **See also:** [Vue.set](#Vue-set)
-### vm.$delete( target, key )
+### vm.$delete( target, propertyName/index )
- **Arguments:**
- `{Object | Array} target`
- - `{string | number} key`
+ - `{string | number} propertyName/index`
- **Usage:**
@@ -2011,7 +2045,7 @@ type: api
``` html
-
+
```
The default behavior of `v-for` will try to patch the elements in-place without moving them. To force it to reorder elements, you need to provide an ordering hint with the `key` special attribute:
@@ -2166,7 +2200,7 @@ type: api
-
+
@@ -2347,7 +2381,7 @@ type: api
### key
-- **Expects:** `number | string`
+- **Expects:** `number | string | boolean (since 2.4.2) | symbol (since 2.5.12)`
The `key` special attribute is primarily used as a hint for Vue's virtual DOM algorithm to identify VNodes when diffing the new list of nodes against the old list. Without keys, Vue uses an algorithm that minimizes element movement and tries to patch/reuse elements of the same type in-place as much as possible. With keys, it will reorder elements based on the order change of keys, and elements with keys that are no longer present will always be removed/destroyed.
@@ -2484,8 +2518,9 @@ Used to denote a `` element as a scoped slot.
- `name` - string, Used to automatically generate transition CSS class names. e.g. `name: 'fade'` will auto expand to `.fade-enter`, `.fade-enter-active`, etc. Defaults to `"v"`.
- `appear` - boolean, Whether to apply transition on initial render. Defaults to `false`.
- `css` - boolean, Whether to apply CSS transition classes. Defaults to `true`. If set to `false`, will only trigger JavaScript hooks registered via component events.
- - `type` - string, Specify the type of transition events to wait for to determine transition end timing. Available values are `"transition"` and `"animation"`. By default, it will automatically detect the type that has a longer duration.
+ - `type` - string, Specifies the type of transition events to wait for to determine transition end timing. Available values are `"transition"` and `"animation"`. By default, it will automatically detect the type that has a longer duration.
- `mode` - string, Controls the timing sequence of leaving/entering transitions. Available modes are `"out-in"` and `"in-out"`; defaults to simultaneous.
+ - `duration` - number | { `enter`: number, `leave`: number }, Specifies the duration of transition. By default, Vue waits for the first `transitionend` or `animationend` event on the root transition element.
- `enter-class` - string
- `leave-class` - string
- `appear-class` - string
@@ -2561,7 +2596,7 @@ Used to denote a `` element as a scoped slot.
`` serve as transition effects for **multiple** elements/components. The `` renders a real DOM element. By default it renders a ``, and you can configure what element it should render via the `tag` attribute.
- Note every child in a `` must be **uniquely keyed** for the animations to work properly.
+ Note that every child in a `` must be **uniquely keyed** for the animations to work properly.
`` supports moving transitions via CSS transform. When a child's position on screen has changed after an update, it will get applied a moving CSS class (auto generated from the `name` attribute or configured with the `move-class` attribute). If the CSS `transform` property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the [FLIP technique](https://aerotwist.com/blog/flip-your-animations/).
diff --git a/src/v2/cookbook/adding-instance-properties.md b/src/v2/cookbook/adding-instance-properties.md
index 5e18247356..8df1c7eab0 100644
--- a/src/v2/cookbook/adding-instance-properties.md
+++ b/src/v2/cookbook/adding-instance-properties.md
@@ -6,7 +6,7 @@ order: 2
## Base Example
-There may be data/utilities you'd like to use in many components, but you don't want to [pollute the global scope](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md). In these cases, you can make them available to each Vue instance by defining them on the prototype:
+There may be data/utilities you'd like to use in many components, but you don't want to [pollute the global scope](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md). In these cases, you can make them available to each Vue instance by defining them on the prototype:
```js
Vue.prototype.$appName = 'My App'
@@ -58,7 +58,7 @@ new Vue({
})
```
-It would be `"My App"`, then `"The name of some other app"`, because `this.appName` is overwritten ([sort of](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)) by `data` when the instance is created. We scope instance properties with `$` to avoid this. You can even use your own convention if you'd like, such as `$_appName` or `ΩappName`, to prevent even conflicts with plugins or future features.
+It would be `"My App"`, then `"The name of some other app"`, because `this.appName` is overwritten ([sort of](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch5.md)) by `data` when the instance is created. We scope instance properties with `$` to avoid this. You can even use your own convention if you'd like, such as `$_appName` or `ΩappName`, to prevent even conflicts with plugins or future features.
## Real-World Example: Replacing Vue Resource with Axios
diff --git a/src/v2/cookbook/client-side-storage.md b/src/v2/cookbook/client-side-storage.md
index b40f2a633d..915ff798bf 100644
--- a/src/v2/cookbook/client-side-storage.md
+++ b/src/v2/cookbook/client-side-storage.md
@@ -170,7 +170,7 @@ const app = new Vue({
In this application, we've switched to use the Local Storage APIs versus "direct" access. Both work but the API method is generally preferred. `mounted` now has to grab the value and parse the JSON value. If anything goes wrong here we assume the data is corrupt and delete it. (Remember, any time your web application uses client-side storage, the user has access to it and can modify it at will.)
-We have three methods now to handle working with cat. Both `addCat` and `removeCat` handle updating the "live" Vue data stored in `this.cats`. They then run `saveCats` which handles serializing and persisting the data. You can play with this version below:
+We have three methods now to handle working with cats. Both `addCat` and `removeCat` handle updating the "live" Vue data stored in `this.cats`. They then run `saveCats` which handles serializing and persisting the data. You can play with this version below:
diff --git a/src/v2/cookbook/creating-custom-scroll-directives.md b/src/v2/cookbook/creating-custom-scroll-directives.md
index 3d6ea76b84..645ba3eb5c 100644
--- a/src/v2/cookbook/creating-custom-scroll-directives.md
+++ b/src/v2/cookbook/creating-custom-scroll-directives.md
@@ -6,7 +6,7 @@ order: 7
## Base Example
-There are many times that we might want to add a bit of behavior, especially animation, to a scroll event on a site. There are many ways to do so, but the path with the least amount of code and dependencies is perhaps to use a [custom directive](https://vuejs.org/v2/guide/custom-directive.html) to create a hook for anything that fires off a particular scroll event.
+There are many times that we might want to add a bit of behavior, especially animation, to a scroll event on a site. There are many ways to do so, but the path with the least amount of code and dependencies is perhaps to use a [custom directive](/v2/guide/custom-directive.html) to create a hook for anything that fires off a particular scroll event.
```js
Vue.directive('scroll', {
diff --git a/src/v2/cookbook/debugging-in-vscode.md b/src/v2/cookbook/debugging-in-vscode.md
index 68b1c32e4e..5c79d7b6dd 100644
--- a/src/v2/cookbook/debugging-in-vscode.md
+++ b/src/v2/cookbook/debugging-in-vscode.md
@@ -6,7 +6,7 @@ order: 8
Every application reaches a point where it's necessary to understand failures, small to large. In this recipe, we explore a few workflows for VS Code users who would like to debug their application in the browser.
-This recipe shows how to to debug [Vue CLI](https://github.com/vuejs/vue-cli) applications in VS Code as they run in the browser.
+This recipe shows how to debug [Vue CLI](https://github.com/vuejs/vue-cli) applications in VS Code as they run in the browser.
Note: This recipe covers Chrome and Firefox. If you know how to setup VS Code debugging with other browsers, please consider sharing your insights (see bottom of the page).
@@ -41,6 +41,8 @@ module.exports = {
### Launching the Application from VS Code
+
We're assuming the port to be `8080` here. If it's not the case (for instance, if `8080` has been taken and Vue CLI automatically picks another port for you), just modify the configuration accordingly.
+
Click on the Debugging icon in the Activity Bar to bring up the Debug view, then click on the gear icon to configure a launch.json file, selecting **Chrome/Firefox: Launch** as the environment. Replace content of the generated launch.json with the corresponding configuration:

@@ -57,7 +59,7 @@ Click on the Debugging icon in the Activity Bar to bring up the Debug view, then
"webRoot": "${workspaceFolder}/src",
"breakOnLoad": true,
"sourceMapPathOverrides": {
- "webpack:///./src/*": "${webRoot}/*"
+ "webpack:///src/*": "${webRoot}/*"
}
},
{
@@ -81,7 +83,7 @@ Click on the Debugging icon in the Activity Bar to bring up the Debug view, then
2. Open your favorite terminal at the root folder and serve the app using Vue CLI:
```
- npm start
+ npm run serve
```
3. Go to the Debug view, select the **'vuejs: chrome/firefox'** configuration, then press F5 or click the green play button.
diff --git a/src/v2/cookbook/dockerize-vuejs-app.md b/src/v2/cookbook/dockerize-vuejs-app.md
index 12b282dd32..1fc4ed6299 100644
--- a/src/v2/cookbook/dockerize-vuejs-app.md
+++ b/src/v2/cookbook/dockerize-vuejs-app.md
@@ -35,7 +35,7 @@ EXPOSE 8080
CMD [ "http-server", "dist" ]
```
-It may seem reduntant to first copy `package.json` and `package-lock.json` and then all project files and folders in two separate steps but there is actually [a very good reason for that](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/) (spoiler: it allows us to take advantage of cached Docker layers).
+It may seem redundant to first copy `package.json` and `package-lock.json` and then all project files and folders in two separate steps but there is actually [a very good reason for that](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/) (spoiler: it allows us to take advantage of cached Docker layers).
Now let's build the Docker image of our Vue.js app:
@@ -121,7 +121,7 @@ So, delivering our Vue.js app as a Docker image helps reducing, if not removing
### Effects of Continuous Delivery
-By leveraging the [Continuous Delivery](https://martinfowler.com/bliki/ContinuousDelivery.html) discipline we build our software in a way that it can potentially be released to production at any time. Such engineering practice is enabled by means of what is normally called [continuous delivery pipeline](https://martinfowler.com/bliki/DeploymentPipeline.html). The purpose of a continuous delivery pipeline is to split our build into stages (e.g. compilation, unit tests, integration tests, performance tests, etc.) and let each stage verify our build artifact whenever our software changes. Ultimately, each stage increases our confidence in the production readiness of our build artifact and, therefore, reduces the risk of breaking things in production (or any other environment for that matters).
+By leveraging the [Continuous Delivery](https://martinfowler.com/bliki/ContinuousDelivery.html) discipline we build our software in a way that it can potentially be released to production at any time. Such engineering practice is enabled by means of what is normally called [continuous delivery pipeline](https://martinfowler.com/bliki/DeploymentPipeline.html). The purpose of a continuous delivery pipeline is to split our build into stages (e.g. compilation, unit tests, integration tests, performance tests, etc.) and let each stage verify our build artifact whenever our software changes. Ultimately, each stage increases our confidence in the production readiness of our build artifact and, therefore, reduces the risk of breaking things in production (or any other environment for that matter).
So, creating a Docker image for our Vue.js app is a good choice here because that would represent our final build artifact, the same artifact that would be verified against our continuous delivery pipeline and that could potentially be released to production with confidence.
diff --git a/src/v2/cookbook/editable-svg-icons.md b/src/v2/cookbook/editable-svg-icons.md
index 003b127bbd..a1903f5533 100644
--- a/src/v2/cookbook/editable-svg-icons.md
+++ b/src/v2/cookbook/editable-svg-icons.md
@@ -175,7 +175,7 @@ Designers may change their minds. Product requirements change. Keeping the logic
## When To Avoid This Pattern
-This type of SVG icon system is really useful when you have a number of icons that are used in different ways throughout your site. If you're repeating the same icon many times on one page (e.g. a giant table a delete icon in each row), it might make more sense to have all of the sprites compiled into a sprite sheet and use `