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 -

+

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 -

+

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 `