这是一个实时文档。 最后更新:2016 年 8 月 17 日,截至 2.0.0-rc.2
一般注意事项
最后有一些升级技巧。
模板解析器不再依赖于 DOM(除非您使用真实的 DOM 作为模板),因此只要您使用字符串模板( <script type="text/x-template">
、内联 JavaScript 字符串或通过单文件组件编译) ),您不再受1.x 中的任何el
选项),您仍然会受到这些限制。
编译器(将模板字符串转换为渲染函数的部分)和运行时现在可以分开了。 将有两种不同的构建:
vueify
或vue-loader
将执行模板预编译。[x] Vue.config.silent
v-on
配置自定义键别名。不推荐使用Vue.config.unsafeDelimiters ,使用 v-html
[x] Vue.extend
el
上设置和访问数据索引[x] 手表
[x] el
不推荐使用替换,组件现在必须只有一个根元素。
[x]初始化前创建
分离已弃用,同上
[x] 指令
elementDirectives已弃用
[x] 父母
事件已弃用,因为不再有事件传播
[x] vm.$data
vm.$log已弃用,请使用 devtools
[x] vm.$on
vm.$broadcast已弃用,同上
[x] vm.$nextTick
vm.$remove已弃用
[x] vm.$mount
[x] vm.$destroy
[x] 垂直文本
{{{ }}}
简写已被弃用(value, index) in arr
, (value, key, index) in obj
$index
和$key
Vue.config.keyCodes
而不是Vue.directive('on').keyCodes
)ref
v-el已弃用(与 ref 合并)
[x] <component>
<transition>
<transition-group>
<keep-alive>
<slot>
部分弃用
[x] 键
[x] 插槽
[x] 渲染到字符串
v-for
迭代语法更改弃用$index
和$key
这两个都被弃用,以支持更明确的命名索引和键。 这种语法有点神奇,并且在嵌套循环中具有局限性。 作为奖励,新手要学习的语法点会少两个。
value in arr
(value, index) in arr
(改变参数的顺序以与 JavaScript 的forEach
和map
更一致)value in obj
(value, key) in obj
(参数的切换顺序,部分是为了与许多常见的对象迭代器更加一致,例如 lodash 的)(value, key, index) in obj
(索引现在可以在对象迭代中用于视觉目的,例如表条带化)一般来说,2.0 指令的职责范围大大缩小:它们现在只用于应用低级直接 DOM 操作。 在大多数情况下,您应该更喜欢使用组件作为主要的代码重用抽象。
指令不再有实例 - 这意味着指令钩子内不再有this
并且bind
、 update
和unbind
现在接收所有内容作为参数。
请注意binding
对象是不可变的,设置binding.value
将不起作用,并且添加到它的属性不会被持久化。 如果您绝对需要,您可以在el
上保留指令状态:
<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) { ... }
}
如果您只关心值,则可以使用解构:
export default {
bind (el, { value }) {
// ...
}
}
另外, update
钩子有一些变化:
bind
之后不再自动调用它。binding.value === binding.oldValue
以跳过不必要的更新,但也有一些情况下您希望始终应用更新,例如当指令绑定到可能已发生变异而不是被替换的对象时。elementDirective
、指令参数和指令选项如acceptStatement
、 deep
等都已弃用。
在 Vue 2.0 中,过滤系统有几处变化:
{{}}
标签)。 过去,我们发现使用带有v-model
、 v-on
等指令的过滤器会带来更多的复杂性而不是方便,对于v-for
上的列表过滤,它更合适将该逻辑作为计算属性移动到 JavaScript 中。
{{ date | formatDate('YY-MM-DD') }}
过渡 CSS 类更改:
永远在线的v-transition
类不再添加,Vue 现在使用与 Angular 和 React CSSTransitionGroup 相同的类:
v-enter
:在插入元素之前应用,在 1 个刻度后删除。 (进入的起始状态)v-enter-active
:在插入元素之前应用,在过渡/动画完成时移除。 (进入的活动 + 结束状态)v-leave
:在触发离开转换时立即应用,在 1 个滴答后移除(离开的起始状态)v-leave-active
:在触发离开过渡时立即应用,在过渡/动画完成时移除。 (活动+休假结束状态)v-enter-active
和v-leave-active
使您能够为进入/离开过渡指定不同的缓动曲线。 在大多数情况下,升级意味着简单地用v-leave-active
替换您当前的v-leave
v-leave-active
。 (对于 CSS 动画,使用v-enter-active
+ v-leave-active
)
<transition>
组件
现在通过使用<transition>
内置组件包装目标元素/组件来应用所有单元素过渡效果。 这是一个抽象组件,这意味着它不会呈现额外的 DOM 元素,也不会显示在检查的组件层次结构中。 它只是将转换行为应用于内部包装的内容。
最简单的用法示例:
<transition>
<div v-if="ok">toggled content</div>
</transition>
该组件定义了许多直接映射到旧转换定义选项的道具和事件:
道具
用于自动生成过渡 CSS 类名。 例如name: 'fade'
将自动扩展为.fade-enter
、 .fade-enter-active
等。默认为"v"
。
是否在初始渲染上应用过渡。 默认为false
。
是否应用 CSS 过渡类。 默认为true
。 如果设置为false
,则只会触发通过组件事件注册的 JavaScript 钩子。
指定要等待以确定转换结束时间的转换事件的类型。 可用值是"transition"
和"animation"
。 默认情况下,它会自动检测持续时间较长的类型。
控制离开/进入转换的时序。 可用的模式是"out-in"
和"in-out"
; 默认为同时。
单独配置过渡 CSS 类。
将过渡应用于动态组件的示例:
<transition name="fade" mode="out-in" appear>
<component :is="view"></component>
</transition>
活动
对应于 1.x API 中可用的 JavaScript 钩子。
例子:
<transition @after-enter="transitionComplete">
<div v-show="ok">toggled content</div>
</transition>
当进入过渡完成时,组件的transitionComplete
方法将使用过渡后的 DOM 元素作为参数被调用。
一些注意事项:
leave-cancelled
不再可用于插入/删除。 一旦休假过渡开始,就无法取消。 但是,它仍可用于v-show
转换。enter
和leave
钩子, cb
作为第二个参数的存在表明用户希望明确控制转换的结束时间。<transition-group>
组件
现在通过使用<transition-group>
内置组件包装元素来应用所有多元素过渡效果。 它公开了与<transition>
相同的道具和事件。 不同之处在于:
<transition>
, <transition-group>
渲染一个真实的 DOM 元素。 默认情况下,它呈现<span>
,您可以通过tag
属性配置应该呈现的元素。 您也可以将它与is
属性一起使用,例如<ul is="transition-group">
。<transition-group>
不支持mode
道具。<transition-group>
中的每个子项都必须是唯一键控的。例子:
<transition-group tag="ul" name="slide">
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</transition-group>
移动过渡
<transition-group>
支持通过 CSS 转换移动过渡。 当孩子在屏幕上的位置在更新后发生变化时,它将应用一个移动的 CSS 类(从name
道具自动生成或使用moveClass
道具配置)。 如果在应用移动类时 CSS transform
属性是“可转换的”,则元素将使用FLIP 技术平滑地动画到其目的地。
在此处查看现场演示。
创建可重用的转换
现在过渡是通过组件应用的,它们不再被视为资产类型,因此全局Vue.transition()
方法和transition
选项都已弃用。 您可以使用组件道具和事件内联配置过渡。 但是我们现在如何创建可重用的过渡效果,尤其是那些带有自定义 JavaScript 钩子的效果? 嗯,答案是创建您自己的过渡组件(它们特别适合作为功能组件):
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)
}
})
然后你可以像这样使用它:
<fade>
<div v-if="ok">toggled content</div>
</fade>
lazy
和number
参数现在是修饰符:
<input v-model.lazy="text">
.trim
- 顾名思义,修剪输入。debounce
参数已被弃用。 (见底部升级提示)v-model
不再关心初始内联value
。 它将始终将 Vue 实例数据视为真实来源。 这意味着以下内容将以 1 而不是 2 的值呈现:
data: {
val: 1
}
<input v-model="val" value="2">
<textarea>
与现有内容相同。 所以而不是:
<textarea v-model="val">hello world</textarea>
做:
data () {
return {
val: 'hello world'
}
}
<textarea v-model="val"></textarea>
主要思想是 JS 端应该被认为是事实的来源,而不是你的模板。
v-model
在v-for
迭代原始值上使用时不再有效:
<input v-for="str in strings" v-model="str">
这不起作用,因为它相当于 JavaScript 中的 this:
strings.map(function (str) {
return createElement('input', ...)
})
如您所见,在迭代器函数中将str
为另一个值将没有任何作用,因为它只是函数作用域中的一个局部变量。 相反,您应该使用对象数组,以便v-model
可以更新对象上的字段:
<input v-for="obj in objects" v-model="obj.str">
.once
和.sync
已弃用。 道具现在总是单向下降。 为了在父作用域中产生副作用,组件需要显式地发出一个事件,而不是依赖于隐式绑定。
a
然后在组件中设置this.a = someOtherValue
。 由于新的渲染机制,每当父组件重新渲染时,子组件的本地更改都会被覆盖。 通常,在 2.0 中,您应该将 props 视为不可变的。 大多数改变 prop 的用例都可以用数据属性或计算属性替换。keep-alive
不再是一个特殊的属性:它现在是一个包装组件,类似于<transition>
:
<keep-alive>
<component :is="view"></component>
</keep-alive>
这使得在多个有条件的孩子上使用keep-alive
成为可能(注意孩子最终应该评估为一个孩子 - 除了第一个孩子之外的任何孩子都将被忽略):
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
与<transition>
一起使用时,请确保将其嵌套在其中:
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
<slot>
。 当一个插槽被渲染时,它被“用完”并且不能在同一渲染树中的其他地方渲染。通过名为<slot>
插入的内容不再保留slot
属性。 使用包装元素来设置它们的样式,或者,对于高级用例,使用渲染函数以编程方式修改插入的内容。
v-ref
现在不再是一个指令:它现在是一个类似于key
和transition
的特殊属性:
<!-- before -->
<comp v-ref:foo></comp>
<!-- after -->
<comp ref="foo"></comp>
现在还支持动态 ref 绑定:
<comp :ref="dynamicRef"></comp>
vm.$els
和vm.$refs
合并。 当在普通元素上使用时,ref 将是 DOM 元素,当在组件上使用时,ref 将是组件实例。vm.$refs
不再是响应式的,因为它们是在渲染过程中注册/更新的。 使它们具有反应性需要对每次更改进行重复渲染。
另一方面, $refs
主要用于 JavaScript 中的编程访问 - 不建议在模板中依赖$refs
,因为它需要引用不属于实例本身的状态。
track-by
已替换为key
。 它现在遵循绑定属性的相同规则:没有v-bind:
或:
前缀,它被视为文字 string 。 在大多数情况下,您希望使用动态绑定,它需要完整的表达式而不是字符串键。 例如:
<!-- 1.x -->
<div v-for="item in items" track-by="id">
<!-- 2.0 -->
<div v-for="item in items" :key="item.id">
不推荐使用属性内的插值:
<!-- 1.x -->
<div id="{{ id }}">
<!-- 2.0 -->
<div :id="id">
属性绑定行为改变:只有null
、 undefined
和false
在绑定属性时被认为是假的。 这意味着0
和空字符串将按原样呈现。 对于枚举属性。 这意味着:draggable="''"
将呈现为draggable="true"
。
此外,对于枚举属性,除了上面的假值之外,“false”的字符串值也将呈现为 attr="false"。
v-on
现在只监听该组件发出的自定义事件 $emitted。 (不再监听 DOM 事件)v-else
不再适用于v-show
- 只需使用否定表达式。{{* foo }}
) 已弃用 - 请改用v-once
。:style
不再支持内联!important
propsData
)el
选项不能再用于Vue.extend
。 它现在只能用作实例创建选项。Vue.set
和Vue.delete
不能在 Vue 实例上工作。 现在必须在data
选项中正确声明所有顶级反应性属性。$data
。 这可以防止反应性系统中的一些边缘情况,并使组件状态更可预测(尤其是在类型检查系统中)。通过vm.$watch
创建的用户观察者现在在关联的组件重新渲染之前被触发。 这让用户有机会在组件重新渲染之前进一步更新其他状态,从而避免不必要的更新。 例如,您可以监视组件 prop 并在 prop 更改时更新组件自己的数据。
要在组件更新后对 DOM 做一些事情,只需使用更新的生命周期钩子。
$dispatch
和$broadcast
弃用?我们弃用$dispatch
和$broadcast
是依赖于组件树结构的事件流很难推断组件树何时变大(简单地说:它不会在大型应用程序中很好地扩展,我们不想让你以后痛苦)。 $dispatch
和$broadcast
也没有解决兄弟组件之间的通信问题。 相反,您可以使用类似于Node.js 中的
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)
并且不要忘记使用 $off 解除事件绑定。
// in component B's destroyed hook
bus.$off('id-selected', this.someMethod)
在简单的场景中,这种模式可以替代$dispatch
和$broadcast
。 但是对于更复杂的情况,建议使用Vuex引入一个专用的状态管理层。
对于使用v-for
列表过滤 - 过滤器的一种更常见的用法 - 现在建议使用计算属性返回原始数组的处理副本(请参阅更新的数据网格示例)。 好处是你不再受任意过滤器语法/API 的限制——它现在只是普通的 JavaScript,你自然可以访问过滤结果,因为它是一个计算属性。
另请参阅此讨论主题。
debounce
对v-model
的弃用?去抖动用于限制我们执行 Ajax 请求和其他昂贵操作的频率。 Vue公司的debounce
的属性参数v-model
让一切变得简单,但它也去抖_STATE updates_而不是昂贵的操作本身,其自带的局限性。
在设计搜索指示器时,这些限制变得明显。 看看那个例子。 使用debounce
属性,将无法在搜索开始之前检测到脏输入,因为我们将无法访问输入的实时状态。 通过将 debounce 函数与 Vue 解耦,我们能够_仅_对我们想要限制的操作进行 debounce。
在其他时候,去抖动并不是_非常_正确的包装函数。 在点击 API 以获取搜索建议的非常常见的示例中,等到用户停止输入后才提供建议并不是理想的体验。 您可能想要的是限制功能。 现在,由于您已经在debounce
使用了像 lodash 这样的实用程序库,因此重构为使用throttle
只需几秒钟!
@rekateka 2.0 独立构建意味着(编译器 + 运行时)。 NPM 包的默认导出将仅在运行时进行,因为如果从 NPM 安装,您可能会使用构建工具预编译模板。
谢谢,@yyx990803。 我还有几个关于编译器和其他功能的问题,但我已经使用了论坛。
是否对我应该审查的文档进行了任何令人担忧的更改? 做得好! 保持它的人。 您正在重新定义 Web 开发。 谢谢!
我可以获得指令的this.arg
吗?
我看到vnode.data.directives
有arg
,但是当我有两个或更多指令时,我不知道index
。
<!-- show @ 0, img @ 1-->
<img v-show="true" v-img:200*200="imgSrc">
<!-- img @ 0, show @ 1-->
<img v-img:200*200="imgSrc" v-show="true">
我应该使用forEach
吗? 谢谢!
@banricho好点,这被忽视了! 请参阅更新的指令函数签名。
首先,抱歉我不是很确定可以在这里问这个问题,我有一点要求想说。
要求是我希望我可以像这样设计我的组件的用法
<carousel>
<img src="..." alt="..." desc="..." is="argument">
<img src="..." alt="..." desc="..." is="argument">
</carousel>
我希望孩子们可以作为某种论据,不仅限于属性
现在我可以制作一个组件,用法像
<carousel items="[{}, {}, {}]"></carousel>
但是我觉得不是很好,希望能像我之前在React coverflow中做的这个
@andyyou - 这个问题可能最好发布在论坛上,因为它不是问题,也不是明确的建议,也不是对这个问题的任何真正帮助。
如果您在论坛帖子中发现 Vue 无法满足您的要求,那么您可以在此处打开一个新问题。
斯科特
@smolinari谢谢
“但对于更复杂的情况,建议使用 Vuex 引入专用的状态管理层。” 这似乎暗示应该在事件上使用状态。 我认为它们是完全独立的——一个事件是一个时刻,而状态不会改变。 你可以说你可以观察状态,但这也没有传达特定的时刻,而是任何时候发生的变化。 我对这条建议背后的含义很感兴趣。
@jrenton通常,我们可以将事件系统简单地视为组件 A 告诉组件 B 更改其状态,或者 A 告诉 B 做其他事情。
所以对于第一种情况,我们可以使用状态管理(管理 A 和 B 的共享状态)而不是使用事件系统让 A 告诉 B 改变状态。
对于第二种情况,我认为可以用“事件总线”方法很好地处理它。
@jrenton而不是组件相互交谈的汤,Vuex 建议组件使用单一通道来表达“意图”与动作,并通过突变记录“事实”。
我正在使用 Twig 和 Vue。
到目前为止(vue 1.0)我一直在将数据传递到我的组件中,如下所示:
<my-component data="{{ DATA }}"><my-component>
(请注意, {{
和}}
是树枝标签 - 对于 vue 我一直在使用自定义分隔符${
和}
)
如果我理解正确,在 Vue 2.0 中我应该这样做:
<my-component :data=" '{{ DATA }}' "></my-component>
对?
@gholol不,这只是
<my-component :data="{{ DATA }}"></my-component>
实际上,您的旧用法似乎一开始就不起作用。
嗯,它工作得很好......
就像我说的,数据来自树枝模板引擎。 现在在 Vue 2.0 中它不起作用。 我一直在尝试像您说的那样传递它(没有单个撇号),但是数据属性未定义。
错误:SyntaxError:在属性列表之后缺少}
编辑:它有效,我忘了提到 DATA 变量是一个字符串
@jrenton我的想法和动机很简单,似乎 Vue 不喜欢强迫我们使用 JSX 的 React。 我们可以选择很多template
。
我希望我可以使用子元素语法作为参数(参数)将 args 传递给父级,因为在一些模板语言中,如slim
如果你有很多属性或者说 attr 的名字很长那么我们必须把所有的东西都在一行中。 使一行代码超过 80 个字符更容易。
@yyx990803今天<input type="text" name="account[categories][{{ category.id }}]">
2.0?
ES6 内联模板在绑定表达式中工作:
<input type="text" :name="`account[categories][${ category.id }]`">
如果这是在 2.0 上运行的唯一方法,那么请不要介意我说这是对我们习惯的可爱语法 1.0 的回归——是的,我知道那只是 ES2015。
我认为出于性能原因删除了插值? 我只是希望它值得使用丑陋的语法。
@oskarkrawczyk我假设你想在你的 DOM 中得到类似name="account[categories][fruits]"
东西,因为这就是你的表达式会呈现的。
2.0 版本(实际上是正确的 1.0)将是:name=" 'account[categories][' + category.id + ']' "
。
@simplesmiler 明白了。 我认为{{ }}
只是把我宠坏了一点。
@yyx990803我可以像这样动态插入组件吗?
render () {
return this.$createElement('div', { staticClass: 'list-container' }, this.list)
},
data () {
return {
list: []
}
},
method: {
a () {
this.list.push(this.$createElement('myComponent', {}))
}
}
如何为依赖于表达式的属性绑定几个值? 例如:
new Vue({
el:'body',
data:{
flag: true
}
})
<input type="text" v-bind:placeholder="{test: flag, test2: !flag}" />
我期待下一个结果:
<input type="text" placeholder="test" />
<!-- or -->
<input type="text" placeholder="test2" />
@nervgh这不是问这个问题的正确地方。
使用三元表达式v-bind:placeholder="flag ? 'test' : 'test2'"
。
@simplesmiler ,感谢您的回答。 我想说_Object-Syntax_在这些情况下会很有用,但它并不像我期望的那样工作。
@nervgh对象语法仅适用于采用字符串列表的属性。 在本机属性中,唯一的此类属性是class
,对于组件,无法从子端检测您是要发送字符串列表还是正确的对象。
回复: .once
和.sync
已弃用。
这不是真的打破了常见的设计模式吗?
我无法想象如果没有这些,您将如何拥有处理表单字段的简单组件。
我有用于不同表单字段类型的简单组件,例如这是我的“文本框”组件模板:
<label>{{type.caption}}:<input type="text" v-model="data"></label>
...还有一个更复杂的列表组件,它提供了一个用户界面来在数据结构中的数组中添加和删除元素
然后我使用这些组件,例如:
<div v-for="field in type.fields">
<component :data.sync="data[field.name]" :is="field.ctype" :type="field">
注意:所有这些组件都有两个道具: data
和type
。 data
是组件负责提供编辑的数据结构中的节点,以及用于编辑的UI, type
是(海量,静态)数据结构中包含类型的节点/fields 层次结构。
没有.sync
这样的东西怎么能工作?
在我看来,在这些组件之间创建某种消息传递系统会使事情变得非常复杂,其中子组件可以以某种方式与父组件通信,它们是哪个子组件,然后父组件可以找出其数据的哪一部分要修改的结构。
我真的希望我遗漏了一些东西......因为看起来你是说使用组件为数据结构的一部分创建编辑器是一种反模式。 什么? 到目前为止,这是我使用 Vue 的唯一目的。 我猜您认为删除此功能会鼓励人们编写更简洁的代码。 也许它会对某些人产生这种影响,但是很多人会编写更多讨厌的代码来解决这个限制。 修改状态是计算机所做的唯一有用的事情。 请继续使这更容易。
2.0 中的@JasonWoof v-model
可以处理自定义组件。 该组件只需要:
value
的道具input
事件,例如this.$emit('input', value)
参见示例。
@yyx990803感谢您的解释和链接。 现在我只是坚持:
为什么要删除.sync
?
我没有看到优点,只有缺点。 您链接的示例表明您可以使用:selected.sync
或v-model
。 我只看到 v-model 方法的缺点:
.sync
props我看不出切换到 v-model 会如何使任何事情变得更清晰/更清晰。 在这两种情况下,父组件中唯一表明子组件可以轻松修改父状态的指示是模板中 prop 的语法。 我什至认为.sync
更清楚。
另一件事是,当您将对象/数组/等作为道具传递时,它们在子组件中是可变的。 因此,在这种情况下,您无法阻止程序员更改子组件的状态(我认为这很常见。)所以在我看来,您正在通过删除使事情变得如此的东西来引入绊脚石传递字符串值的工作原理与传递对象值相同。 .sync
通过始终让我的“数据”道具可从子端写入,无论数据类型如何,都使我的代码更简单、更一致。
我是 Vue.js 的新手(3 天前),但从我目前所见,Vue.js 之所以有价值主要是因为两件事:
至少这是我目前发现的。
在我看来,删除.sync
使得 Vue.js 很难始终如一地执行第二个操作。
@JasonWoof因为组件自身范围之外的显式与隐式副作用在长期可维护性方面产生了所有差异。
...虽然人们可能会争辩说人们应该学习何时不使用.sync
,但到目前为止我们的经验是不同的。 人们往往过于依赖这一点,并创建了以后几乎无法调试的代码。
所以这是一个设计决定,迫使人们从一开始就做对。
一个例子:
name
。 一切都很好。watch
函数。 好的!console.log()
放在任何地方来跟踪行为。watch
函数中找到一种方法来区分这些场景。...当您同步深度超过一层时,这会变得更加疯狂。
这是我们在论坛和 gitter 聊天中反复看到的(反)模式。
删除.sync
迫使人们从一开始就编写清晰、明确、可维护的代码,因为大多数情况下,他们的代码对于.sync
来说不会保持足够简单。
行。 谢谢你的解释。
很高兴听到您要解决的问题。
我严重怀疑这会有所帮助... 让它不能轻易打破你喜欢的模式,人们会做更糟糕的事情来解决这些限制。
这让我想起了很多抽象。 抽象给我们带来了很多麻烦。 它们使代码难以阅读,难以调试,等等......但是你不能通过剥夺进行抽象的能力来解决这个问题......这几乎是使编程成为可能/有用的事情。 解决这个问题的方法不是在语言或框架层面,而是在教学、建议、学习中。 我们鼓励人们不要把事情变得过于抽象。
在我看来,您在谈论这样的设计理念。 在许多情况下,在编码时牢记这一点是一个很好的哲学。 但是当它被强加为一个限制,并且程序员认为这个限制阻止她做她需要做的事情时,那么她就会解决它,这将导致你试图避免的所有问题,甚至更糟。
人们不会停止尝试从孩子那里改变父状态。 你不能强迫人们不要那样做。
你的v-model
事情足够复杂,我可以通过传递父对象/数组和一个键来解决这个问题,以便孩子可以修改它。
我想这最后一点打击是我试图解决的核心问题:我(个人)认为缺少.sync
是一个问题,并且会解决它或不使用您的框架。 我敢打赌,很多人都会有同样的方法。
也许这不言而喻,但当人们试图将设计理念强加于我时,这让我有点生气。 我宁愿建造出严重错误的东西并学会不再这样做,也不愿使用故意扣留权力的系统,因为我担心我可能会用不好。
PS 对不起,我忍不住了,再评论一条,那我就不打扰你们了。 大多数程序员编写他们无法调试的代码。 这发生在每种语言和每种框架的每个程序员身上。 这就是程序员如何成为更好的程序员:他们会犯错误,他们编写无法修复的代码,他们学习如何在未来以不同的方式编写代码。 请不要为每个人都简化你的框架,试图让那些把自己抽象到角落里的程序员可以让他们的东西变得更加混乱/复杂,以免它变得如此混乱以至于他们无法调试它。
@JasonWoof它与“愚蠢”无关,根据定义,防止用户陷入常见陷阱/确保更好的可维护性是框架工作的一部分。 我们根据第一手经验设计、使用框架本身并观察各种用例中的用户行为做出了决定。 如果是反模式,我们会劝阻用户使用它,并提供惯用解决方案的指导。 你可以根据你的个人意见自由地反对这一点,但我觉得你的论点很难令人信服。
人们不会停止尝试从孩子那里改变父状态。 你不能强迫人们不要那样做。
当然。 我们_不会_“强制”他们,因为可能有一些边缘情况,这可能仍然是必要的。 所以你仍然可以访问this.$parent
,你可以通过一个道具等传递$data
,但坦率地说,这样做并不会比$emit
大部分的事件更方便时间,所以它们不会像.sync
糖那样有吸引力。
另外, $parent
等。 不是官方指南的一部分,因此使用它们的用户正在积极解决建议的最佳实践 - 他们可以自由地这样做,但我们不鼓励这种行为。
因此,如果我们认为这样的功能在大多数情况下被滥用并且与框架试图建立的最佳实践背道而驰,那么框架不应该通过提供像.sync
这样的“神奇”语法糖来鼓励类似的行为。
尤大 有没有中文版的。。
vue-router 的兼容性如何?
@roblav96
有一些变化需要兼容,我们希望更好地将 Router 合并到 Vue.js 中。
@布莱克纽曼
我们可以在 vue-cli 上一起获取样板模板吗? 我似乎无法让这些工作 😢
@roblav96
目前有一些,vue-loader 需要进行一些更改以使其兼容。 目前 2.0 应该仅用于实验,直到更新大规模应用程序的所有其他依赖项。
测试版/发布候选版是否有预计到达时间?
@Evertt Alpha 将于本周到期。 Beta 版将完成文档,并且可能会从核心扩展库(Vue-router 等)获得更多支持。 当 Beta 被证明成功时发布候选版本。
@blake-newman 感谢您快速、简洁和完整的回复。 那些是最好的。 :-D
vue 2.0 中replace: false
任何解决方法?
嗨,JSX 已经可用了吗?
@reohjs - 不,我个人认为这是 Vue 真正的倒退,如果它确实支持 JSX。
斯科特
@reohjs 昨晚在 Evan 的直播中,他提到它可以用插件制作,所以我想一旦它进入测试阶段,很快就会有人创建它。 我很高兴它不在核心中,但 JSX 插件听起来是个好主意。
我很高兴它不在核心
👍👍👍👍
应该是插件吧然而,正如所见,模板对标准组件有很多好处。
使用这个插件应该很容易实现 JSX 编译: https :
我认为_h
函数将替代React.createElement
提供一个接口来创建自定义 v-model 修改器作为替换 2 路过滤器的方式怎么样? 似乎它们已经被用于解析用户输入(例如v-model.trim
)。 如果解析/格式化很简单并且独立于特定的数据属性,与为每个单独的数据属性设置计算属性或为每个单独的数据属性创建一个新组件相比,使用修饰符将允许以更少的样板重复使用解析/格式化我们希望应用解析/格式的输入类型。
嗨,我目前正在开发一个插件来支持 Vue.js 1.0
gettext
1.0
并且我有一个使用vm.$interpolate
的指令。
我想知道如何将我的代码迁移到2.0
因为:
vm.$interpolate
将被弃用2.0
有实例或者有比指令更好的方法吗?
import languages from 'src/plugins/translate/languages'
import translateUtils from 'src/plugins/translate/utils'
const translateDirective = {
terminal: true,
params: ['translateN', 'translatePlural'],
paramWatchers: {
translateN: function () {
this.translate()
},
},
isPlural: function () {
return 'translateN' in this.params && 'translatePlural' in this.params
},
bind: function () {
this.boundTranslate = this.translate.bind(this)
this.msgid = this.el.innerHTML.trim()
this.translate()
languages.eventEmitter.on(languages.languageChangedEventName, this.boundTranslate)
},
unbind: function () {
languages.eventEmitter.removeListener(languages.languageChangedEventName, this.boundTranslate)
},
translate: function () {
let n = this.isPlural() ? parseInt(this.params.translateN) : 1
let translation = translateUtils.getTranslation(this.msgid, n)
this.el.innerHTML = this.vm.$interpolate(translation)
},
}
export default translateDirective
因为我是Vue 的新手,所以只是简单地说几句,只是说我很高兴看到 API 或 _under-the-hood_ 助手的减少。 JavaScript 已经非常强大了,有了计算属性加上框架的其他响应式特性,几乎一切都可以实现。
此 _next_ 版本的荣誉! 🎆
@kemar我对 gettext 不太熟悉,但我会简单地使用 $translate 方法扩展 Vue.prototype,然后执行
{{ $translate('some.Key.path') }}
从 2.0 中删除了使用数组语法注册资产的能力吗? 没有在 alpha 上工作,只是想知道它是否是故意的。
IE:
components: [compA, compB, compC]
我知道 ES6 有类似的速记,但在某些情况下数组语法很有用。
我看到你提到rendering to native interfaces on mobile
和weex
,我想知道让 vue 和Nativescript交谈是多么容易。
与 Vue 的 Nativescript 类似的东西要么是你提到的 Weex ,要么是Quasar 。
斯科特
如果不再有dispatch
或broadcast
通用子组件将如何通知其父级事件/更改? 这似乎不符合全局总线或 vuex 的模式。 我们现在使用的用例是搜索过滤器的范围滑块。 范围滑块组件是通用的,是几个不同搜索过滤器的子项。 我们目前使用dispatch
当范围滑块完成滑动时,然后父级知道根据更改触发搜索。
@jrenton内联侦听器<child @some-event="parentHandler">
干得好伙计们。
在我看来,所有的变化都表明,最好的方法是仅基于“单向流”创建组件树,这更加简单且易于调试和维护。
如果没有这个,你的数据真实性将与你离最顶层组件的距离成反比。
只想说:
render (h) {
return (
<div>
{this.things.map(thing => <Thing thing={thing}></Thing>)}
</div>
);
让我开心
预计在 2.0 发布之前会有更多内容添加到此列表中吗? 只是好奇,因为这个问题仍然存在。
@zephraph是的,我们会在更新 API 时不断更新列表。 😃 到目前为止还没有什么大的变化,但偶尔会对以前的 alpha 进行重大更改。
我有一个案例,我过去使用过事件调度,但我在 vuex 中遇到了问题:父组件有一个子组件列表,当它的值发生变化时,子组件正在调度一个事件,因此父组件能够做一些事情这种变化的反应。
现在我尝试在 vuex 存储中有一个子值数组。 问题是,子组件如何在 getter 和 action 中知道它需要更新该数组的哪个元素。 据我所知,vuex 不提供动态获取或触发值变化的功能,或者我错了吗?
在没有事件调度的情况下处理这种情况的最佳方法是什么?
删除$broadcast
后,您会如何告诉直系孩子在发生特定事情时做某事? 在这种情况下,实际上没有数据发生变化,因此响应式道具似乎不适合。
我可以使用道具并传递时间戳或一些随机数据并在孩子身上观看该道具,但这似乎很奇怪。 全局事件总线需要生成唯一 ID,因此子组件仅对来自其父组件的事件做出反应,而不对父组件的任何其他实例做出反应。
父母可以使用内联侦听器收听孩子中的$emit
,有什么相反的方法吗?
我可以通过道具传递一个发射器的实例,然后在孩子中传递emmiter.on
,这听起来很糟糕吗?
@gwildu操作可以带参数,因此您可以将项目 ID 与操作一起传递。 并且不是让 item 组件从 store 中获取相应的 item,而是获取 parent 中的列表,并使用 prop 将 item 数据传递给 item 组件。
// Vuex store
state: {
items: [],
},
mutations: {
ITEM_REMOVED: function(state, id) {
var io = state.items.findIndex(item => item.id === id);
state.items.splice(io, 1);
},
},
// within the parent component
vuex: {
getters: {
items: state => state.items,
},
actions: {
removeItem(store, id) {
store.dispatch('ITEM_REMOVED', id);
},
},
},
<!-- within the parent template -->
<item v-for="item in item"
:item-data="item.data"
@removed="removeItem(item.id)"
>
</item>
<!-- within the child template -->
<button @click="$emit('removed')">Remove</button>
如果您的商品没有本地唯一 ID,您可以在创建商品或从 API 接收商品时生成一个。 大多数情况下, cuid已经足够了。
@fergaldoyle由于父母总是知道它是孩子,您可以将v-ref:some-child
放在孩子身上以获取对孩子虚拟机的引用,然后在其上添加$emit
,或者直接调用一个方法与this.$refs.someChild.<methodName>(...)
。
但是,我建议在这种情况下重新考虑架构,因为向下流动的事件使组件很难推理。
我在玩 vuejs 2,如果你通过了,我注意到了 Snabbdom
h('div', {style: {color: '#000'}}, [
h('h1', 'Headline'),
h('p', 'A paragraph'),
]);
你得到的渲染函数
<div style="color:#000;"><h1>Headline</h1><p>A paragraph</p></div>
但是在 vuejs 中你得到
<div style="color:#000;"><h1></h1><p></p></div>
有没有办法修改文本内容(在<h1>
)?
@dubcanada为什么不把它们当作孩子传递呢?
说得对。 谢谢
你好。 我对 Vue 2.0 中的转换系统有一些疑问,或者更确切地说是一个提案,因为我不认为它在 Vue 2.0 的计划中。 在 Vue 1.0 中,我经常遇到需要检测我设置的某些过渡/动画何时结束。 现在我通过使用 setTimeout 来做到这一点,但这是非常笨拙和丑陋的方式,我们都同意。 所以我的问题是,当我们使用过渡与 v-show/v-if 结合时,是否会在 Vue 2.0 中以某种方式检测 CSS 过渡的结束,可能是通过事件?
<my-comp v-show="isVisible" @transition-end="onTransitionEnd" transition></my-comp>
我会很高兴在下一个 Vue 版本中看到这样的东西 :) 谢谢你听我说
@sqal你可以用过渡钩子做到这一点: https : //jsfiddle.net/simplesmiler/Lrk9sxjf/97/
@dubcanada下个版本会支持(创建元素时省略数据)
感谢@fergaldoyle和@simplesmiler发出提示。
我不知道,父母能够收听孩子发出的事件。 当然,那时听那个非冒泡事件更有意义。
大家好。 一点背景:我们正在使用 webgl,我想在 3D 表面上做一些接口。 这意味着我们需要将界面渲染到例如画布,然后将画布的内容转换为纹理。
我一直在使用 Angular、React 和 Vue,对我来说 Vue 最有意义! 在阅读 React 时,我遇到了 react-canvas 项目。 有趣的是,他们不是将虚拟 DOM 转换为真实的 DOM 节点,而是将其绘制到画布上。
因为 Vue 2.0 也在使用虚拟 DOM,所以我想知道是否也可以这样做?
你好,
只是对.sync
的删除以及在通用组件上处理 props 的通用工作流程进行了一些说明。
所以,从<component :value.sync="some.value"></component>
到<component :value="some.value" @update="updateSomeValue"></component>
跟踪道具value
的推荐方法是什么?
在最基本的情况下,它似乎是
props: ['value'],
computed: {
_value: {
get(){
return this.value;
},
set(newVal) {
this.$emit('update', newVal);
return newVal;
}
}
}
但是,这肯定依赖于父组件将该值返回给 prop,所以当组件再次获取它时,它反映了最近的更改......
这是否意味着我们现在需要做这样的事情:
props: ['value'],
data() {
return {
_val: this.value
}
},
watch: {
value(newVal) {
this._val = newVal;
}
},
computed: {
_value: {
get(){
return this._val;
},
set(newVal) {
this._val = newVal
this.$emit('update', newVal);
}
}
}
这似乎有很多样板文件来处理值的传入(和更改),通知父级值已更改,并在内部跟踪更改,以防更改未由父级传回。
或者我在这里错过了一些 vue 魔术反应?
此外,如果有很多道具需要处理,这可能会变得非常复杂。
我几乎可以看到自己开发了一个包装组件,其中孩子们访问this.$parent.value
以便直接变异,而包装组件只是处理道具/计算/手表
@Towerful “跟踪价值”究竟是什么意思? 为什么你想要 setter 风格( this._value = newValue
)而不是显式的this.$emit('value-updated', newValue)
?
单向流的强大之处在于父级可以决定不应用子级请求的更改,或者可以将子级标记为“暂停”并稍后应用更改(例如,在与服务器核对之后)。
@simplesmiler使用计算属性允许您将其绑定到模板中,不是吗? 所以你可以使用v-model
。
并且将 setter 和 getter 包含在 1 个地方可以很容易地在值更新时查看功能,而不是使用不同的方法来访问值和改变组件内的值,并分散在整个代码中。
如果在模型中使用显式方式,而不是使用 setter,则methods
对象似乎会被模板的updateValue
类型方法弄得乱七八糟,而不是实际方法。
我猜它适用于用户在组件中选择一个选项的情况,该组件依赖于该值来显示选择的内容。
您依赖父组件将其传递回组件才能做到这一点。
除非,当用户选择一个选项时,您手动触发组件显示更新。 这似乎正在远离 Vue 的反应性。
因此,让内部值跟踪它“应该是什么”,让模板对此做出反应。 使用 setter/getter 包装属性以跟踪内部更改并引发外部事件,并在属性上监视以在外部更改时更新内部值。
也许我只是在努力寻找新的方法。
@Towerful - 你不是唯一的......
斯科特
@Towerful :
对我来说,您所描述的似乎本质上是像v-model
输入的组件:用户更改了 UI 中的某些值,并且您希望该更改立即反映在绑定数据中。
对于这些类型的组件,您可以在 2.0 中的组件上使用v-model
:
<my-input v-model="myValue">
// in my-input.vue
<input :value="value" @change="$emit('input', $event.target.value)">
export default {
props: ['value'] //special prop received from v-model
}
这使得真正的<input>
元素和自定义输入组件的接口基本相同,并且是双向绑定。
对于接收多个 props 的更复杂的组件(并且不是简单的自定义输入,而是更抽象),我们不鼓励使用.sync
因为在大多数情况下它变得难以推理。
父母应该决定如何处理从孩子那里收到的值,它的数据不应该像.sync
那样隐式更改。
你能提供一个例子,它是 _not_solvabel 与上面的 v-model 方法,仍然受益于使用.sync
吗? 这可能是比抽象理论更好的讨论基础。
哦,我怎么错过了?! 它绝对存在于 OP 中,甚至在一些评论之前也讨论过这个问题! 现在我觉得有点傻。
是否可以更新原始帖子以使其更清楚v-model
可以在组件上使用?
@LinusBorg在我的脑海里,我想不出一个组件上的v-model
不起作用的情况。 我错过了原帖中的那部分。
即使对于复杂的对象组件,也只是嵌套组件的问题。 这会重新强制执行单一职责组件。
这更有意义:)
@Towerful
回复:使用v-model
。 问题是, v-model
是同步的(在某种程度上),而跨组件数据流由于观察者队列( demo )而本质上是异步的。 我已经看到这让很多人感到困惑。 单向流只是让 props 不同步变得更加明确,并迫使你不要依赖它们是同步的(这就是你试图欺骗自己的方式)。
回复:杂乱的方法。 对于简单的情况,您始终可以执行@value-updated="value = $arguments[0]"
。 对于复杂的情况,拥有一种方法是一件好事,您可以在其中调整状态以使其保持一致(例如手动触发更新)。 赛格威到下一点。
回复:远离反应性。 我不同意这种说法。 对于简单的情况,您不需要魔法来让孩子拿起由value-updated="value = $arguments[0]"
更新的值。
对于复杂的情况,对于.sync
道具,您将不得不使用watch
,但显式watch
并不是反应性的一部分。 这是一个逃生舱,您可以在其中触发无法表示为计算的手动更新。 而且它不是一个好方法,因为它不能像计算那样同步响应变化。 这就是为什么在大量使用watch
,您可能会发现您的数据更新需要一些“滴答”才能传播。 如果您曾偶然发现直接嵌套的nextTick
,您就会知道我在说什么。
现在, -updated
处理程序提供了一个更好的逃生舱口,让复杂的模型更改在孩子表达意图后同步(或同时异步)应用,确保孩子将在下一个滴答中收到更新的值(或不会接收不一致的状态)。
@yyx990803我们能否实现一种监听 $
感觉更像 vuejs 风格,类似这样(“开”或“听”):
Vue.component('cart', {
template: "#cart-template",
data () {
return {quantity : 0 }
},
watch: {
'quantity': function (quantity, oldQuantity) {
console.log('quantity changed from %s to %s', oldQuantity, quantity)
bus.$emit('cart.quantity-changed', quantity)
}
}
});
new Vue({
el: '.container',
data : function () {
return {
quantity: 0
};
},
on: {
'cart.quantity-changed': function (newQuantity) {
console.log('quantity change emitted');
Vue.set(self, 'quantity', newQuantity);
}
},
computed:{
gold: function(){
return this.quantity * 100
}
}
})
这基本上会自动将其自身附加到全局总线。
事件总线不是我们想要鼓励的模式 - 它仅在某些边缘情况下有用。 通常,首选存储模式,例如 vuex。
实现使使用总线更容易并感觉“官方支持”的 API 将是错误的信号。
看看您的示例,如果您将数量存储在两个组件都可以访问的商店中,则不需要任何事件。 container
组件中的计算属性将自动更新。
不使用像 vuex 这样的真实商店解决方案的简单示例代码:
var store = {
cart: {
quantity: 0
}
}
Vue.component('cart', {
template: "#cart-template",
data () {
return store.cart
},
});
new Vue({
el: '.container',
data : function () {
return store.cart;
},
computed:{
gold: function(){
return this.quantity * 100
}
}
})
我会说 vue2 的总体思路是让自己更难拍摄
在脚。
2016 年 7 月 3 日星期日上午 11:24,Thorsten Lünborg通知@github.com
写道:
事件总线不是我们想要鼓励的模式 - 它只是
有用的一些边缘情况。 通常,首选存储模式,例如 vuex。实现一个 API,使使用总线更容易,感觉“正式”
支持”将是错误的信号。—
您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/vuejs/vue/issues/2873#issuecomment -230158828,或者静音
线程
https://github.com/notifications/unsubscribe/AACoukCpCgYlDbVej_w_h4NEhQ-imYHBks5qR9QwgaJpZM4IedHC
.
@kharysharpe $emit
旨在在子实例上与v-on
一起收听。 这还有一个额外的好处,即能够利用实例使用的原始上下文:
<list-item v-for="(item, index) in items"
:title="item.title"
@remove="items.splice(index, 1)"
>
</list-item>
2.0 版本有发布日期吗? 我对这些变化感到非常兴奋。 恭喜!
我正在考虑使用 Vue 2.0 + Redux。
@Sendoushi最终版本尚无日期,但测试版可能会在一周内发布。 😄 Vuex 2.0也正在开发中,它不仅具有比当前 vuex 更简单的 API,而且比 redux 更好地集成到 Vue 生态系统中。
Vuex 2.0 也在同时开发,它不仅具有比当前 vuex 更简单的 API,而且比 redux 更好地集成到 Vue 生态系统中。
@chrisvfritz真是太棒了! 我一直觉得当前的 API 有点过于复杂和不必要的复杂。 最终不得不做这样的事情来补偿:
const mutations = {
LOGIN (state) { state.loggedIn = true },
LOGOUT (state) { state.loggedIn = false }
}
export const types = Object.keys(mutations)
// For now we dynamically generate all the actions like this.
// It's rare when anything more complicated is needed, but there
// is an example here:
// http://vuex.vuejs.org/en/actions.html
export const actions = types.reduce((o, el) => {
var action = S(el.toLowerCase()).camelize().s
o[action] = ({dispatch}, ...args) => dispatch(el, ...args)
return o
}, {})
vue 2和vuex 2的路线图怎么样,是一起发布还是先发布,不同版本的兼容性如何?
关于上述问题,vue-router 的状态如何——它是否会很快获得 Vue 2 支持,还是需要在没有路由器的情况下完成 Vue 2 测试?
@gwildu他们很可能会一起发布,Vuex 2.0 将只支持 Vue 2.0。 Pre 2.0 Vuex 仍将获得支持,直到 Vue 1.x 不再受支持。
在 Vue 2.0 发布之前, @Uninen Vue Router 接下来会受到一些喜爱。
感谢您的信息@chrisvfritz :)
@chrisvfritz @Uninen更正:Vuex 2.0 也适用于 Vue 1.x。
vue-router
下一个主要版本将仅支持 Vue 2.x。
仅运行时构建:由于它不包括编译器,您需要在编译步骤中预编译模板,或者手动编写渲染函数。
是否有/将有一种方法可以在不使用 vueify/vue-loader 和.vue
文件的情况下预编译模板? 如果没有,使用 babel 插件将template:
属性转换render
组件中的
升级2.0后,deprecated的特性还能用不
可以先升级2.0,然后再慢慢把deprecated的特性改掉不
现在 elementDirective 消失了,是否可以创建终端组件?
如前所述:
v-model 不再关心初始内联值。 它将始终将 Vue 实例数据视为真实来源。
考虑一下
<child-component>
<input type="checkbox" :id="_uid" v-model="childModel" :value="value" />
<label :for="_uid"><slot></slot></label>
</child-component>
如何处理带有自定义组件之间的数组的复选框?
_更新 1:_
解决了。 将 prop type="checkbox"
传递给父组件中的子组件。
<parent-component>
<child-component type="checkbox" v-model="parentModel" value="apple" />
<child-component type="checkbox" v-model="parentModel" value="orange" />
<child-component type="checkbox" v-model="parentModel" value="banana" />
</parent-component>
然后你可以通过{props: [ 'value' ]}
获得内联值。
向父组件发出change
事件以告知值已更改。
<child-component>
<input type="checkbox" :id="_uid" v-model="childModel" :value="value"
@change="$emit('change', $event)"
/>
<label :for="_uid"><slot></slot></label>
</child-component>
这是因为编译器根据type
编译v-model
指令。 并且编译器将生成checked
属性并将change
事件绑定到它。
_更新 2:_
但是, updated
生命周期钩子不会触发,因为v-model
直接更改了checked
属性(这意味着您无法获得change
事件通过修改v-model
的值来创建原生 html 复选框组件。
那么, @yyx990803 ,您能否在v-model
更改后触发change
事件?
@YunSun-CN 我能够解决您的问题的唯一方法是添加一个特定于该值的属性 ala val,并使用它来设置实际值,然后只对 v-model 'input 发出更改' 事件。
@johnleider我写了一个自定义指令来模拟v-model
作用。
顺便说一句,您应该以严格的方式生成模型,不仅要检查type
prop,还要检查元素的 tagName。 否则,另一个带有type
属性的自定义组件可能会覆盖其默认模型行为。
你好。 我们知道发布日期吗?
@thanosalexander我们还没有决定日期,不。 我们刚刚在 2.0.0-bet.2 中对 Transition 系统引入了一些重大的突破性变化,这些变化必须经过全面测试。 所以在我看来,我们还需要几周的时间才能考虑发布。
好的..我会去的,然后..我认为通往马厩的步子不会太大! 谢谢
文档呢? Vue 被早期采用的原因之一是文档,这是现在阻碍我使用 v2 的唯一原因。 我看到了跟进文档的问题,但没有看到即将完成。 可能我忽略了引擎盖下发生的很多事情,为什么提出这个问题:)
有没有计划在 2.0 中的组件切换之外实现过渡模式?
https://github.com/vuejs/Discussion/issues/156
@miljan-aleksic 文档将在 2.0 正式发布时准备就绪。 我们仍处于测试阶段。 ;)
在此之前,您可以在此处关注文档的进展(甚至贡献)
@aristidesfl已经完成了。 🎉
@miljan-aleksic 除了@LinusBorg提到的内容可以在此处阅读源代码。 请记住,在撰写本文时,它还没有完全更新以反映beta.2 中的更改,重要的同行评审仍在进行中,并且正在考虑其他一些小的 API 更改。 因此,除非您想帮助修复拼写错误并改进解释,否则我建议您等到我们正式发布(可能在 RC 阶段)。
我们也同意优秀的文档是 Vue 的重要组成部分。 甚至 React 团队的Dan Abramov 也喜欢我们的文档。 😄 这就是为什么我的个人目标之一是 2.0 文档_甚至更好_。 与此同时……
这是我编写文档的主要资源之一,如果您熟悉 Jasmine,它们通常很容易阅读。
谢谢@chrisvfritz ,非常有用的信息。 我将考虑新文档的 WIP,并根据需要提供反馈。 是时候认真对待 Vue 2.0 了;)
createElement
在使用 on 的渲染函数中似乎没有处理数组(就像 snabbdom 那样)有没有办法将数据传递给被调用的函数?
例如在 snabbdom 我可以使用
{on:{click: [function, dataToPass]}}
而function
将获得dataToPass
作为第一个参数。 但这似乎在 vuejs 2 beta 2 Uncaught TypeError: arr[i] is not a function
出错了。 有没有办法使用 on from create 元素传递数据和事件?
@dubcanada Vue 2.0 中的事件处理与 snabbdom 的不同 - 您必须自己编写函数。 数组语法只是将多个处理程序附加到同一事件。
我试图将插槽内容作为字符串而不是呈现它们。 使用标准节点有一个简单的解决方法,但使用 Vnodes 我没有找到方法。 有什么解决方法吗?
@miljan-aleksic 尝试渲染它,使用innerHTML
获取元素的内容,然后在 css 中使用display: none
隐藏元素。
谢谢您的帮助。 如果我渲染它,最终的输出会有所不同。 我正在创建一个组件,它将用pre
标签包装其子内容并对 HTML 进行编码。
在这种情况下,在与原始元素不同的元素中呈现输出。
尽管我会指出模板不应该成为您编写内容的方式。 它应该是描述_如何_编写内容的方式,而不是内容本身。 我建议将文本存储为 JS 中的字符串(或作为项目中其他地方的资源,_特别是_如果它是某种用户输入),然后将其作为道具传递给孩子,这应该会使事情发生一千次反正更容易。
你是对的@Kingdaro ,最好不要混淆概念并保持简单。 不过,拥有 hihgligthig 语法还是不错的 :)
使用v-on
指令时, $arguments
变量不再可用。 我在这里没有看到有关该更改的任何参考。 是错误还是缺少参考?
@ miljan-aleksic 只需使用arguments
。
必须是 PHP 开发人员(像我一样)...我知道你的感受。 哈哈!
斯科特
@ yyx990803,@smolinari我...和尴尬的一个,现在哈哈。 我让自己相信我已经尝试过了……似乎我做得还不够好。 它正在工作,感谢并抱歉浪费了您的时间。
我正要开一张关于另一个“问题”的票,但不确定它是否是...当使用ref
,注册的组件或元素不能立即使用,所以这样的事情是行不通的。
<button ref="button"...></button>
<foo :connect="$refs.button"></foo>
在 Foo 被渲染时$refs.button
仍然未定义。 在 Vue 1 中按预期工作。 这次我错过了什么?
你错过了你不应该将 DOM 元素或组件实例作为道具传递......
为什么这是个坏主意? 假设我有一个 Dropdown 组件,我想将它连接到一个 Button(触发器)。 两者都是独立的组件,我直接传递引用而不是通过查询连接它们。
@miljan-aleksic 最好通过状态连接它们:
这样下拉和按钮就完全解耦了,按钮可以复用来控制其他类型的组件,下拉可以被其他类型的输入组件控制。
旧习惯不容易改掉。 我应该责怪jQuery还是主要怪我? :D
埃文,你的方法是正确的。 即使这意味着 Dropdown 集成会更乏味,我也会这样做。 由于父组件必须知道如何侦听不同的事件,不仅是在单击外部时打开和关闭下拉菜单,而不是它本身的下拉菜单等。下拉列表正在解决的许多事件和变通方法。
由于父组件必须知道如何侦听不同的事件,不仅是在单击外部时打开和关闭下拉菜单,而不是它本身的下拉菜单等。下拉列表正在解决的许多事件和变通方法。
还可以吗? 你完全可以从下拉组件中执行addEventListener('body', ... )
来注册外部点击等等......当有人点击外部时,下拉可以简单地为父级发出“关闭”事件,例如。
是的,是的。 是时候重构一些组件了 :) 谢谢大家! 很棒的社区。
如何将v-model
应用于带有createElement
? 我使用模板编译器查看了生成的代码,并且……代码很多。 我不太了解那里关于指令的文档。
默认情况下,编译时指令将提取该指令,并且该指令在运行时不会出现。 如果您希望指令也由运行时定义处理,请在转换函数中返回 true。
@blocka如果您使用render
函数,则您无权访问内置指令。 您必须自己处理等效的逻辑。 例如v-if
只是一个三元表达式, v-for
是一个array.map()
表达式...和v-model
(在普通的<input>
元素上) 被转换为value
绑定和input
事件侦听器。
@yyx990803这就是我的想法。 我可能会用 HOC 处理这个问题(我已经用同样的方式处理条件了(虽然我正在考虑使用这个)
在 vue 1 中,vuex 与 redux 有两个明显的优势。
使用虚拟 dom 是否可以缓解部分或全部 1?
@blocka它确实减轻了一些影响,但整体性能仍然会比 Redux 好得多。
2.0 中改变的是反应性的粒度。 我们来做个对比:
shouldComponentUpdate
以获得更好的性能。一般用2.0,你会看到(对比1.x)
嘿,
我没有使用animated.css 进行转换工作。
<transition enterClass="fadeIn" leaveClass="fadeOut" class="animated" mode="out-in">
<router-view keep-alive></router-view>
</transition>
有人有想法吗?
你的道具名称是错误的。
camelCase vs kebap-case在 2.0 中仍然适用。
<transition enter-class="fadeIn" leave-class="fadeOut" class="animated" mode="out-in">
<router-view keep-alive></router-view>
</transition>
@LinusBorg对不起,我已经试过了。 在这里,我有一个小小提琴。 使用 css 过渡和名称标签,它可以正常工作。
https://jsfiddle.net/z0nyfba0/
在组件上使用v-model
时,组件是否可以看到与v-model
一起使用的任何修饰符?
例如,如果我有一个发出input
事件的组件,则何时发出该事件取决于是否使用了lazy
修饰符。
@fergaldoyle我玩了一点,我认为您不能在自定义元素上使用 v-model 修饰符,因为您需要手动发出输入事件。 如果你想实现懒惰的行为,你需要将change
事件绑定到输入,例如https://jsfiddle.net/cynhtLty/1/
@calebboyd
https://jsfiddle.net/Linusborg/z0nyfba0/1/
enter-active-class
和leave-active-class
class="animated"
放在<router-view>
元素上。@fergaldoyle根据 1.0 文档,我认为使用lazy
,v-model 只会对change
而不是input
。 您可以使用它来更改行为,并根据是否给出lazy
发出input
或change
以给出不同的结果。
在玩一个简单的v-for
示例时,我一直在挠头。 出于某种原因, value
绑定不适用于 2.0 中的select
元素: https :
此外,可能应该在文档中指出,像"i in 10"
这样的 v-for 范围从 1 开始,而不是 1.0 中的 0。
为什么 vm.$get 已被弃用?
为什么不是 Vue.get 呢?
这对于评估这样的计算表达式非常有用var exp = 'entity.type.name' // this is generated in runtime
return vm.$get(exp)
@iagafonov没有很多场景有用,因此它不应该是核心的一部分。
如果您需要少数场景之一的功能,您可以在例如 lodash 的帮助下非常轻松地添加类似的行为:
import get from 'lodash/get';
Vue.prototype.$get = get
//in any component
var value = this.$get(this.someObject,'some.path.to.value')
(当然,您也可以将其作为“类方法”添加为 Vue.get() - 或者只需将其导入本地您需要的地方 - 您的选择)
@LinusBorg。 首先,我不使用 lodash 或类似的东西。
其次 lodash 的实现很慢,因为它在运行时尝试深入到表达结构中。 vue 遵守新的指定函数(通过 parseExpression),绑定到作用域。
这不是微不足道的部分,重新实现这一点非常困难。
当然,每次 $get 编译函数)。 例如,如果 parseExression 成为 Vue.util 中 api 的一部分,那就太好了。
@iagafonov this.$get
还必须在运行时解析路径并动态检索值。 否则,如果路径不存在,您将收到错误消息。 在大多数情况下,性能差异也可以忽略不计。 如果你不想要 lodash,那么还有很多其他的路径检索库。 它不再是 Vue 关心的一部分。
现在已弃用的 param 属性有哪些替代方案?
你在谈论指令中的参数吗? 然后你可以在 vnode 对象中找到所有绑定的属性
<button v-test="123" color="red" type="button">click me</button>
bind (el, binding, vnode) {
// vnode.data.attrs -> { color: 'red' }
}
@sqal ,这是在回答我的问题吗? 如果是这样,我说的是 param 属性,例如lazy、number 和 debounce。 例如,在 2.0 之前,我可以这样做<input type="text" v-model="msg" number>
(这里的数字是一个参数属性)。 如何在不使用 param 属性的情况下获得相同的结果?
@p-adams 在帖子中提到 - 它们现在是修饰符<input v-model.number="msg">
我发现在Vue 2.0中,当props改变时,总是调用render函数,所以我想知道2.0是否支持shouldComponentUpdate
来决定是否重新渲染。
@yyx990803好的,我现在在帖子The lazy and number params are now modifiers
看到
@HeChenTao Evan 在这里解释了一点https://medium.com/the-vue-point/announcing-vue-js-2-0-8af1bde7ab9#.pc5c8urbv
@HeChenTao渲染函数并不“总是”调用,只有在需要时才调用:
shouldComponentUpdate
,因为它的反应性。同样的事情可以在与 mobx 的反应中完成。 我相当确定您不必实现shouldComponentUpdate
。 但是,和 vue 一样,mobx 也坚持可变状态。 如果出于某种原因,您已经接受了不可变状态的概念。 在这种情况下,react 支持shouldComponentUpdate
。
那么这是否意味着如果有人坚持不可变状态,vue 将不会是一个很好的匹配?
功能组件的上下文参数有children
加上slots
。 我发现children()
和slots().default
完全相同,这让我有点困惑。 让我想知道什么是正确的方法。 可能作为插槽的“孩子”很懒惰,但为什么还要支持两种不同的方式来获得相同的行为?
功能组件只是函数,因此它们没有子组件。 恕我直言,孩子们应该被弃用,只是保持插槽不懒惰。
@blocka你可以实现反应式数据与 mobx 反应,真的。 但反应性是 Vue 功能的核心。 所以如果那不是一个人的那杯茶,那人就错了。
@miljan-aleksic children
是原始的(你得到每个节点,不管它们应该进入哪个槽), slots
将根据传入子节点的slot
名称解析。
谢谢@yyx990803。 @chrisvfritz,也许文档中有关此的更多详细信息可以避免混淆。
@ miljan-aleksic 我会添加一个注释。 👍
关于过滤器,使用计算属性似乎很简单,但是如何处理将过滤器与 v-model 一起使用的情况。 如果想通过在输入字段中输入来过滤名称列表,在 2.0 中如何做到这一点?
关于在模板中未使用数据字段/计算属性时让 Vue 发出警告的想法? 我想这里有一些限制,但是知道在哪里我可以负担得起在不需要的地方撤出一些无用的商店进口商品会非常有帮助。
@yyx990803 ,您如何看待将$context
引用设置为 Component 原型? 与$parent
或$root
我发现自己经常访问当前只能通过$vnode
对象访问的上下文。
实际上,这似乎不是访问上下文的可靠方法。 应该怎么做?
@miljan-aleksic 你能分享一下你经常访问上下文的用例吗?
@Kingdaro你能
@p-adams 您仍然可以将计算属性与Array.prototype.filter
。
@chrisvfritz ,基本上用于解决方法,例如在孩子期望的上下文中设置变量。 或者在 Vue 自己之前设置一个对组件的引用。
我同意并非所有人都通用,但至少应该有一种可靠的方法可以在组件内访问它。 $vnode 在使用模板安装组件之前不存在(至少到目前为止我的结论是)。
我会满足于知道如何以适当的方式访问它。
$context
有用的另一种情况是将一个组件重用为另一个组件的根。
<template>
<Foo>
<child/>
</Foo>
</template>
<script>
{ name: 'Bar' ... }
</script>
在示例中, child.$parent
将返回组件 Foo 而不是 Bar,这是正确的,但如果父级和子级相互依赖,则它们之间的直接通信可以通过上下文进行。
@miljan-aleksic 我会把这个留给 @yyx990803。 我想说,就像$parent
,在 99.9% 的情况下,达到$context
可能是错误的方式,我想我可能永远不会使用它。
我有v-show
和转换的情况。 在这种情况下,CSS 中有一个模态默认为“显示:无”。 当与v-show
结合使用时,它永远不会显示,因为该指令删除了 display 属性,然后 CSS 将保留。 我无法更改 CSS(项目要求),也无法使用自定义指令,因为 Vue 转换似乎特别依赖于它。
我现在在想,在 v-show 之后立即评估的指令可以将显示属性设置为阻止。 需要尝试一下,但无论如何,将修饰符添加到 v-show 以允许将显示设置为块或内联块可能是个好主意。 只是一个想法。
@chrisvfritz ,预计对于功能组件,父引用不是它们被用作插槽的直接父,而是上下文组件?
如果模板在 2.0.0-beta7 中包含“<”(可能还有其他 html 敏感字符),则编译失败
https://jsfiddle.net/x0r59ur1/
这在 1.0.26 中有效。
用“<”转义“<”解决了这个问题。
@GlurG预计会正确转义“<”。
@yyx990803 ,如果我想在相同类型的组件列表上使用转换并保持它们的状态,我应该怎么做? 按照文档,我只看到组件不同时的情况。
让我们说一个 Tab 组件并转换它的项目。 我找不到方法:(
<tabs>
<transition>
<tabs-item>Content 1</tabs-item>
<tabs-item>Content 2</tabs-item>
<tabs-item>Content 3</tabs-item>
<transition>
</tabs>
@miljan-aleksic <transition>
仅适用于单个元素。 多个项目需要<transition-group>
。
@yyx990803 ,也尝试过那个,但仍然不知道如何实现它。 Transition-group 通过添加/删除元素来工作,但这样做时组件将再次初始化,失去状态。 除了选项卡的想法是一次只显示一个组件,它不完全是一个列表:)
@ yyx990803,@LinusBorg我欣赏的帮助,但该解决方案并不明显。 我知道如何应用转换,我无法弄清楚如何keep-alive
转换的组件。
为清楚起见,我创建了一个新问题,其中包含 jsfiddle 示例,每次如何创建组件。
@yyx990803 ,非常感谢您改进保持活动功能,现在它按预期工作。
你真的改变了我的生活,通过你的产品和职业道德,我能够学习、构建和交付我长期处于待机状态的产品。 通过保持简单的方法,每个人都可以使用高科技来使用和构建。 对于这一切,我永远感激不尽。
@ miljan-aleksic 有一个Patreon 竞选活动使眼色。
你知道什么@phanan ,你是完全正确的。 我已经开始亲自支持 Evan,一旦公司产品开始产生效果,就会确保支持变得更加明显。
ready
生命周期钩子被弃用,取而代之的是mounted
; 但是根据更改日志,不能保证在调用 mount 之前会呈现组件。 当我想在组件初始化后初始化某些 jquery 组件(如 selectize)时,这会导致偶发错误。 我应该使用哪个生命周期钩子? 可以像这样模拟“就绪”钩子:
function mounted() {
Vue.nextTick(() => {
//...
});
}
@GlurG是的,那会奏效。 顺便说一句,在许多情况下,1.0 中的ready'()
也是必不可少的。
有什么理由不能为此提供一个钩子吗? 我也
跨越这个......即使在 1.0 中,并采取诸如循环使用 raf 之类的方法
检查它是否在 dom 中,等等。
2016 年 8 月 10 日下午 6:26,“Thorsten Lünborg”通知@github.com
写道:
@GlurG https://github.com/GlurG是的,这会起作用。 顺便说一下,
在许多情况下,1.0 中的 ready'() 也是必不可少的。—
你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/vuejs/vue/issues/2873#issuecomment -238903012,或者静音
线程
https://github.com/notifications/unsubscribe-auth/AACounAoI8p65soUUrbdaiwteDXKgMGJks5qee25gaJpZM4IedHC
.
使用渲染函数时,核心指令被忽略,这是合理的。 但是有些使用普通 js 并没有那么容易重现,因为v-model
具有适用于 IE9 的变通方法,并且可能解决其他边缘情况问题。
它让您重新考虑改用模板,但这在某些情况下是不可能的或最佳选择。 文档肯定可以提供有关此主题的更多指导,此外,在使用渲染函数时使用一些帮助程序可能是一个好主意,这将有助于解决这些常见情况并且不会让任何人错过模板。
@miljan-aleksic 抱歉,我删除了我的评论,因为我注意到它仅适用于 v-show 或自定义指令,是的,正如您在 v-model 的情况下所说,需要添加输入/更改侦听器并手动更新我们的数据
当激活/安装router-view
的路由被触发时,是否应该调用新的activated
钩子? 我目前没有看到这种行为。
@wprater不,它仅与<keep-alive>
与此无关。
@yyx990803我将我的路由器视图包装在保持活动状态中,但是当我返回到上一个视图时,我似乎找不到钩子。 mounted
和activated
被调用。 我需要确定 dom 已呈现。
@wprater请避免将此线程用于不相关的问题。 如果有错误,请在相应的 repo 中发布文件并进行复制。
Vue JSX 是否支持对象扩展运算符? 我试过了,但它不起作用。
确实如此, @yyx990803付出了很多努力才能让它发挥作用。
我正在做这个<Component {...{ props } }></Component>
并且它按照文档工作。
@blocka谢谢! 我认为不需要属性名称props
😂
@yyx990803
components
选项不支持数组类型,但它在 1.x 中有效。
例如
var Parent = Vue.extend({
name: 'parent',
template: '<div><slot></slot></div>'
})
var Child = Vue.extend({
name: 'child',
template: '<span>hello</span>'
})
new Vue({
el: '#app',
components: [
Parent,
Child
],
replace: false,
template: '<parent><child></child></parent>'
})
是bug?
@QingWei-Li 他们不再受支持,因为它从来不是正式记录的功能。 原因是在 ES2015 中你可以只写components: { Parent, Child }
。
只是一个小建议,
我们使用v-foreach
进行正常的数组迭代,我们使用v-for
范围是否有任何机会。
这对来自 php 的用户更有意义,甚至与 JQ 中的.each
或 JS 中的foreach
保持一致
@ctf0我们处于 RC 阶段,API 不会再改变。 我们也不会引入替代语法来做同样的事情。
我认为v-for="item in items"
的心理开销不足以保证这一点。
有了这个新版本,我会帮你处理这个案子。
我有一个日历组件(来自语义 ui),它使用经典的文本输入,并以人类格式显示日期(例如“2016 年 7 月 10 日”)。 在 v1.0 中,我使用双向过滤器将该字符串转换为正确的日期,以便我的对象数据可以直接提交。 但是由于过滤器在 v-model 中不再起作用,我现在如何在 v2.0 中做同样的事情?
谢谢
@shadowRR可以看到一些代码吗?
@p-adams 当然。 干得好。
首先是我的过滤器,它在我的 v-model 上用于我的日历输入。 它的唯一目的是在值更改时将正确的日期类型写入我的数据(postgres 日期)。
Vue.filter( 'formatDate', {
read( date ) {
return date;
},
write( date ) {
if( !date ) return null;
return moment( date, 'D MMMM YYYY' ).format( 'YYYY-MM-DD' );
}
} );
我会像这样在我的组件上使用它(输入有一个日历系统,它以人类可读的格式返回我的日期)
<div class="required field">
<label>Start date</label>
<div class="ui calendar">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input v-model="section.start | formatDate" type="text">
</div>
</div>
</div>
我错过了你正在谈论的帖子,会看到的,谢谢;)
你好,
我对新的生命周期钩子有一些疑问。
如果我想在挂载时注册一个事件处理程序,并在卸载前取消注册,我应该如何使它工作? 在 created 和 beforeDestroy 钩子中添加检查和逻辑?
在 Vue 1.x 中,我会使用附加和分离的钩子。
但是在 2.0 中有安装钩子但没有卸载钩子。 感觉有点不符合。
是否有任何原因不提供卸载挂钩?
@f15gdsy mounted
对应于destroyed
。 2.0 中没有attached
/ detatched
计数器部件 - 您需要自己进行内部检查。 如果您的活动不关心 in-dom/off-dom,那么mounted
和beforeDestroy
是合适的地方。
在自定义组件上使用时,v-on 现在只侦听该组件发出的自定义事件 $emitted。 (不再监听 DOM 事件)
我可能在这里错过了一些帖子,但这背后的设计决策是什么?
它会使在组件上绑定简单的点击事件变得非常冗长。
1.0:
<foo @click="bar"></foo>
2.0:
<div @click=bar>
<foo></foo>
<div>
@fnlctrl ,使用本机修饰符: @click.native="bar"
。
@miljan-aleksic 非常感谢! 我认为这个修饰符应该添加到Directives
-> v-on
-> modifiers
在这个问题中
我可以使用 Koa(1.x 或 2.x) 作为服务器吗? Koa 的vue-server-renderer
有问题吗?
@yyx990803
import Vue from 'vue'
Vue.component('expanding', {
functional: true,
render (createElement, { children }) {
const data = {
props: {
name: 'expanding',
},
on: {
beforeEnter ($el) {
$el.classList.add('collapse')
console.log('beforeEnter')
},
enter ($el) {
$el.classList.remove('collapse')
$el.classList.add('collapsing')
$el.style.height = `${$el.scrollHeight}px`
console.log('enter')
},
afterEnter ($el) {
$el.classList.remove('collapsing')
$el.classList.add('collapse', 'in')
console.log('afterEnter')
},
beforeLeave ($el) {
$el.classList.add('collapsing')
$el.classList.remove('collapse', 'in')
$el.style.height = 0
console.log('beforeLeave')
},
leave ($el) {
console.log('leave')
},
afterLeave ($el) {
$el.classList.remove('collapsing')
$el.classList.add('collapse')
$el.style.display = 'none'
console.log('afterLeave')
}
}
}
return createElement('transition', data, children)
}
})
<a href="#" :aria-expanded="showItem ? 'true' : 'false'" @click="showItem = !showItem">
<span class="icon is-small"><i class="fa fa-table"></i></span>
Tables
<span class="icon is-small is-angle"><i class="fa fa-angle-down"></i></span>
</a>
<expanding appear="true">
<ul v-show="showItem">
<li>
<router-link to="/tables/basic">Basic</router-link>
</li>
<li>
<router-link to="/tables/handsontable">Handsontable</router-link>
</li>
</ul>
</expanding>
为什么不调用 enter 钩子?
@fundon你应该在论坛或gitter chat上
锁定此线程是因为:
如果您有错误,请按照问题报告指南打开一个单独的问题,如果您有问题,请使用论坛或 gitter。
更新:有关 2.0 中更明确和详细的更改列表,请参阅新的迁移指南。
最有用的评论
@chrisvfritz @Uninen更正:Vuex 2.0 也适用于 Vue 1.x。
vue-router
下一个主要版本将仅支持 Vue 2.x。