Migrating from Vue 1.x


Table of Contents

  • FAQ

  • Template

  • Lifecycle hook function

    • ##beforeCompile

    • ##compiled

    • attached

    • detached

    • ##init
    • ready
    ##v-for
  • v-for Parameter order when traversing an array
    • v-for Parameter order when traversing an object
    • $index and $key
    • ##track-by

    • v-for range value

    • ##Props
  • Parameters of coerce Prop

  • cache: false

    • ##Built-In directive

  • v-bind true/false value

    • Use v-on to listen to native events

    • v-model with debounce

    • V-model using lazy or number parameters

    • v-model using inline value

    • v-model with v-for Iterated Primitive Values

    • v-bind:style with !important

    • ##v-el and v-ref

    • Use v-else after v-show

  • ##Custom instructions

    • Directive.literal modifier

  • ##Transition

    • transition parameters

    • Reusable transition Vue.transition

    • Transition stagger parameters

  • ##Events
    • events Options
    • Vue.directive('on').keyCodes
    • $dispatch and $broadcast
    ##Filter
  • Insert filters outside text
    • Filter parameter symbols
    • Built-in text filter
    • Bidirectional filter
    Insert Slot
  • Slot with the same name
    • slot style parameter
    Special attributes
  • ##keep-alive attribute

    • Calculated interpolation
  • Computed interpolation inside the attribute

    • HTML calculation interpolation

    • Single binding

    • Response
  • vm.$watch

  • ##Instance methods around the DOM

    • vm.$appendTo

    • ##vm.$before

    • vm.$after

    • ##vm.$remove
  • Underlying instance methods
    • vm.$eval
    • vm.$interpolate
    • vm.$log
  • Instance DOM options
    • replace: false
    ## Global configuration
  • Vue.config.debug
  • ##Vue.extend with el

    • Vue.elementDirective

    • ##Vue.partial

    • ##FAQ


##Wow, a very long one Page! Does it mean that Vue 2.0 is completely different? Do you need to learn it from scratch? Is it impossible to migrate Vue 1.0 projects?

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!


Where should I start project migration?

1. First, run the
migration tool

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



##beforeCompileRemove

Use

createdhook function instead.


##compiledreplaceUse

mounted

hook function instead.

Upgrade methodRun the

migration tool

in the code base to find all functions that use this hook example.


attachedRemoveUse 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

to find all examples that use this hook function.


##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() }) }

Upgrade method

In the code base Run theMigration Tool

to find all examples that use this hook function.


##init#RenameUse the new

beforeCreate

hook function instead, essentially beforeCreate is exactly the same as init. init was renamed to be consistent with the naming of other lifecycle methods.


##readyreplaceUse the newmounted

hook function instead. It should be noted that using

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 中 }) }

Upgrade method

Run themigration tool

in the code base to find out all uses Example of this hook function.


##v-for



v-for

Parameter order when traversing the arrayChangeWhenindex
is included, the order of parameters when traversing the array was

(index, value)

. It's now(value, index)to be consistent with JavaScript's native array methods (such asforEachandmap).

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 index parameter something unusual (such as

position

ornum), the migration tool will not mark them out.


v-for## Parameter order when traversing the objectChange

When the property name/key is included, the parameter order of the previous traversal object is

(name, value). Now(value, name), to be consistent with common object iterators (such as lodash).


$indexand$keyRemoved

The two implicit declarations

$indexand$keyhave been removed Variables to be explicitly defined inv-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 the

migration 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-byreplacement

track-by

has been replaced withkeywhich works like other properties withoutv-bindor: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 PropRemoveCheck 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

Run themigration toolFind out the

An instance of the coerce

option.


#twoWay

Prop parametersMove ExceptProps 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

  • Custom input component

    (Use component Event)
  • Global status management

  • ##Upgrade method

Run themigration toolto find the instance containing thetwoWayparameter.


##v-bind## of.onceand.syncModifiersRemovedProps 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:

  • Custom component event

  • Custom input component

    (Use component Event)

  • Global status management

##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 ofprops.

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: falseDeprecated

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 valueChange##When usingv-bind
in 2.0, only

null

,undefined, andfalseare considered false . This means that0and 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 asv-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-on

to listen for native eventsChangeNow 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.nativemodifier, such as:

Upgrade method

Run themigration toolin the code base to find all examples that use this hook function.


v-modelremove## withdebounce

#Debouncing was once used to control the frequency of Ajax requests and other expensive tasks. The

debounceattribute parameters ofv-modelin Vue make it very easy to achieve this control in some simple cases. But in fact, this is to control the frequency ofstatus 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:

1.gif

Using the

debounceparameter, you cannot observe the status of "Typing" . Because the input status cannot be detected in real time. However, by decouplingdebouncefrom 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## usinglazyornumberparameters # .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-modelRemove# using inlinevalue

##v-modelno longer initializes the initial value inlinevalue. Obviously, it will use the corresponding attribute of the instance's data as the real initial value. .

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 of

must ensure that the initial value of

textis "hello world"

Upgrade method

Run the end-to-end test after the upgrade, pay attention to

console warnings aboutv-modelinline parameters


##v-modelwithv-forIterated Primitive ValuesRemoveWriting 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 of

v-model

will be invalid here. Assigningstrto 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-model

can 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!importantExcept 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 method

RunMigration Help Tool

. Find the style binding object containing

!important.


