🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

Overview

Vue logo

Build Status Coverage Status Downloads Version License Chat
Build Status

Supporting Vue.js

Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider:

What's the difference between Patreon and OpenCollective?

Funds donated via Patreon go directly to support Evan You's full-time work on Vue.js. Funds donated via OpenCollective are managed with transparent expenses and will be used for compensating work and expenses for core team members or sponsoring community events. Your name/logo will receive proper recognition and exposure by donating on either platform.

Special Sponsors

Platinum Sponsors

Platinum Sponsors (China)

Gold Sponsors

Sponsors via Open Collective

Platinum

Gold


Introduction

Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. It is designed from the ground up to be incrementally adoptable, and can easily scale between a library and a framework depending on different use cases. It consists of an approachable core library that focuses on the view layer only, and an ecosystem of supporting libraries that helps you tackle complexity in large Single-Page Applications.

Browser Compatibility

Vue.js supports all browsers that are ES5-compliant (IE8 and below are not supported).

Ecosystem

Project Status Description
vue-router vue-router-status Single-page application routing
vuex vuex-status Large-scale state management
vue-cli vue-cli-status Project scaffolding
vue-loader vue-loader-status Single File Component (*.vue file) loader for webpack
vue-server-renderer vue-server-renderer-status Server-side rendering support
vue-class-component vue-class-component-status TypeScript decorator for a class-based API
vue-rx vue-rx-status RxJS integration
vue-devtools vue-devtools-status Browser DevTools extension

Documentation

To check out live examples and docs, visit vuejs.org.

Questions

For questions and support please use the official forum or community chat. The issue list of this repo is exclusively for bug reports and feature requests.

Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

Changelog

Detailed changes for each release are documented in the release notes.

Stay In Touch

Contribution

Please make sure to read the Contributing Guide before making a pull request. If you have a Vue-related project/component/tool, add it with a pull request to this curated list!

Thank you to all the people who already contributed to Vue!

License

MIT

Copyright (c) 2013-present, Yuxi (Evan) You

