Migrating from Vue 1.x
Table of Contents
- ##v-for
- v-for Parameter order when traversing an array
-
- ##v-el and v-ref
- ##Transition ##Events
- ##Filter
- Insert filters outside text Insert Slot
- Slot with the same name Special attributes
-
- ##Array.prototype.$set
- Array.prototype.$remove
- Underlying instance methods
- Instance DOM options
- ## Global configuration
- Vue.config.debug
- Global API
I am very happy to tell you that it is not! Almost 90% of the API and core concepts remain unchanged. This section is a bit long because it contains a lot of elaboration and many migration examples. Don't worry,You don't have to read this section from beginning to end!
migration toolWhere should I start project migration?
1. First, run the
under the current project. We've taken great care to simplify the advanced Vue upgrade process to using a simple command line tool. When the tool identifies a legacy feature, it notifies you and makes recommendations, along with links to more information.
2. Then, browse the content listed in the sidebar of this page. If you find that some titles have an impact on your project, but the migration tool does not give a prompt, please check your project.
3. If your project has test code, run it and see where it still fails. If you don't have test code, open your application in a browser, navigate around and pay attention to any errors or warnings.
4. Your application should now be completely migrated. If you're eager to learn more, you can read the rest of this page - or start from the beginning in theIntroductionsection and dive into the new documentation and improved guidance. Many sections have been left out since you are already familiar with some of the core concepts.
How long does it take to migrate a Vue 1.x version application to 2.0?
This depends on several factors:
Depends on the size of your application (small and medium-sized ones can basically be done in one day) .
Depends on how many times you get distracted and start 2.0's coolest new feature.Can't tell the time, this happens often when we build 2.0 applications!
Depends on which old features you use. Most can be upgraded via find-and-replace, but some may take a while. If you don't follow best practices, Vue 2.0 will try its best to force you to follow them. This is good for the long term of the project, but may also mean significant refactoring (although some of the parts that need to be refactored may be obsolete).
If I upgrade to Vue 2, do I also have to upgrade Vuex and Vue Router at the same time?
Only Vue Router 2 is compatible with Vue 2, so Vue Router needs to be upgraded, and you must follow theVue Router migration methodto handle it. Fortunately, most applications don't have a lot of router-related code, so the migration probably won't take more than an hour.
For Vuex, version 0.8 remains compatible with Vue 2, so some parts do not have to be forced to upgrade. The only reason to upgrade now is if you want to take advantage of the new advanced features in Vuex 2, such as modules and reduced boilerplate.
template
Fragment instanceRemove
Each component must have only one root element. Fragment instances are no longer allowed, if you have a template like this:
foo
bar
It's better to simply wrap the entire content into a new element, like this:
foo
bar
Upgrade method
Run the end-to-end test suite (end-to-end test suite) or run the application after the upgrade, and Checkconsole warningsto identify places in the template that have multiple root elements.
Life cycle hook function
##beforeCompile
Remove
createdhook function instead.
Upgrade method
Run themigration toolin the code base to find all functions that use this hook example.
##compiled
replaceUse
hook function instead.
Upgrade methodRun the
migration toolin the code base to find all functions that use this hook example.
attached
RemoveUse the DOM check method built into other hook functions. For example, replace the following:
attached: function () { doSomething() }
can be used like this:
mounted: function () { this.$nextTick(function () { doSomething() }) }
Upgrade methodIn the code base Run the
Migration Tool##detachedRemovedUse the DOM check method in other hook functions. For example, replace the following:
detached: function () { doSomething() }can be used like this:
destroyed: function () { this.$nextTick(function () { doSomething() }) }
In the code base Run theMigration Tool
to find all examples that use this hook function. beforeCreatehook function instead, essentially beforeCreate is exactly the same as init. init was renamed to be consistent with the naming of other lifecycle methods.
Upgrade methodRun the
migration toolin the code base to find all functions that use this hook example.
##readyreplaceUse the newmounted
mounteddoes not guarantee that this.$el in the hook function is in the document.
Vue.nextTick/
vm.$nextTickshould also be introduced for this purpose. For example:
mounted: function () { this.$nextTick(function () { // 代码保证 this.$el 在 document 中 }) }
Run themigration tool
in the code base to find out all uses Example of this hook function.Parameter order when traversing the arrayChange
Whenindex
is included, the order of parameters when traversing the array was
. It's now(value, index)
to be consistent with JavaScript's native array methods (such asforEach
andmap
).
Run themigration toolin the code base to find out which files use the old parameters Example of sequence. Note that if you name your index parameter something unusual (such as
positionornum), the migration tool will not mark them out.
v-for
## Parameter order when traversing the objectChange
(name, value). Now
(value, name), to be consistent with common object iterators (such as lodash).
Upgrade method
Run themigration toolin the code base to find out which files use the old parameters Example of sequence. Note that if you name your key parameters something unusual (such asnameor
property), the migration tool will not mark them out.
$index
and$keyRemoved
$indexand
$keyhave been removed Variables to be explicitly defined in
v-for. This allows developers without much Vue development experience to better read the code and also results in cleaner behavior when dealing with nested loops.
Upgrade method
Run themigration toolin the code base to find out the variables used to remove these example. If you don't find it, you can also look for it inConsole Error(for exampleUncaught ReferenceError: $index is not defined).
##track-by
replacement
has been replaced withkey
which works like other properties withoutv-bind
or:
prefix, it will be treated as a string. In most cases, you will need to replace static keys with dynamic binding with full expressions. For example, to replace:
you should now write:
Upgrade methodin the code base Run the
Migration Tool
in to find examples that usetrack-by.
##v-for
## Range valueChangeBefore, the
number
ofv-for="number in 10"
started from 0 and ended at 9, now it starts from 1 and ends at 10 .
Upgrade methodUse the regular
/\w in \d /
search in the code base. When present inv-for
, please check if it is affected.
##Props
##coerce
Parameters of PropRemove
Check if needed The value of prop creates an internal computed value instead of defining it inside props. For example:
props: { username: { type: String, coerce: function (value) { return value .toLowerCase() .replace(/\s+/, '-') } } }
should now be written as:
props: { username: String, }, computed: { normalizedUsername: function () { return this.username .toLowerCase() .replace(/\s+/, '-') } }
This has some advantages:
You can maintain the operation permissions of the original prop value.
Force developers to use explicit declarations by giving the validated value a different name.
Upgrade method
#twoWay
Prop parametersMove Except
Props can now only be passed in one direction. In order to have a reverse effect on the parent component, the child component needs to explicitly pass an event instead of relying on implicit two-way binding. For details, see:
Custom component event
Run themigration toolto find the instance containing thetwoWayparameter.
##v-bind
## of.onceand.sync
ModifiersRemoved
Props can now only be passed one way. In order to have a reverse effect on the parent component, the child component needs to explicitly pass an event instead of relying on implicit two-way binding. For details, see:
##Upgrade method
RunMigration Tool
Find instances using the .once and
.syncmodifiers.
Modify Props
DeprecatedModify props within the component It's an anti-pattern (not recommended). For example, declare a prop first, and then change the prop's value in the component throughthis.myProp = 'someOtherValue'
. According to the rendering mechanism, when the parent component is re-rendered, the internal prop value of the child component will also be overwritten.
In most cases, changing the prop value can be replaced by the following options:
Through the data attribute, use prop to set the default value of a data attribute.
- Through the computed attribute.
Upgrade method
Run the end-to-end test and view thecontrols on prop modification Station warning message
.
Props for the root instance
ReplacementFor a root For instances (for example: instances created withnew Vue({ ... })
), you can only use
propsDatainstead of
props.
Upgrade method
Run the end-to-end test,failed tests
will pop up to notify you to use The root instance of
propshas expired.
Computed properties
##cache: false
Deprecated
In future major versions of Vue , cache validation for computed properties will be removed. Converting uncached computed properties to methods yields the same results as before.Example:template: 'message: {{ timeMessage }}
', computed: { timeMessage: { cache: false, get: function () { return Date.now() + this.message } } }
Or use component method:template: 'message: {{ getTimeMessage() }}
', methods: { getTimeMessage: function () { return Date.now() + this.message } }
##Upgrade methodRun the
migration tool
and find thecache: falseoption.
##Built-In Command
v-bindTrue/False value
Change##When usingv-bind
in 2.0, only
null,undefined
, andfalse
are considered false . This means that0
and the empty string will be rendered as true values. For example,v-bind:draggable="''"
will be rendered asdraggable="true"
.
For enumeration properties, in addition to the above false values, the string"false"
will also be rendered as
attr="false".
Note that for other hook functions (such as
v-if
and
v-show
), they still follow the general rules of js for judging true and false values. .
Upgrade method
Run end-to-end tests if any part of your app may be affected by this upgrade to, failed tests will pop up
Use
v-onto listen for native eventsChange
Now usingv-onon the component will only listen to custom events (events triggered by the component using
$emit). If you want to listen to the native events of the root element, you can use the.native
modifier, such as:
Upgrade method
Run themigration toolin the code base to find all examples that use this hook function.
v-model
remove
## withdebounce
#Debouncing was once used to control the frequency of Ajax requests and other expensive tasks. The
debounceattribute parameters of
v-modelin Vue make it very easy to achieve this control in some simple cases. But in fact, this is to control the frequency of
status updates, rather than to control the time-consuming task itself. This is a small difference, but will become limiting as your application grows.
For example, limitations when designing a search prompt:
Using the
debounceparameter, you cannot observe the status of "Typing" . Because the input status cannot be detected in real time. However, by decoupling
debouncefrom Vue, we can only delay the operations we want to control, thus avoiding these limitations:
{{ searchIndicator }}
new Vue({ el: '#debounce-search-demo', data: { searchQuery: '', searchQueryIsDirty: false, isCalculating: false }, computed: { searchIndicator: function () { if (this.isCalculating) { return '⟳ Fetching new results' } else if (this.searchQueryIsDirty) { return '... Typing' } else { return '✓ Done' } } }, watch: { searchQuery: function () { this.searchQueryIsDirty = true this.expensiveOperation() } }, methods: { // 这是 debounce 实现的地方。 expensiveOperation: _.debounce(function () { this.isCalculating = true setTimeout(function () { this.isCalculating = false this.searchQueryIsDirty = false }.bind(this), 1000) }, 500) } })
Another advantage of this approach is: When the execution time of the wrapped function is equal to the delay time, it will wait for a long time. For example, when giving search suggestions, you have to wait for the user to stop inputting for a period of time before giving the suggestions, which is a very poor experience. In fact, it is more suitable to use the
throttlingfunction at this time. Since you now have the freedom to use libraries like lodash, you can quickly refactor your project using throttling.
Upgrade Path
Run the
migration toolInstance using thedebounceparameter.
v-model## usinglazy
ornumber
parameters # .Replacement
##lazy
and
numberparameters are now used as modifiers, which makes it look clearer, while Not like this:
Now it’s written like this:
Upgrade method
Runmigration tool
Find these deprecated parameters.
v-model
Remove
# using inlinevalue
This means that the following elements:Having the following in the data option:data: { text: 'bar' }
will render the model as 'bar' instead of 'foo' . Similarly, for the existing value ofmust ensure that the initial value oftextis "hello world"
Upgrade method
Run the end-to-end test after the upgrade, pay attention to
console warnings aboutv-model
inline parameters
##v-model
withv-forIterated Primitive ValuesRemove
Writing like this will not work:
Because
< ;input>will be compiled into js code similar to the following:
strings.map(function (str) { return createElement('input', ...) })
In this way, the two-way binding ofv-modelwill be invalid here. Assigningstr
to another value in the iterator is useless because it is just a variable inside the function.
The alternative is that you can use an object array so that
v-modelcan update the fields in the object synchronously, for example:
Upgrade methodRun the test. If your app is affected by this update, a failed tests prompt will pop up.
##v-bind:styleShift with!important
Except for
, writing like this will be invalid:
hello
If you really need to cover other!important
, it is best to use string form. Write:hello
Upgrade methodRunMigration Help Tool
. Find the style binding object containing!important.
v-el
## andv-refreplace
For simplicity,v-eland
v-refare combined into one
refattribute, which can be used in components In the example, it is called by
$refs. This means
v-el:my-elementwill be written like this:
ref="myElement",
v-ref:my-componentbecomes like this:
ref="myComponent". When bound to a general element,
refrefers to a DOM element. When bound to a component,
refis a component instance.
Becausev-refis no longer an instruction but a special attribute, it can also be defined dynamically. This is useful when combined with
v-for:
formerv-el/
v-refand
v-forused together will produce a DOM array or array of components, since there is no way to give each element a specific name. You can still do this and give every element the same
ref:
Unlike in 1.x,$refsis not responsive because They are registered/updated during rendering. Only listening for changes and rendering repeatedly can make them responsive.
On the other hand, the design$refsis mainly provided for access by js programs, and it is not recommended to rely too much on it in templates. Because this means accessing instance state outside the instance, which goes against the data-driven thinking of Vue.
Upgrade method
Run
migration toolFind outv-el# in the instance ## andv-ref
.
##v-showUse
after v-elseRemove
v-else
can no longer be used afterv-show. Please use
v-showin the negative branch of
v-ifinstead. For example:
Foo
Not foo, but bar
should now be written like this:
Foo
Not foo, but bar
Upgrade method
RunMigration Tools
Find out
v-elseandv-showthat exist in the instance.
Custom instructionsSimplify
In the new version, the use of instructions The scope has been greatly reduced: now the directive is only used for low-level DOM manipulation. In most cases, it's best to use components as an abstraction layer for code reuse.
The significant changes are as follows:
Instructions no longer have instances. Meaning, you no longer have the instance'sthis
in the directive's hook function. Instead, you can accept any data you need in the parameters. If you really need it, you can access the instance viael
.
Similar toacceptStatement
,deep
,priority
, etc. have been deprecated. To replace thebidirectional
directive, seeExample.
Now the meaning of some hooks is different from before, and there are two more hook functions.
Fortunately, the new hook is simpler and easier to master. SeeCustom Instructions Guidefor details.
Upgrade method
Run themigration toolFind out where the directive is defined. The helper tool will mark these places because it is likely that these places need to be refactored.
Directive.literal
ModifierRemove# The
##.literal modifier has been removed. To obtain the same functionality, you can simply provide the string modifier as the value.Example, change as follows:
Just:
##Upgrade methodRun the
Migration Tool
to find out where the `.literal` modifier is used in the instance.
transition
transition
ParameterReplacement
Vue’s transition system has been completely changed , transition effects are now achieved by wrapping elements with
and
instead of using thetransition
attribute. SeeTransitions guidefor details.
Upgrade method
Run themigration toolFind the place where thetransition
attribute is used .
##Reusable transitionVue.transition
Replacement
In the new transition system, you can
reuse transition effectsthrough templates.
Upgrade method
Run the
migration toolFind the place where thetransitionattribute is used .
TransitionalstaggerParameters
Removed
If you wish to use a gradual transition in list rendering, you can control the timing by setting the element's
data-index(or similar attribute). Please refer to
this example.
Upgrade method
Run the
migration toolFind the place where thetransitionattribute is used . During an upgrade, you can "transition" to a new transition strategy.
event
events
OptionRemoved
events
Option is deprecated . Event handlers are now registered in thecreated
hook. Refer to detailed examples$dispatch
and$broadcast
Migration Guide
Vue.directive('on').keyCodes
##Replacement
New concise configuration The way
keyCodesis through
Vue.config.keyCodesFor example:
// v-on:keyup.f1 不可用 Vue.config.keyCodes.f1 = 112
Upgrade method
Run
Migration ToolFind outdatedkeyCodeconfiguration
##$dispatch
## and$broadcastReplacements
$dispatch
and$broadcast
have been deprecated. Please use more concise and clear inter-component communication and better state management solutions, such as:Vuex
.Because the event flow method based on the component tree structure is really difficult to understand, and will become more and more fragile as the component structure expands. This event method is really not good, and we don’t want to cause developers too much pain in the future. And
$dispatch
and$broadcast
do not solve the communication problem between sibling components.
The easiest way to upgrade
$dispatch
and$broadcast
is to use event hubs to allow components to communicate freely, no matter what level they are in the component tree. . Since Vue instances implement an event dispatching interface, you can achieve this by instantiating an empty Vue instance.
One of the most common uses of these methods is for parent-child components to communicate with each other. In these cases, you can use
v-on
Listen for changes to $emit on the child component
. This allows you to easily add event visibility.However, if the communication is across multiple layers of parent-child components,
$emit
is of no use. In contrast, using centralized event middleware allows for simple upgrades. This makes communication between components very smooth, even if they are siblings. Because Vue executes instances through the event emitter interface, you can actually use an empty Vue instance.
For example, suppose we have a todo application structure as follows:
Todos ├─ NewTodoInput └─ Todo └─ DeleteTodoButton
You can manage communication between components through a separate event center:
// 将在各处使用该事件中心 // 组件通过它来通信 var eventHub = new Vue()
Then in the component, you can Use
$emit
,$on
,$off
to distribute, monitor, and cancel listening events respectively:
// NewTodoInput // ... methods: { addTodo: function () { eventHub.$emit('add-todo', { text: this.newTodoText }) this.newTodoText = '' } }
// DeleteTodoButton // ... methods: { deleteTodo: function (id) { eventHub.$emit('delete-todo', id) } }
// Todos // ... created: function () { eventHub.$on('add-todo', this.addTodo) eventHub.$on('delete-todo', this.deleteTodo) }, // 最好在组件销毁前 // 清除事件监听 beforeDestroy: function () { eventHub.$off('add-todo', this.addTodo) eventHub.$off('delete-todo', this.deleteTodo) }, methods: { addTodo: function (newTodo) { this.todos.push(newTodo) }, deleteTodo: function (todoId) { this.todos = this.todos.filter(function (todo) { return todo.id !== todoId }) } }
In a simple case, this is the case Do can replace
$dispatch
and$broadcast
, but for most complex situations it is recommended to use a dedicated state management layer such as:Vuex
.
Upgrade methodRun
Migration tool
Find out how to use$dispatchand Instance of$broadcast
.
filter
Filter outside inserted textRemoved
Now the filter can only be used inside inserted text({{ }}
tags). We found that using filters in directives (eg:v-model
,v-on
, etc.) made things more complicated. For list filters likev-for
it is best to put the processing logic in js as a computed property so that it can be reused throughout the template.
In short, for things that can be implemented in native js, we try to avoid introducing a new symbol to repeatedly deal with the same problem. Here's how to replace Vue's built-in filters:
Replacedebounce
Filter
No longer written like this
methods: { doStuff: function () { // ... } }
Please uselodash'sdebounce
(or maybethrottle
) to directly control high-consuming tasks. You can achieve the above function like this:
methods: { doStuff: _.debounce(function () { // ... }, 500) }
For more advantages of this writing method, see:v-model
Example.
ReplacelimitBy
filter
no longer written like this:
{{ item }}
in Use the js built-in method in the computed attribute:.slice
method:
{{ item }}
computed: { filteredItems: function () { return this.items.slice(0, 10) } }
## replacefilterByFilter
No longer written like this:
{{ user.name }}
Use the js built-in method
.filtermethod
:## in the computed attribute #
{{ user.name }}
computed: { filteredUsers: function () { var self = this return self.users.filter(function (user) { return user.name.indexOf(self.searchQuery) !== -1 }) } }
js native
.filter
can also implement many complex filter operations, because all js methods can be used in computed properties. For example, to find users by matching their names and email addresses (case-insensitive):
var self = this self.users.filter(function (user) { var searchRegex = new RegExp(self.searchQuery, 'i') return user.isActive && ( searchRegex.test(user.name) || searchRegex.test(user.email) ) })
replace the
orderByfilter
Instead of writing:
{{ user.name }}
Instead use
lodash's
orderBy(or maybe
## in the computed attribute #sortBy):
{{ user.name }}
computed: { orderedUsers: function () { return _.orderBy(this.users, 'name') } }
You can even sort by fields:
_.orderBy(this.users, ['name', 'last_login'], ['asc', 'desc'])
Upgrade method
RunMigration Tool
Find the filter used in the directive. If some are not found, look at
Console error messages.
Filter parameter notationChanges
The filter parameter form now works better The method of calling the js function is the same, so there is no need to separate the parameters with spaces:
{{ date | formatDate 'YY-MM-DD' timeZone }}
Now use parentheses and separate them with commas:
{{ date | formatDate('YY-MM-DD', timeZone) }}
Upgrade method
Run themigration toolto find the old calling symbols. If any are missing, please see theconsole error message.
Built-in text filterRemoved
Although the filter inserted inside the text remains Works, but all built-in filters have been removed. Instead, it is recommended to use more specialized libraries for each area. (For example, usedate-fns
to format the date andaccounting
to format the currency).
For each built-in filter, we roughly summarize how to replace it. Code examples may be written in custom helper functions, methods, or computed properties.
Replacejson
Filter
No need to change one by one, because Vue has automatically formatted it for you Okay, whether it's a string, a number, an array, an object. If you want to use theJSON.stringify
function of js to implement it, you can also write it in a method or calculated attribute.
Replacecapitalize
filter
text[0].toUpperCase() + text.slice(1)
Replaceuppercase
filter
text.toUpperCase()
Replacelowercase
filter
text.toLowerCase()
Replacepluralize
filter
Thepluralizelibrary on NPM can achieve this very well Function. If you just want to format specific words into the plural form or want to specify specific output for a specific value ('0'), you can also easily customize the plural formatting filter:
function pluralizeKnife (count) { if (count === 0) { return 'no knives' } else if (count === 1) { return '1 knife' } else { return count + 'knives' } }
Replacing thecurrency
Filter
For simple questions, you can do this:
'$' + price.toFixed(2)
In most cases, still There will be strange phenomena (for example,0.035.toFixed(2)
rounds up to get0.04
, but0.045
rounds down to get0.04
). To solve these problems, you can use theaccounting
library to achieve more reliable currency formatting.
Upgrade method
Runmigration toolFind the discarded filter. If something is missing, please refer toConsole Error Messages.
Bidirectional filterReplacement
Some users have been happy to passv- model
Use bidirectional filters to create interesting inputs with very little code. Although simple on the surface, bidirectional filters can hide some huge complexities—even making status updates sluggish and impacting the user experience. It is recommended to use a component that wraps an input instead, allowing you to create custom inputs in a more explicit and feature-rich way.
Let's now do a two-way exchange rate filter migration as a demonstration:
It basically works well, but delayed status updates can cause weirdness the behavior of. For example, click theResult
tag and try entering9.999
in one of the input boxes. When the input box loses focus, its value will be updated to$10.00
. However when we look at the entire calculator, you will find that the data stored is9.999
. What users see is no longer true synchronization!
To transition to a more robust Vue 2.0 solution, let's first wrap this filter in a new
component:
It allows us to add behaviors that cannot be encapsulated by independent filters, such as selecting the content of the input box focus. Next we extract the business logic from the filter. Next we put everything into an externalcurrencyValidator
object:
This will be more Modularity not only makes migration to Vue 2 easier, but also allows for rate gaps and formatting:
Unit testing independently from your Vue code
Use it in other parts of your application, such as verifying the load of an API end
After extracting this validator, we can also update it Feel comfortable building it into a more robust solution. Those weird states are also eliminated, and users are no longer likely to enter errors, just like the browser's native number input box.
However, in the filters of Vue 1.0, we are still limited, so it is better to completely upgrade to Vue 2.0:
You You may have noticed:
Every aspect of our input box is more explicit, using lifecycle hooks and DOM events to replace the hidden behavior of bidirectional filters.
We can now usev-model
directly in the custom input box. It is not only used with the normal input box, it also means that we The components are Vuex friendly.
Because we no longer require that the filter option must have a return value, our exchange rate work can actually be completed asynchronously. This means that if we have many applications that deal with exchange rates, we can easily refine this logic and make it a shared microservice.
Upgrade method
RunMigration toolFind in exampleExample of using filters in v-model
directive. If you miss it, you should get acommand line error.
##Slot
Slots with duplicate namesRemove
Duplicate names in the same templateDeprecated. Once a slot has been rendered, it cannot be rendered again elsewhere in the same template. If you want to render the same content in different locations, you can use prop to pass it.
Upgrade method
Run the test after the update and check the
console warning messageAbout slots with the same name Tipv-model.
slot
Style parametersRemove
Fragments inserted via namedno longer maintain the parameters of
slot. Please use a wrapping element to control styling. Or take a more advanced approach: modify the content programmatically:
render functions.
Upgrade method
Run
Migration toolFind the select slots tag CSS selector (for example:[slot="my-slot-name"]).
Special attributes
##keep-alive
AttributeReplace
keep-aliveIt is no longer a special attribute but a wrapped component, similar to
For example:
This can be used in subcomponents with multiple states
:
When
contains different sub-components, each sub-component should be affected separately. Not just the first but all child components will be ignored.
When used together with
, make sure to wrap the content:
##Upgrade methodRun the
migration tool
Find thekeep-aliveattribute.
Calculate interpolation
##Computed interpolation inside the attribute
RemovedThe calculated interpolation inside the attribute can no longer be used:
should be written as an inline expression:
or a calculated attribute:
computed: { buttonClasses: function () { return 'btn btn-' + size } }
##HTML calculated interpolation
Remove
HTML computed interpolation ({{{ foo }}}) has been removed and replaced by the
Upgrade method
RunMigration toolFind the HTML to calculate the interpolation.
Single BindingReplace
##Single Binding(
{ {* foo }}) has been replaced by the new
v-oncedirective
.
Upgrade method
Run
Migration toolFind the location where single binding is used.
response
vm.$watch
changed
Passed
Observers created by vm.$watchwill now be activated when the component renders. This allows you to update the state before the component is rendered without making unnecessary updates. For example, you can update the value of the component itself by observing changes in the component's props.
If you used to interact with the DOM after component updates through
vm.$watch, you can now do this through
updatedlife cycle hooks.
Upgrade method
Run the test. If there are observers that depend on the old method, failed tests will pop up.
##vm.$set
Change
vm.$set
is just an alias for
Vue.set.
vm.$delete
##Changevm.$delete
is now just:
Vue.delete
Alias.
Upgrade method
RunMigration tool
Find obsolete usage
Array.prototype.$setDeprecated
Runmigration toolFind theon the array .$set
. If there is anything missing, please refer toConsole Error Message.
##Array.prototype.$remove
Remove
Replace with
Array.prototype.splice, for example:
methods: { removeTodo: function (todo) { var index = this.todos.indexOf(todo) this.todos.splice(index, 1) } }
or better way, remove it directly The method has an index parameter:
methods: { removeTodo: function (index) { this.todos.splice(index, 1) } }
Upgrade method
Run
Migration toolFind the # on the array ##.$remove. If there is anything missing, please refer toConsole Error Message
.
##Vue.setandVue.delete
on the Vue instance Remove
Vue.set
and
Vue.deletewill no longer work on the instance. It is now mandatory to declare all top-level response values in the instance's data option. If you delete an instance attribute or a value on instance
$data, just set it to null.
Upgrade method
RunMigration tool
Find
Vue.set## in the instance # orVue.delete. If there is anything missing, please refer toConsole Error Message
.
##Replace
vm.$data
Remove
Replacement of instance $data is now prohibited. This prevents the response system from some edge cases and makes the component state more controllable and predictable (especially for systems with type checking).
Upgrade method
RunMigration toolFind the coveragevm.$data
s position. If there is anything missing, please refer to
Console Warning Message.
##vm.$get
##removeThe response data can be retrieved directly.
Upgrade methodRun
migration toolFindvm.$getLocation. If there is anything missing, please refer toConsole Error Message
.
Instance methods around the DOM
vm.$appendTo
Remove
Use DOM native method:
myElement.appendChild(vm.$el)
Upgrade methodRun
Migration toolFind # The location of ##vm.$appendTo. If there is anything missing, please refer toConsole Error Message.
##vm.$beforeMove Except
## use DOM native method:
myElement.parentNode.insertBefore(vm.$el, myElement)
Upgrade method
RunMigration ToolFindvm.$before
. If anything is missing, please refer to
Console Error Message.
##vm.$after
Move Except
use DOM native method:
myElement.parentNode.insertBefore(vm.$el, myElement.nextSibling)
If myElement is the last node, you can also write like this:myElement.parentNode.appendChild(vm.$el)
Upgrade method
Runmigration toolFind the location ofvm.$after. If anything is missing, please refer to
Console Error Message
##vm.$remove
remove
Use DOM native method:
vm.$el.remove()
Upgrade method
Run
Migration Toolsfindvm.$remove. If anything is missing, please refer to
Console Error Message.
Underlying instance methods
vm.$eval
Remove
As much as possible Don't use it, if you must use this feature and are not sure how to use it please refer to
the forum.
Upgrade method
Run
Migration toolFind and usevm.$evals position. If there is anything missing, please refer to
Console Error Message.
##vm.$interpolate
shift Try not to use it except##. If you must use this function and are not sure how to use it, please refer tothe forum
.
Upgrade method
Runmigration tool
Find
vm.$interpolate. If there is anything missing, please refer toConsole Error Message.
##vm.$log
Move In addition to
, please useVue Devtoolsto experience the best debugging experience.
Upgrade method
Runmigration toolFind
vm.$log
. If anything is missing, please refer to the console error message.
Instance DOM Options
##replace: false
Remove
Now the component will always Replace the elements they are bound to. To imitate the behavior of
replace: false, you can wrap the root component with an element similar to the element to be replaced:
new Vue({ el: '#app', template: ' ... ' })
or use the rendering function:
new Vue({ el: '#app', render: function (h) { h('div', { attrs: { id: 'app', } }, /* ... */) } })
Upgrade method
Run
Migration toolFind the location wherereplace: falseis used.
Global configuration
##Vue.config.debug
Remove
No longer required, because warning messages will be output in the stack message by default.
Upgrade methodRun
Migration tool
Find the file containingVue.config.debugThe place.
##Vue.config.async## Removed
Asynchronous operations now require rendering performance support.
Upgrade method
##Vue.config.delimiters
## Replace
withtemplate options. This avoids affecting third-party templates when using custom separators.
RunMigration toolFind and useVue.config.delimitersinstance.
##Vue.config.unsafeDelimiters
Remove
HTML interpolation
Upgrade method
Run the
migration toolto findVue.config.unsafeDelimiters. Then the helper tool will also find instances of HTML insertion, which can be replaced with `v-html`.
##Global API
##Vue.extendwithel
remove
el option is not Then use it in
Vue.extend
. Available only in instance creation parameters.
Upgrade methodRun the test after updating and find out about the problem with # in the
console warning message
##Vue.extendofel.
##Vue.elementDirective
Remove
Use components instead
Upgrade method
RunMigration ToolFind the instance containing
Vue.elementDirective
##Vue.partial
##RemovePartials have been removed and replaced with more explicit data flow between components – props. Unless you are using a partially performance-critical area, it is recommended to just use a
normal component
instead. If you are dynamically binding partname, you can usedynamic component
.If you happen to use partials in performance-critical parts of your application, then you should upgrade to
Functional components
. They must be in pure JS/JSX files (not in.vuefiles) and be stateless and instanceless, just like partials. This makes rendering extremely fast.
One benefit of functional components over partials is that they can be more dynamic because they allow you to access the full power of JavaScript. However, this comes at a cost. If you've never used a rendered component framework, it may take you longer to learn them.
Upgrade methodRun
Migration tool
Find the file containingVue.partialExample