v-el## andv-refreplace

For simplicity,

v-elandv-refare combined into onerefattribute, which can be used in components In the example, it is called by$refs. This meansv-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.

Because

v-refis no longer an instruction but a special attribute, it can also be defined dynamically. This is useful when combined withv-for:

former

v-el/v-refandv-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 sameref:

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-showUseafter v-elseRemovev-else

can no longer be used after

v-show. Please usev-showin the negative branch ofv-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'sthisin 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 thebidirectionaldirective, 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.literalModifierRemove# 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



transitionParameterReplacement

Vue’s transition system has been completely changed , transition effects are now achieved by wrapping elements withandinstead of using thetransitionattribute. SeeTransitions guidefor details.

Upgrade method

Run themigration toolFind the place where thetransitionattribute is used .


##Reusable transitionVue.transitionReplacement

In the new transition system, you can

reuse transition effectsthrough templates.

Upgrade method

Run the

migration toolFind the place where thetransitionattribute is used .


TransitionalstaggerParametersRemoved

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 tothis 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



eventsOptionRemoved

eventsOption is deprecated . Event handlers are now registered in thecreatedhook. Refer to detailed examples$dispatchand$broadcastMigration Guide


Vue.directive('on').keyCodes##Replacement

New concise configuration The way

keyCodesis throughVue.config.keyCodesFor example:

// v-on:keyup.f1 不可用 Vue.config.keyCodes.f1 = 112

Upgrade method

Run

Migration ToolFind outdatedkeyCodeconfiguration


##$dispatch## and$broadcastReplacements

$dispatch

and$broadcasthave 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$broadcastdo not solve the communication problem between sibling components.The easiest way to upgrade

$dispatch

and$broadcastis 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,$offto 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-forit 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:


ReplacedebounceFilter

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-modelExample.


ReplacelimitByfilter

no longer written like this:

{{ item }}

in Use the js built-in method in the computed attribute:.slicemethod:

{{ 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

orderByfilterInstead 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-fnsto format the date andaccountingto 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.


ReplacejsonFilter

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.stringifyfunction of js to implement it, you can also write it in a method or calculated attribute.


Replacecapitalizefilter

text[0].toUpperCase() + text.slice(1)


Replaceuppercasefilter

text.toUpperCase()


Replacelowercasefilter

text.toLowerCase()


Replacepluralizefilter

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 thecurrencyFilter

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.045rounds down to get0.04). To solve these problems, you can use theaccountinglibrary 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- modelUse 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 theResulttag and try entering9.999in 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 newcomponent:

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 externalcurrencyValidatorobject:

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-modeldirectly 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-modeldirective. If you miss it, you should get acommand line error.


##Slot



Slots with duplicate namesRemove

Duplicate names in the same template

Deprecated. 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.


slotStyle parametersRemove

Fragments inserted via named

no longer maintain the parameters ofslot. 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-aliveAttributeReplace

keep-aliveIt is no longer a special attribute but a wrapped component, similar toFor 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 } }

Upgrade method

RunMigration tool

Find the calculated interpolation inside the attribute


##HTML calculated interpolation

Remove

HTML computed interpolation ({{{ foo }}}) has been removed and replaced by the

v-htmldirective.

Upgrade method

RunMigration toolFind the HTML to calculate the interpolation.


Single BindingReplace

##Single Binding(

{ {* foo }}) has been replaced by the newv-oncedirective.

Upgrade method

Run

Migration toolFind the location where single binding is used.


response



vm.$watchchanged

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 throughupdatedlife cycle hooks.

Upgrade method

Run the test. If there are observers that depend on the old method, failed tests will pop up.


##vm.$setChange

vm.$set

is just an alias forVue.set.

Upgrade methodRun

Migration tool

Find outdated usage


vm.$delete##Changevm.$delete

is now just:

Vue.deleteAlias.

Upgrade method

RunMigration tool

Find obsolete usage


Array.prototype.$setDeprecated

UseVue. setAlternative

Upgrade method

Runmigration toolFind theon the array .$set. If there is anything missing, please refer toConsole Error Message.


##Array.prototype.$removeRemove

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.deleteon the Vue instance RemoveVue.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

RemoveReplacement 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 tool

Findvm.$getLocation. If there is anything missing, please refer toConsole Error Message.


Instance methods around the DOM



vm.$appendToRemove
Use DOM native method:

myElement.appendChild(vm.$el)

Upgrade methodRun

Migration tool

Find # The location of ##vm.$appendTo. If there is anything missing, please refer toConsole Error Message.


##vm.$before

Move 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 Exceptuse 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.$removeremove

Use DOM native method:

vm.$el.remove()

Upgrade method

Run

Migration Toolsfindvm.$remove. If anything is missing, please refer toConsole Error Message.


Underlying instance methods



vm.$evalRemove

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 toConsole Error Message.


##vm.$interpolateshift 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: falseRemove

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.debugRemove
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## RemovedAsynchronous operations now require rendering performance support.

Upgrade method

RunMigration toolFind and use

Vue.config.async

instance.


##Vue.config.delimiters

## Replacewithtemplate options. This avoids affecting third-party templates when using custom separators.

Upgrade method

RunMigration toolFind and useVue.config.delimitersinstance.


##Vue.config.unsafeDelimitersRemove

HTML interpolation

is replaced withv-html.

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.extendwithelremove
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

RemoveUse 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