Comments
  • Make binding syntax more consistent

    Make binding syntax more consistent

    Quick Reference of Latest Syntax

    Last updated: Sep. 11th - 1.0.0-alpha.4

    <!-- flow control -->
    <div v-if="ok">
    <div v-for="item in items">
    <div v-show="hi">
    
    <!-- two-way form binding -->
    <input v-model="abc">
    
    <!-- literal directive: add hash before equal -->
    <a v-link#="/abc/123"></a>
    
    <!-- event handlers -->
     <input
        on-change="handleChange"
        on-focus="handleFocus"
        on-blur="handleBlur">
    
    <!-- key filter for keypress events -->
    <input on-keyup-esc="handleEsc">
    
    <!-- normal attribute bindings, make it reactive by adding "bind-" -->
    <img bind-src="baseURL + '/avatar/' + username + '.png'">
    <a bind-href="'/profile/' + username"></a>
    
    <!-- class & style are enhanced to accept objects and arrays -->
    
    <!-- toggle classes -->
    <div bind-class="{ 'class-a': true, 'class-b': false }"></div>
    <!-- apply a list of classes -->
    <div bind-class="[ dynamicClass, 'literal-class' ]"></div>
    
    <!-- apply style object (camelCase accepted) -->
    <div bind-style="{ fontSize: '14px', color: 'red' }"></div>
    <!-- apply multiple style objects -->
    <div bind-style="[ styleObjectA, styleObjectB ]"></div>
    
    <!-- shorthand for "bind-", just add colon -->
    <img :src="...">
    <a :href="..."></a>
    
    <!-- component props, also use "bind-" or colon shorthand -->
    <!-- without "bind-" or colon it's passed as a literal string -->
    <component
      literal="hello"
      bind-dynamic="parentMsg"
      :dynamic="something"
      :two-way@="something"
      :one-time*="something">
    </component>
    
    <!-- v-el and v-ref now use dedicated syntax -->
    
    <!-- registers vm.$.child -->
    <comp $.child></comp>
    
    <!-- registers vm.$$.node -->
    <div $$.node></div>
    
    <!-- caveat: must use dash-case instead of camelCase, similar to props -->
    <!-- registers vm.$.someComp -->
    <comp $.some-comp></comp>
    

    Context

    Currently we have several types of bindings in the template:

    1. Reactive directives, e.g. v-style, v-on & v-repeat. Their attribute values are directly evaluated as expressions in the current component scope, and cannot contain mustache tags.
    2. (Dynamic) Literal directives, e.g. v-transition, v-ref & v-el. Their attribute values are treated as plain strings and can contain mustache tags - but it's not always reactive: only v-transition is reactive when containing mustache tags; the other two evaluate them only once.
    3. Normal HTML attributes with mustache tags. These are converted into v-attr internally.
    4. Prop bindings, e.g. my-prop="{{abc}}". Props' attribute values are treated as plain strings and can contain mustache tags; the prop binding is only dynamic if it contains mustache tags.
    5. Directive param attributes, e.g. transition-mode, track-by, number & debounce. These are treated almost as normal attributes, but evaluated only once.

    Problem

    Well, as you probably have noticed, it's confusing! There are many types of attributes and there's no clear rule on where expressions are expected and where mustache interpolations are allowed.

    Specifically, the prop syntax could use some improvement. The original intention of making props require mustaches tags to be reactive is so that a dynamic prop can look different from normal HTML attributes. But given that normal attributes can contain mustache tags as well, it's still not explicit enough. It's also much more common to use dynamic props than literal strings, and using mustache tags to indicate reactivity is simply not intuitive.

    Another problem is it becomes awkward when you want to pass a literal number/boolean prop, because without mustache tags, the attribute value is just a string. You'd have to write prop="{{123}}" or prop="{{true}}" to pass a real number or boolean. Currently, Vue auto-casts literal props into numbers/booleans if possible, which this may not always be what we want - what if we want to pass in a string of numbers?

    Proposal

    Last Updated: Sep.11th (1.0.0-alpha.4)

    Here's some pretty radical changes (or maybe not), but imo conceptually much cleaner. The goal here is to 1) eliminate {{ }} inside attribute values; and 2) categorize the syntax by their purpose.

    1. Text and HTML interpolations. Handled with {{ }} and {{{ }}}. And this will also be the only places where mustaches are used.

    2. Vue directives. These preserve the v- prefix because they do something special. Binding values are always parsed as expressions. No more arguments or multiple clauses, just one expression followed by one or more filters. Only v-for (previously v-repeat) preserves the item in items special syntax.

      <!-- view logic -->
      <p v-show="ok"></p>
      <p v-if="!ok"></p>
      <p v-for="item in items"></p>
      
      <!-- two-way binding -->
      <input v-model="val">
      
      <!-- empty directives -->
      <div v-cloak></div>
      <div v-pre></div>
      

      And that's it. Only 6 core directives. (v-text and v-html are also preserved, but they are replaceable by interpolations)

      Literal Syntax

      In 1.0, all core directives are either reactive or empty. But sometimes we may want to pass in a literal string to a custom directive instead of a dynamic expression, similar to 0.12 literal directives. But in 1.0 we want to make this explicit, so we can clearly know whether the attribute value is actually a string or an expression. So, in 1.0 there will no longer be the concept of "literal directives", we use the dot-equal syntax to indicate we are passing a literal value to the directive. The directive's update function will be called once, with the literal string as the argument:

      <a v-link#="/a/b/c">
      
    3. Event handlers. Prefixed with on-. Value always parsed as expressions, can either be the method name or a statement (e.g. a = !a). I've raised this once before, but people seemed to really like the fact that v-on starts with v-. IMO event handlers deserve something different and more succinct.

      <!-- easier to type, and reads better -->
      <form on-submit="handleSubmit"></form>
      
      <!-- multiple listeners also much cleaner -->
      <input
        on-change="handleChange"
        on-focus="handleFocus"
        on-blur="handleBlur">
      
      <!-- in addition: key filter can be replaced with: -->
      <input on-keyup-enter="doThis" on-keyup-esc="doThat">
      
    4. Normal attribute bindings. Currently these are done via putting {{ }} inside attribute values. This often leads to people thinking in a string-template fashion and get confused about where {{ }} are allowed and where not. The proposal is to prefix dynamic attribute bindings with the bind- prefix:

      <!-- plain string -->
      <img src="/avatars/123.png">
      
      <!-- bind to expression -->
      <img bind-src="'/avatars/' + userId + '.png'">
      
      <!-- style/class are enhanced to accept object/array values -->
      <div bind-class="classes"></div>
      <div bind-class="[classA, classB]"></div>
      <div bind-class="{ classA: true, classB: false }"></div>
      
      <div bind-style="cssString"></div>
      <div bind-style="{ fontSize: fontSize, color: currentColor }"></div>
      <div bind-style="[styleObjectA, styleObjectB]"></div>
      

      In addition, the bind- prefix can be shortened as a colon, which is totally optional:

      <img :src="'/avatars/' + userId + '.png'">
      
    5. Props. Similar to normal attribute bindings, non-prefixed props are always passed down as literal strings; To pass a dynamic prop, add bind- or colon prefix.

      Also, binding type indicators are now moved from the attribute value into the attribute name, right before the equal sign.

      <example
        literal="Mike"
        bind-dynamic="someThing"
        bind-onetime*="onlyOnce"
        bind-twoway@="syncsBackUp"
        :shorthand="sameAsBind">
      </example>
      
    6. Special attributes (including both directive params & literal directives). These will only appear together with either a directive or a component. You can also use bind- or colon prefixes for these, but only is, ref, el and transition will have reactive behavior, other directive params are evaluated only once (Vue will tell you in dev mode).

      <component
        :is="view"
        transition="slide"
        transition-mode="out-in">
      </component>
      
    7. Child component and element refs (previously v-ref and v-el) are no longer directives. They now have their own dedicated syntaxes. (see #1292)

    The benefits:

    1. Explicit. The code says what it does.
    2. Simpler. Smaller set of core directives. No more "args" for directives; no more multiple clauses; It's just expressions + filters.
    3. No more confusion about mustache inside attributes. If you see a v-, on- or bind- prefix, it always means the value is an expression. If there's no prefix, then it's a always a plain string!
    4. Eliminates edge cases like src="{{abc}}" causing 404 requests and style="{{something}}" gets thrown away in IE. Also eliminates the need for v-attr.

    Note

    Please don't dislike this proposal just for the sake of "why so many changes"; all the changes proposed here can be implemented in a backwards compatible way in 1.0.0-alpha (with deprecation warnings) and migration should not be unacceptably painful.

    opened by yyx990803 212
  • 2.0 Changes

    2.0 Changes

    This is a live document. Last update: 08/17/2016 as of 2.0.0-rc.2

    General Notes

    • A checked item means it has been implemented in the 2.0 development branch.
    • Features subject to change during development.
    • The breaking change list is not guaranteed to be complete during development.
    • There are some upgrade tips at the end.

    High Level Changes

    • The template parser no longer relies on the DOM (unless you are using the real DOM as your template), so as long as you are using string templates (<script type="text/x-template">, inline JavaScript strings, or compiled via single-file components), you are no longer subject to any of the template parsing limitations in 1.x. However, if you are relying on mounting to an element with existing content as template (using the el option), you will still be subject to those limitations.
    • The compiler (the part which converts a template string to a render function) and the runtime can now be separated. There will be two different builds:
      • Standalone build: includes both the compiler and the runtime. This functions basically exactly the same Vue 1.x does.
      • Runtime only build: since it doesn't include the compiler, you need to either pre-compiled templates in a compile step, or manually written render functions. The npm package will export this build by default, since when consuming Vue from npm, you will likely be using a compilation step (with Browserify or Webpack), during which vueify or vue-loader will perform the template pre-compilation.

    Global config

    • [x] Vue.config.silent
    • [x] Vue.config.optionMergeStrategies
    • [x] Vue.config.devtools
    • [x] Vue.config.errorHandler new - global hook for handling uncaught errors during component render and watchers (default behavior is ~~logging the error stack~~ throwing in place)
    • [x] Vue.config.keyCodes new - configure custom key aliases for v-on.
    • ~~Vue.config.debug~~ deprecated, no longer useful since warnings come with stack traces by default now
    • ~~Vue.config.async~~ deprecated, async is required for rendering performance
    • ~~Vue.config.delimiters~~ reworked as a component-level option
    • ~~Vue.config.unsafeDelimiters~~ deprecated, use v-html

    Global API

    • [x] Vue.extend
    • [x] Vue.nextTick
    • [x] Vue.set
    • [x] Vue.delete
    • [x] Vue.directive
    • [x] Vue.component
    • [x] Vue.use
    • [x] Vue.mixin
    • [x] Vue.compile new (only in standalone build)
    • [x] Vue.transition
      • ~~stagger~~ deprecated, set and access data-index on el instead
    • [x] Vue.filter
    • ~~Vue.elementDirective~~ deprecated, just use components
    • ~~Vue.partial~~ deprecated, use functional components

    Options

    data
    • [x] data
    • [x] props
      • [x] prop validation
      • [x] default value
      • ~~coerce~~ deprecated. If you want to convert a prop, setup a local computed value based on it.
      • ~~prop binding modes~~ deprecated (v-model can work on components)
    • [x] propsData new, instantiation only
    • [x] computed
    • [x] methods
    • [x] watch
    DOM
    • [x] el
    • [x] template
    • [x] render new
    • ~~replace~~ deprecated, components now must have exactly one root element.
    Lifecycle Hooks
    • [x] ~~init~~ beforeCreate
    • [x] created
    • [x] beforeDestroy
    • [x] destroyed
    • [x] beforeMount new
    • [x] mounted new
    • [x] beforeUpdate new
    • [x] updated new
    • [x] activated new (for keep-alive)
    • [x] deactivated new (for keep-alive)
    • [x] ~~ready~~ deprecated, use mounted (there's no longer the guarantee to be in-document)
    • ~~activate~~ deprecated, moved into vue-router
    • ~~beforeCompile~~ deprecated, use created
    • ~~compiled~~ deprecated, use mounted
    • ~~attached~~ deprecated, use custom in-dom check in other hooks
    • ~~detached~~ deprecated, same as above
    Assets
    • [x] directives
    • [x] components
    • [x] transitions
    • [x] filters
    • ~~partials~~ deprecated
    • ~~elementDirectives~~ deprecated
    Misc
    • [x] parent
    • [x] mixins
    • [x] name
    • [x] extends
    • [x] delimiters new, replacing the original global config option. Only available in standalone build.
    • [x] functional new, makes the component stateless and instance-less (just a render function that returns virtual nodes)
    • ~~events~~ deprecated, since no more event propagation

    Instance Properties

    • [x] vm.$data
    • [x] vm.$el
    • [x] vm.$options
    • [x] vm.$parent
    • [x] vm.$root
    • [x] vm.$children
    • [x] vm.$refs
    • ~~vm.$els~~ deprecated, merged with $refs

    Instance Methods

    data
    • [x] vm.$watch
    • ~~vm.$get~~ deprecated, just retrieve values directly
    • ~~vm.$set~~ deprecated, use Vue.set
    • ~~vm.$delete~~ deprecated, use Vue.delete
    • ~~vm.$eval~~ deprecated, no real use
    • ~~vm.$interpolate~~ deprecated, no real use
    • ~~vm.$log~~ deprecated, use devtools
    events
    • [x] vm.$on
    • [x] vm.$once
    • [x] vm.$off
    • [x] vm.$emit
    • ~~vm.$dispatch~~ deprecated, use global event bus or Vuex. (see below)
    • ~~vm.$broadcast~~ deprecated, same as above
    DOM
    • [x] vm.$nextTick
    • ~~vm.$appendTo~~ deprecated, just use native DOM API on vm.$el.
    • ~~vm.$before~~ deprecated
    • ~~vm.$after~~ deprecated
    • ~~vm.$remove~~ deprecated
    Lifecycle
    • [x] vm.$mount
    • [x] vm.$destroy

    Directives

    • [x] v-text
    • [x] v-html but {{{ }}} shorthand has been deprecated
    • [x] v-if
    • [x] v-show
    • [x] v-else
    • [x] v-for
      • [x] key (replacing track-by)
      • [x] Object v-for
      • [x] range v-for
      • [x] argument order updates: (value, index) in arr, (value, key, index) in obj
      • ~~$index and $key~~ deprecated
    • [x] v-on
      • [x] modifiers
      • [x] on child component
      • [x] custom keyCodes (now avaiable via Vue.config.keyCodes instead of Vue.directive('on').keyCodes)
    • [x] v-bind
      • [x] as prop
      • [x] xlink
      • [x] bind object
    • [x] v-bind:style
      • [x] prefix sniffing
    • [x] v-bind:class
    • [x] v-model
      • [x] lazy (as modifier)
      • [x] number (as modifier)
      • [x] ignoring composition events
      • ~~debounce~~ deprecated, use v-on:input + 3rd party debounce function
    • [x] v-cloak
    • [x] v-pre
    • [x] v-once new
    • ~~v-ref~~ now just a special attribute as ref
    • ~~v-el~~ deprecated (merged with ref)

    Special Components

    • [x] <component>
      • [x] :is
      • [x] async components
      • [x] inline-template
    • [x] <transition>
    • [x] <transition-group>
    • [x] <keep-alive>
    • [x] <slot>
    • ~~partial~~ deprecated

    Special Attributes

    • [x] key
    • [x] ref
    • [x] slot

    Server-side Rendering

    • [x] renderToString
    • [x] renderToStream
    • [x] client-side hydration

    Other Breaking Changes

    v-for iteration syntax change

    • Deprecating $index and $key

      Both of these are being deprecated in favor of more explicit named indices and keys. This syntax is a bit magical and has limitations in nested loops. As a bonus, there will be two fewer points of syntax for newcomers to learn.

    • New array syntax

      • value in arr
      • (value, index) in arr (switched order of arguments to be more consistent with JavaScript's forEach and map)
    • New object syntax

      • value in obj
      • (value, key) in obj (switched order of arguments, partly to be more consistent with many common object iterators, such as lodash's)
      • (value, key, index) in obj (index will now be available in object iteration for visual purposes, such as table striping)

    Directive interface change

    In general, in 2.0 directives have a greatly reduced scope of responsibility: they are now only used for applying low-level direct DOM manipulations. In most cases, you should prefer using Components as the main code-reuse abstraction.

    Directives no longer have instances - this means there's no more this inside directive hooks and bind, update and unbind now receives everything as arguments.

    Note the binding object is immutable, setting binding.value will have no effect, and properties added to it will not be persisted. You can persist directive state on el if you absolutely need to:

    <div v-example:arg.modifier="a.b"></div>
    
    // example directive
    export default {
      bind (el, binding, vnode) {
        // the binding object exposes value, oldValue, expression, arg and modifiers.
        binding.expression // "a.b"
        binding.arg // "arg"
        binding.modifiers // { modifier: true }
        // the context Vue instance can be accessed as vnode.context.
      },
    
      // update has a few changes, see below
      update (el, binding, vnode, oldVnode) { ... },
    
      // componentUpdated is a new hook that is called AFTER the entire component
      // has completed the current update cycle. This means all the DOM would
      // be in updated state when this hook is called. Also, this hook is always
      // called regardless of whether this directive's value has changed or not.
      componentUpdated (el, binding, vnode, oldVNode) { ... },
    
      unbind (el, binding, vnode) { ... }
    }
    

    You can use destructuring if you only care about the value:

    export default {
      bind (el, { value }) {
        // ...
      }
    }
    

    In addition, the update hook has a few changes:

    1. It no longer gets called automatically after bind.
    2. It now always gets calls when the component is re-rendered, regardless of whether the value it's bound to has changed or not. You can compare binding.value === binding.oldValue to skip unnecessary updates, but there are also cases where you'd want to always apply updates, e.g. when the directive is bound to an Object that might have been mutated instead of replaced.

    elementDirective, directive params and directive options such as acceptStatement, deep etc. are all deprecated.

    Filter Usage and Syntax Change

    In Vue 2.0, there are several changes to the filter system:

    1. Filters can now only be used inside text interpolations ({{}} tags). In the past we've found using filters with directives such as v-model, v-on etc. led to more complexity than convenience, and for list filtering on v-for it is more appropriate to move that logic into JavaScript as computed properties.

    2. Vue 2.0 will not ship with any built-in filters. It is recommended to use standalone libraries dedicated for solving problems in a specific domain, e.g. moment.js for formatting dates and accounting.js for formatting financial currencies. You are also welcome to create your own filter pack and share it with the community!

    3. The filter syntax has changed to be more inline with JavaScript function invocation, instead of taking space-delimited arguments:

      {{ date | formatDate('YY-MM-DD') }}
      

    Transition System

    Transition CSS class changes:

    The always-on v-transition class is no longer added and Vue now uses the same classes Angular and React CSSTransitionGroup does:

    • v-enter: applied before element is inserted, remove after 1 tick. (starting state for enter)

    • v-enter-active: applied before element is inserted, removed when transition/animation finishes. (active + ending state for enter)

    • v-leave: applied right when the leave transition is triggered, remove after 1 tick (starting state for leave)

    • v-leave-active: applied right when the leave transition is triggered, removed when the transition/animation finishes. (active + ending state for leave)

      v-enter-active and v-leave-active gives you the ability to specify different easing curves for enter/leave transitions. In most cases, upgrading means simply replacing your current v-leavewith v-leave-active. (For CSS animations, use v-enter-active + v-leave-active)

    Transition API Change

    • The <transition> component

      All single-element transition effects are now applied by wrapping the target element/component with the <transition> built-in component. This is an abstract component, which means it does not render an extra DOM element, nor does it show up in the inspected component hierarchy. It simply applies the transition behavior to the wrapped content inside.

      The simplest usage example:

      <transition>
        <div v-if="ok">toggled content</div>
      </transition>
      

      The component defines a number of props and events that maps directly to the old transition definition options:

      Props

      • name: String

        Used to automatically generate transition CSS class names. e.g. name: 'fade' will auto expand to .fade-enter, .fade-enter-active, etc. Defaults to "v".

      • appear: Boolean

        Whether to apply transition on initial render. Defaults to false.

      • css: Boolean

        Whether to apply CSS transition classes. Defaults to true. If set to false, will only trigger JavaScript hooks registered via component events.

      • type: String

        Specify the type of transition events to wait for to determine transition end timing. Available values are "transition" and "animation". By default, it will automatically detect the type that has a longer duration.

      • mode: String

        Controls the timing sequence of leaving/entering transitions. Available modes are "out-in" and "in-out"; defaults to simultaneous.

      • enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String

        Individually configure transition CSS classes.

      Example applying transition to dynamic components:

      <transition name="fade" mode="out-in" appear>
        <component :is="view"></component>
      </transition>
      

      Events

      Corresponds to the JavaScript hooks available in 1.x API.

      • before-enter
      • enter
      • after-enter
      • before-leave
      • leave
      • after-leave
      • before-appear
      • appear
      • after-appear

      Example:

      <transition @after-enter="transitionComplete">
        <div v-show="ok">toggled content</div>
      </transition>
      

      When the entering transition completes, the component's transitionComplete method will be called with the transitioned DOM element as the argument.

      Some notes:

      • leave-cancelled is no longer available for insertion/removals. Once a leave transition starts, it cannot be cancelled. It is, however, still available for v-show transitions.
      • Similar to 1.0, for enter and leave hooks, the presence of cb as the second argument indicates the user wants explicit control of the ending timing of the transition.
    • The <transition-group> component

      All multi-element transition effects are now applied by wrapping the elements with the <transition-group> built-in component. It exposes the same props and events as <transition> does. The difference being that:

      1. Unlike <transition>, <transition-group> renders a real DOM element. By default it renders a <span>, and you can configure what element is should render via the tag prop. You can also use it with the is attribute, e.g. <ul is="transition-group">.
      2. <transition-group> does not support the mode prop.
      3. Every child in a <transition-group> must be uniquely keyed.

      Example:

      <transition-group tag="ul" name="slide">
        <li v-for="item in items" :key="item.id">
          {{ item.text }}
        </li>
      </transition-group>
      

      Moving Transitions

      <transition-group> supports moving transitions via CSS transform. When a child's position on screen has changed after an updated, it will get applied a moving CSS class (auto generated from the name prop or configured with the moveClass prop). If the CSS transform property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the FLIP technique.

      See a live demo here.

    • Creating Reusable Transitions

      Now that transitions are applied via components, they are no longer considered an asset type, so the global Vue.transition() method and the transition option are both deprecated. You can just configure the transition inline with component props and events. But how do we create reusable transition effects now, especially those with custom JavaScript hooks? Well, the answer is creating your own transition components (they are particularly suitable as functional components):

      Vue.component('fade', {
        functional: true,
        render (createElement, { children }) {
          const data = {
            props: {
              name: 'fade'
            },
            on: {
              beforeEnter () { /* ... */ }, // <-- Note hooks use camelCase in JavaScript (same as 1.x)
              afterEnter () { /* ... */ }
            }
          }
          return createElement('transition', data, children)
        }
      })
      

      You can then use it like this:

      <fade>
        <div v-if="ok">toggled content</div>
      </fade>
      

    v-model changes

    • The lazy and number params are now modifiers:

      <input v-model.lazy="text">
      
    • New modifier: .trim - trims the input, as the name suggests.

    • The debounce param has been deprecated. (See upgrade tip at bottom)

    • v-model no longer cares about initial inline value. It will always treat the Vue instance data as the source of truth. This means the following will render with a value of 1 instead of 2:

      data: {
        val: 1
      }
      
      <input v-model="val" value="2">
      

      Same goes for <textarea> with existing content. So instead of:

      <textarea v-model="val">hello world</textarea>
      

      Do:

      data () {
        return {
          val: 'hello world'
        }
      }
      
      <textarea v-model="val"></textarea>
      

      The main idea is that the JS side should be considered the source of truth, not your templates.

    • v-model no longer works when used on a v-for iterated primitive value:

      <input v-for="str in strings" v-model="str">
      

      This doesn't work because it's the equivalent of this in JavaScript:

      strings.map(function (str) {
        return createElement('input', ...)
      })
      

      As you can see, setting str to another value in the iterator function will do nothing because it's just a local variable in the function scope. Instead, you should use an array of objects so that v-model can update the field on the object:

      <input v-for="obj in objects" v-model="obj.str">
      

    Props Behavior

    • .once and .sync are deprecated. Props are now always one-way down. To produce side effects in the parent scope, a component needs to explicitly emit an event instead of relying on implicit binding.
    • Mutating a prop locally is now considered an anti-pattern, e.g. declaring a prop a and then set this.a = someOtherValue in the component. Due to the new rendering mechanism, whenever the parent component re-renders, the child component's local changes will be overwritten. In general, in 2.0 you should treat props as immutable. Most use cases of mutating a prop can be replaced by either a data property or a computed property.

    keep-alive

    keep-alive is no longer a special attribute: it is now a wrapper component, similar to <transition>:

      <keep-alive>
        <component :is="view"></component>
      </keep-alive>
    

    This makes it possible to use keep-alive on multiple conditional children (note the children should eventually evaluate to a single child - any child other than the first one will be ignored):

      <keep-alive>
        <comp-a v-if="a > 1"></comp-a>
        <comp-b v-else></comp-b>
      </keep-alive>
    

    When used together with <transition>, make sure to nest it inside:

      <transition>
        <keep-alive>
          <component :is="view"></component>
        </keep-alive>
      </transition>
    

    Slots

    • It is no longer supported to have duplicate <slot>s with the same name in the same template. When a slot is rendered it is "used up" and cannot be rendered elsewhere in the same render tree.
    • Content inserted via named <slot> no longer preserves the slot attribute. Use a wrapper element to style them, or, for advanced use cases, modify the inserted content programmatically using render functions.

    Refs

    • v-ref is now no longer a directive: it is now a special attribute similar to key and transition:

      <!-- before -->
      <comp v-ref:foo></comp>
      
      <!-- after -->
      <comp ref="foo"></comp>
      

      Dynamic ref bindings are now also supported:

      <comp :ref="dynamicRef"></comp>
      
    • vm.$els and vm.$refs are merged. When used on a normal element the ref will be the DOM element, and when used on a component the ref will be the component instance.

    • vm.$refs are no longer reactive, because they are registered/updated during the render process itself. Making them reactive would require duplicate renders for every change.

      On the other hand, $refs are designed primarily for programmatic access in JavaScript - it is not recommended to rely on $refs in templates because it entails referring to state that does not belong to the instance itself.

    Misc

    • track-by has been replaced with key. It now follows the same rule for binding an attribute: without v-bind: or : prefix, it is treated as a literal string. In most cases you'd want to use a dynamic binding, which expects a full expression instead of a string key. For example:

      <!-- 1.x -->
      <div v-for="item in items" track-by="id">
      
      <!-- 2.0 -->
      <div v-for="item in items" :key="item.id">
      
    • Interpolation inside attributes are deprecated:

      <!-- 1.x -->
      <div id="{{ id }}">
      
      <!-- 2.0 -->
      <div :id="id">
      
    • Attribute binding behavior change: only null, undefined and false are considered falsy when binding attributes. This means 0 and empty strings will render as-is. For enumerated attributes. This means :draggable="''" will render as draggable="true".

      Also, for enumerated attributes, in addition to the falsy values above, the string value of "false" will also render as attr="false".

    • When used on a custom component, v-on now only listens to custom events $emitted by that component. (no longer listens to DOM events)

    • v-else no longer works with v-show - just use negation expression.

    • One time bindings ({{* foo }}) deprecated - use v-once instead.

    • Array.prototype.$set/$remove deprecated (use Vue.set or Array.prototype.splice instead)

    • :style no longer supports inline !important

    • root instance can no longer use template props (use propsData instead)

    • The el option can no longer be used in Vue.extend. It can now only be used as an instance creation option.

    • Vue.set and Vue.delete cannot work on Vue instances. It is now mandatory to properly declare all top-level reactive properties in the data option.

    • It is now also prohibited to replace a component instance's root $data. This prevents some edge cases in the reactivity system and makes the component state more predictable (especially with type-checking systems).

    • User watchers created via vm.$watch are now fired before the associated component re-renders. This gives the user a chance to further update other state before the component re-render, thus avoiding unnecessary updates. For example, you can watch a component prop and update the component's own data when the prop changes.

      To do something with the DOM after component updates, just use the updated lifecycle hook.

    Upgrade Tips

    How to Deal with Deprecation of $dispatch and $broadcast?

    The reason that we are deprecating $dispatch and $broadcast is that event flows that depend on the components tree structure can be hard to reason about when the components tree becomes large (simply put: it doesn't scale well in large apps and we don't want to set you up for pain later). $dispatch and $broadcast also do not solve the communication between sibling components. Instead, you can use a pattern similar to the EventEmitter in Node.js: a centralized event hub that allows components to communicate, no matter where they are in the components tree. Because Vue instances implement the event emitter interface, you can actually use an empty Vue instance for that purpose:

    var bus = new Vue()
    
    // in component A's method
    bus.$emit('id-selected', 1)
    
    // in component B's created hook
    bus.$on('id-selected', this.someMethod)
    

    And don't forget to use $off to unbind the event.

    // in component B's destroyed hook
    bus.$off('id-selected', this.someMethod)
    

    This pattern can serve as a replacement for $dispatch and $broadcast in simple scenarios. But for more complex cases, it is recommended to introduce a dedicated state management layer using Vuex.

    How to Deal with the Deprecation of Array Filters?

    For list filtering with v-for - one of the more common usage of filters - it is now recommended to use computed properties that return a processed copy of the original Array (see updated data grid example). The benefits is that you are no longer limited by the arbitrary filter syntax/API - it's just plain JavaScript now, and you naturally have access to the filtered result because it is a computed property.

    Also see this discussion thread.

    How to Deal with the Deprecation of debounce for v-model?

    Debouncing is used to limit how often we execute Ajax requests and other expensive operations. Vue's debounce attribute parameter for v-model makes this easy, but it also debounces state updates rather than the expensive operations themselves, which comes with limitations.

    These limitations become apparent when designing a search indicator. Take a look at that example. Using the debounce attribute, there'd be no way to detect a dirty input before the search begins, because we'd lose access to the input's real-time state. By decoupling the debounce function from Vue, we're able to debounce only the operation we want to limit.

    There will be other times when debouncing isn't quite the right wrapper function. In the very common example of hitting an API for search suggestions, waiting to offer suggestions until after the user has stopped typing isn't an ideal experience. What you probably want instead is a throttling function. Now since you're already using a utility library like lodash for debounce, refactoring to use throttle instead takes only a few seconds!

    opened by yyx990803 210
  • General FAQ

    General FAQ

    Use this thread for simple, quick questions to avoid cluttering the issue list. Alternatively you can try the #vuejs IRC channel on freenode.

    Also, read the wiki FAQ first.

    opened by yyx990803 170
  • 1.0 binding syntax (discussion thread)

    1.0 binding syntax (discussion thread)

    Note: This post may contain outdated content. Latest reference is now maintained at #1325


    Here's yet another long post on the new binding syntax. I know we have gone through a lot of changes during the alpha phase, but please, bear with me - I want to make sure we land on something that is good enough to be called a 1.0 - something that is consistent, explicit, and most importantly, stable. We are going to strictly follow semver post 1.0 - I don't want to have to release 2.0 in a few months ;)

    I've been thinking about all the discussion on consistent v-, and I feel that the new syntax may indeed be a bit too different from what we have in 0.12. Some of the justifications about the additional prefixes was based on the fact that Angular 2 and Aurelia are both introducing custom syntax for bindings; but then I realize Vue is not Angular or Aurelia, because these two are full-stack frameworks, where Vue aims to be flexible in as many use cases as possible.

    So, let's take a step back and think about the original problems that we set out to solve with the new syntax, and evaluate what we have so far:

    1. Confusion about expressions vs. literals for directives

      Example:

      <div v-text="msg"></div>
      <div v-link="/a/b/c"></div>
      

      Here msg is an expression but a/b/c is a literal string. There's no way to tell which should be literal except looking at the directive's documentation.

      Current solution in alpha.4:

      Explicit syntax for literal directives: v-link#="123". This also simplifies implementation of custom directives. I think this is a good change.

    2. Confusion about where mustaches are allowed.

      Example:

      <!-- these works... -->
      <a v-link="/a/b/{{abc}}"></a>
      <a href="/a/b/{{abc}}"></a>
      
      <!-- these don't -->
      <a v-model="{{abc}}">
      <a v-attr="href: 'a/b/{{abc}}'">
      

      The general rule is that mustaches are only allowed in literal strings but not in expressions. But mustaches just make people think in the string template mindset and assume it should work everywhere.

      In addition, mustaches inside attributes have some subtle gotchas, for example when used in src it causes a 404 error; when used in style it causes IE to ignore it.

      Current solution in alpha.4:

      No more mustaches inside attribute values. Attribute bindings use the bind- special prefix.

      As someone pointed out, this introduces an additional prefix and isn't as distinctive and consistent as v-. But v-attr also has its own warts, mostly related to the "arguments + multiple clauses" micro-syntax. We will discuss this in more details below.

    3. Directive micro-syntax

      Example:

      <div v-on="click: doThis, keyup: doThat"></div>
      <div v-attr="href: address, src: imgSrc"></div>
      

      The problem here is that it looks like an object, but it is not; it also becomes awkward to format (different indentation, no syntax highlight) when you have a lot of handlers/attributes:

      <div
        other-attribute-a
        other-attribute-b
        v-on="
          click: doThis,
          keyup: doThat | key 'esc',
          keyup: doSomethingElse | key 'enter'">
      

      Current Solution in alpha.4:

      <div
        bind-href="address"
        bind-src="imgSrc"
        on-click="doThis"
        on-keyup-esc="doThat"
        on-keyup-enter="doSomethingElse">
      </div>
      

      I think breaking each binding into a single attribute is definitely the right move. But we also introduced yet another prefix: on-.

    4. Not-so-good prop syntax.

      Example:

      <component
        literal="string"
        dynamic="{{something}}"
        two-way="{{@something}}"
        one-time="{{*something}}">
      </component>
      

      First, this looks like normal attribute bindings. Second, as we noted above, mustache bindings indicates that it evaluates into a literal string. However, the 0.12 prop syntax is ambiguous in this aspect:

      <component prop="{{ anObject }}">
      

      ^ This passes down the actual object.

      <component prop="abc-{{ anObject }}">
      

      ^ This will try to concatenate "abc-" and the object, resulting in "abc-[object Object]".

      The binding indicator can also be confusing:

      <!-- what does this do? -->
      <component prop="abc-{{@something}}">
      

      Current Solution in alpha.4:

      <component
        literal="string"
        bind-dynamic="something"
        bind-two-way@="something"
        bind-one-time*="something">
      

      By getting rid of mustaches and move the binding type indicator into the attribute name, I think we've solved most of the issues above, but it relies on the extra bind- prefix.


    Recap

    I think with the current 1.0.0-alpha.4 syntax we've addressed most of the original issues, but also introduced some new ones. Most of the negative feedback is concerned with the fact that we now have three prefixes instead of one: v-, on- and bind-. Do event handlers and attribute bindings really deserive their own special prefix?

    My original intention was that on- and bind- would allow us to get rid of the "micro-syntax" issue mentioned above. But I also agree that more top-level prefixes also introduce additional cognitive overhead. So here's an update that attempts to address this issue:

    <!-- 0.12 directive syntax -->
    <div v-dirname="arg1: expression1, arg2: expression2"></div>
    
    <!-- 1.0 directive syntax -->
    <div
      v-dirname:arg1="expression1"
      v-dirname:arg2="expression2">
    <div>
    

    So, instead of what we currently have in 1.0.0-alpha.4:

    <div
      bind-href="address"
      bind-src="imgSrc"
      on-click="doThis"
      on-keyup-esc="doThat">
    </div>
    

    We would write:

    <div
      v-bind:href="address"
      v-bind:src="imgSrc"
      v-on:click="doThis"
      v-on:keyup:esc="doThat">
    </div>
    

    A little more verbose, but more consistent, more Vue-specific, and maps to 0.12 concepts better.

    When we are using Vue alone to build an SPA, the v- prefix may not be that important anymore. So it is still possible to provide optional, more concise sugar on top of v-bind and v-on:

    <!-- : for bind -->
    <div
      :href="address"
      :src="imgSrc">
    </div>
    
    <!-- @ for on -->
    <input
      @click="doThis"
      @keyup:esc="doThat">
    

    You probably would prefer the shorthand for component props as well (changing two-way indicator to & instead of @):

    <component
      :prop="something"
      :two-way&="something"
      :one-time*="something">
    </component>
    
    opened by yyx990803 137
  • Typescript and Vue in general

    Typescript and Vue in general

    I have a small problem; I'm in love with two things at the same time: Typescript and Vue. I tried a handfull different approaches to make them work together; using TS modules and/or classes with public/private/static properties to shim vue components is the best i got. I love the intelisense, autocompletion and error hints i get by doing so! But after all it is kind of hacky.

    I wanted to ask you what you think about Typescript? Do you think it is possible to bring them togeher in a more natural way? Maybe refactoring some parts of your extend routine (to make some of its internals reachable from a typescript construtor) could make a huge difference.

    contribution welcome 
    opened by indus 127
  • [Suggestion] Vue 2.0 - Bring back filters please

    [Suggestion] Vue 2.0 - Bring back filters please

    Hi,

    There was a hot discussion in the Gitter chat and there is a nice post on the forum about people missing the filter feature in 2.0 and it actually being a no-go to upgrading for some. This isn't a positive direction for the community it seems.

    So, I'd like to put up this suggestion to bring back filters in 2.0, because they are so loved and, I would agree, smart. Here are some of the arguments for filters (gathered from the different discussions and no guarantee for correctness):

    • They are easier to read in the templates

    thing in things | filterBy 'foo' | orderBy 'bar' | limitBy 5

    is simply easy to read. In other words, chaining filters helps make sense of what should actually be expected.

    • Filters are global, which is great in a templating/ view system. Currency is a simple example of a great filter that can be used everywhere, just by calling it.
    • Without filters, there will be a ton of boilerplate.
    • Filters allow noobs to learn faster and get a quick and nice winning experience with Vue.
    • Using a mixin for every component to include a self-made "filter" isn't really feasible.

    Needless to say, there are probably strong arguments for removing filter from an engineering perspective and why I would suggest this thread be a pros and cons and voting for or against the return of filters.

    Scott

    discussion 
    opened by smolinari 116
  • roadmap

    roadmap

    Core

    • v0.9.x: Animation and Transition ✓
    • v0.10.x: API and internal improvements ✓
    • v0.11.x: Consolidate API for future specs ✓
    • v0.12.x: Improve API to make it easier to ship standalone, reusable components and build larger-scale applications.

    Tooling

    • Chrome dev tools extension ✓
    • CSP-compliant build ✓ (See csp branch)
    • CommonJS-based build setup ✓
      • Browserify + Vueify ✓
      • Webpack + vue-loader ✓
        • Scoped CSS (WIP)
    • Server-side rendering
    • Starter Kit

    Plugins

    Please discuss plugin specific topics in each plugin's respective repo. The general philosophy for these plugins is to be light, self-contained, and most importantly avoid reinventing the wheel. Build on top of solid low level solutions and mostly just make them Vue-friendly.

    Community

    • Calling for user-contributed examples for tutorials!
    • Open for blog post submissions once the blog is set up
    important 
    opened by yyx990803 88
  • 希望keep-alive能增加可以动态删除已缓存组件的功能

    希望keep-alive能增加可以动态删除已缓存组件的功能

    What problem does this feature solve?

    我在使用vue做单页应用时,在多个功能切换的时候,希望能达到动态创建tab进行切换的效果,和以前使用iframe一样,这些tab是keep-alive的,但如果太多keep-alive的时候,浏览器内存占用会过大。我希望能够达到可切换的tab最多例如只有十个,前面的我会用程序自动关闭对应tab,此时希望能把其缓存的组件也对应清除。

    What does the proposed API look like?

    例如:vm.$clearKeepAlived(routerName)

    feature request 
    opened by okjesse 69
  • is there any plan for

    is there any plan for "vue-native"?

    Hi @yyx990803 Thanks for your great work.. I enjoy Vue so far. This question just across my head, is there any way or do you have plan to bridge Vue to React-Native?

    Thanks again

    opened by ferry77 67
  • [feature] Ability to disable Vue observation

    [feature] Ability to disable Vue observation

    Update: If anyone ends up needing this functionality, I've released it as vue-nonreactive with the appropriate admonitions and everything.


    We have some non-plain models where we need to disable Vue's observation and walking. An example is a resource model that has access to a cache so that it can lookup related resources. This causes all of the objects in the cache to become watched (probably inefficient), as well as some additional interactions with other code. Currently, we get around this by setting a dummy Observer on the cache. Something similar to...

    import get from 'http';
    import Resource from 'resource';
    
    
    new Vue({
        data: { instance: {}, },
        ready() { this.fetch(); },
    
        methods: {
            fetch() {
                const Observer = Object.getPrototypeOf(this.instance.__ob__).constructor;
    
                get('/api/frobs')
                .then(function(data) {
                    // initialize Resource w/ JSON document
                    const resource = new Resource(data);
    
                    // Protect cache with dummy observer
                    resource.cache.__ob__ = new Observer({});
    
                    this.instance = resource;
                });
            },
        },
    });
    

    This does work, but

    • relies on vue's internals
    • requires an already observed object since we cannot import the Observer class directly.

    Proposal: Add an official method for explicitly disabling Vue's observation/walking. eg, something like...

    const someThing = {
      nestedThing: {},
    };
    
    // make entire object non-reactive
    Vue.nonreactive(someThing);
    
    // make nested object non-reactive
    Vue.nonreactive(someThing.nestedThing);
    vm.$set('key.path', someThing);
    

    Considerations:

    • What should happen if a user set a reactive key path to an non-reactive object? Should vue warn the user? eg,

      vm.$set('a', Vue.nonreactive({});
      
      // different from..
      vm.$set('a', {
          someKey: Vue.nonreactive({}),
      });
      
    • Should an already reactive object warn the user if attempted to be made non-reactive? eg,

    // error
    Vue.nonreactive(vm.$data.a)
    
    // valid
    Vue.nonreactive(_.clone(vm.$data.a));
    
    opened by rpkilby 64
  • Optional chaining in templates does not seem to work

    Optional chaining in templates does not seem to work

    Version

    15.8.3

    Reproduction link

    https://template-explorer.vuejs.org/#%3Cdiv%20id%3D%22app%22%20v-if%3D%22obj%3F.a%22%3E%7B%7B%20msg%20%7D%7D%3C%2Fdiv%3E

    Steps to reproduce

    Use a v-if that uses optional chaining w/ @vue/cli version 4.2.0:

    v-if="test?.length > 0"

    What is expected?

    no error is thrown

    What is actually happening?

    following error is thrown:

      Errors compiling template:
    
      invalid expression: Unexpected token '.' in
    
        test?.length > 0
    
      Raw expression: v-if="test?.length > 0"
    
    contribution welcome feature request 
    opened by DRoet 63
  • Firefox 102.6.0 ESR addEventListener not properly works

    Firefox 102.6.0 ESR addEventListener not properly works

    Version

    2.7.14

    Reproduction link

    codepen.io

    Steps to reproduce

    1. Open example: https://codepen.io/zhymabekroman/pen/MWvVByG
    2. Start entering number 7 in the input box

    What is expected?

    The input box should display the formatted phone number in the format: +7 (777) 777-77-77-77 In Chrome based browsers (tested in Edge 109.0.1518.26 beta) this works properly

    What is actually happening?

    Firefox doesn't format numbers, just show: 777777777777777777


    I don't know what the problem is exactly, maybe it's a problem with Firefox, but I still want to report the problem. Related issue (maybe): https://github.com/vuejs/vue/issues/9446.

    If disable vue's events in Firefox dev tool, phone formatting being properly works: Screenshot_20230104_083915

    And sorry for my English.

    opened by ZhymabekRoman 0
  • refactor(compiler): add stack type instead of any

    refactor(compiler): add stack type instead of any

    What kind of change does this PR introduce? (check at least one)

    • [ ] Bugfix
    • [ ] Feature
    • [ ] Code style update
    • [ ] Refactor
    • [ ] Build-related changes
    • [x] Other, please describe: add type description

    Does this PR introduce a breaking change? (check one)

    • [ ] Yes
    • [x] No

    If yes, please describe the impact and migration path for existing applications:

    The PR fulfills these requirements:

    • [ ] It's submitted to the main branch for v2.x (or to a previous version branch)
    • [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)
    • [ ] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
    • [ ] New/updated tests are included

    If adding a new feature, the PR's description includes:

    • [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

    Other information:

    opened by FireBushtree 0
  • activated lifehook is not called in async component

    activated lifehook is not called in async component

    Version

    2.7.14

    Reproduction link

    codesandbox.io

    Steps to reproduce

    Click "add key" and "decrease key", or just wait 10s.

    The activated lifehook behaved different in async component, sync component and dynamic component.

    What is expected?

    Activated lifehook is called in async component,

    or just behave in the same way.

    What is actually happening?

    When using async component, activated lifehook is not called when loaded for the first time.

    When using dynamic component, activated lifehook is never called after mounted.

    opened by MuffinK 0
  • chore: add prettier cache

    chore: add prettier cache

    What kind of change does this PR introduce? (check at least one)

    • [ ] Bugfix
    • [ ] Feature
    • [ ] Code style update
    • [ ] Refactor
    • [ ] Build-related changes
    • [ ] Other, please describe:

    Does this PR introduce a breaking change? (check one)

    • [ ] Yes
    • [ ] No

    If yes, please describe the impact and migration path for existing applications:

    The PR fulfills these requirements:

    • [ ] It's submitted to the main branch for v2.x (or to a previous version branch)
    • [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)
    • [ ] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
    • [ ] New/updated tests are included

    If adding a new feature, the PR's description includes:

    • [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

    Other information:

    opened by Simon-He95 0
  • fix(compiler-sfc): fix rewriteDefault problem when using @babel/parser@^7.20.0

    fix(compiler-sfc): fix rewriteDefault problem when using @babel/parser@^7.20.0

    close https://github.com/vuejs/vue/issues/12892

    https://github.com/babel/babel/pull/15032 change the location of the export declaration when use decorators before export

    opened by linshuohao 0
  • fix(patch): clone insert hooks to avoid being mutated during iteration

    fix(patch): clone insert hooks to avoid being mutated during iteration

    What kind of change does this PR introduce? (check at least one)

    • [x] Bugfix
    • [ ] Feature
    • [ ] Code style update
    • [ ] Refactor
    • [ ] Build-related changes
    • [ ] Other, please describe:

    Does this PR introduce a breaking change? (check one)

    • [ ] Yes
    • [x] No

    If yes, please describe the impact and migration path for existing applications:

    The PR fulfills these requirements:

    • [x] It's submitted to the main branch for v2.x (or to a previous version branch)
    • [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)
    • [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
    • [x] New/updated tests are included

    If adding a new feature, the PR's description includes:

    • [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

    Other information: repro: https://jsbin.com/zobarureye/edit?html,js,console,output

    There is a component called v-switch that is placed inside a transition-group element. The v-switch component has a directive called v-foo, accepts a boolean prop called isOn and switches its template root according to the value of isOn. The v-foo directive has an inserted hook that should be called to ensure that the binding logic is refreshed whenever the template root changes.

    opened by xiaodemen 0
Releases(v2.7.14)
A Web Component compiler for building fast, reusable UI components and static site generated Progressive Web Apps

Stencil: A Compiler for Web Components and PWAs npm init stencil Stencil is a simple compiler for generating Web Components and static site generated

Ionic 11.3k Jan 4, 2023
🐰 Rax is a progressive React framework for building universal application. https://rax.js.org

Rax is a progressive React framework for building universal applications. ?? Write Once, Run Anywhere: write one codebase, run with Web, Weex, Node.js

Alibaba 7.8k Dec 31, 2022
Dojo Framework. A Progressive Framework for Modern Web Apps

@dojo/framework Dojo is a progressive framework for modern web applications built with TypeScript. Visit us at dojo.io for documentation, tutorials, c

Dojo 549 Dec 25, 2022
Relay is a JavaScript framework for building data-driven React applications.

Relay · Relay is a JavaScript framework for building data-driven React applications. Declarative: Never again communicate with your data store using a

Facebook 17.5k Jan 1, 2023
A JavaScript Framework for Building Brilliant Applications

mithril.js What is Mithril? Installation Documentation Getting Help Contributing What is Mithril? A modern client-side JavaScript framework for buildi

null 13.5k Dec 28, 2022
The tiny framework for building hypertext applications.

Hyperapp The tiny framework for building hypertext applications. Do more with less—We have minimized the concepts you need to learn to get stuff done.

Jorge Bucaran 18.9k Jan 1, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs ∙ Try Online ∙ Contribute ∙ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

React · React is a JavaScript library for building user interfaces. Declarative: React makes it painless to create interactive UIs. Design simple view

Facebook 200k Jan 4, 2023
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Inferno is an insanely fast, React-like library for building high-performance user interfaces on both the client and server. Description The main obje

Inferno 15.6k Dec 31, 2022
A declarative, efficient, and flexible JavaScript library for building user interfaces.

Solid is a declarative JavaScript library for creating user interfaces. It does not use a Virtual DOM. Instead it opts to compile its templates down t

Ryan Carniato 24.5k Jan 4, 2023
jCore - JavaScript library for building UI components

JavaScript library for building UI components

iOnStage 11 Jan 21, 2022
Ember.js - A JavaScript framework for creating ambitious web applications

Ember.js is a JavaScript framework that greatly reduces the time, effort and resources needed to build any web application. It is focused on making yo

Ember.js 22.4k Jan 4, 2023
CrossUI is a free Cross-Browser Javascript framework with cutting-edge functionality for rich web application

CrossUI is a free Cross-Browser Javascript framework with cutting-edge functionality for rich web application

Jack Li 1.4k Jan 3, 2023
利用uniapp+tailwindcss+uview+vue-cli搭建的一套基础模板,可以使用Webstorm或者vscode开发。集成miniprogram-ci自动部署

uniapp-tailwind-uview-starter 利用uniapp+tailwindcss+uview+sass搭建的一套基础模板,并且集成了miniprogram-ci实现自动构建上传微信小程序。 tailwindcss以及flex布局的css工具拓展 miniprogram-ci集成,

XLZY 81 Dec 27, 2022
Write components once, run everywhere. Compiles to Vue, React, Solid, Angular, Svelte, and more.

Write components once, run everywhere. Compiles to: At a glance Mitosis is inspired by many modern frameworks. You'll see components look like React c

Builder.io 7.7k Jan 1, 2023
The AMP web component framework.

AMP ⚡ ⚡ ⚡ ⚡ Metrics Tooling AMP is a web component framework for easily creating user-first websites, stories, ads, emails and more. AMP is an open so

AMP 14.9k Jan 4, 2023
A rugged, minimal framework for composing JavaScript behavior in your markup.

Alpine.js Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost. You get to keep your DOM,

Alpine.js 22.5k Jan 2, 2023
A modest JavaScript framework for the HTML you already have

Stimulus A modest JavaScript framework for the HTML you already have Stimulus is a JavaScript framework with modest ambitions. It doesn't seek to take

Hotwire 11.7k Dec 29, 2022