Vue2.0的变化

因为学习vue的视频讲解使用的是1.x的版本,而vue-cli当初默认下载的是vue2.0的版本,所以在学习过程中,会发现有许多东西都发生了改变,今天我就写一下我遇到的问题以及如何解决。

模板

1.x允许

1
2
3
4
<template>
<div class="one"></div>
<div class="two"></div>
</template>

但2.0会报错,它只允许只有一个父元素,所以应该

1
2
3
4
5
6
<template>
<div>
<div class="one"></div>
<div class="two"></div>
</div>
</template>

ref

v-refv-el弃用,统一使用ref属性为元素或组件添加标记,然后通过this.$refs获取。
Html部分:

1
<div ref="oneDiv"></div>

Js部分

1
this.$refs.oneDiv

对了,顺带一提,因为v-refv-el是支持短横分隔命名(kebab-case),所以一开始我也在ref用这种写法,发现控制台出现cannot read property ‘xxx’ of undefined
出现这种情况通常是因为对象获取失败出现的,检查一下哪部分命名出错了。所以我把它改成camelcase写法,即驼峰式写法,即可正确获取.

v-for中常用的$index

v-for循环中常用的$index$key也已不支持使用,trackby被key属性替换。
Html部分:

1
2
3
<ul>
<li v-for="item in items"></li>
</ul>

1
2
3
<ul>
<li v-for="(item,key) in items"></li>
</ul>

过渡

这个改变挺大的,vue2.0提供了这个内置组件,我们使用这个组件来包裹需要执行动画的元素,再添加name属性
Html部分:

1
2
3
<transition name="fade">
<div v-if="ok">Hello World!</div>
</transition>

CSS部分:

1
2
3
4
.fade-enter{}
.fade-enter-active{}
.fade-leave{}
.fade-leave-active{}

fade只是随机取的,name属性的值是什么,就进行相应改动。

父子组件props双向绑定

vuejs2.0中,任何试图在组件内修改通过props传入的父组件数据都被认为是错误的,报以下错误:

1
2
Avoid mutating a prop directly since the value will be
overwritten whenever the parent component re-renders

1.x版本好像使用events和$dispatch来实现,但我没用过没什么印象,直接写2.0的解决方法。

在Vue2.0中,实现组件属性的双向绑定方式

拿项目举例子:

  1. 在组件内的data对象中创建一个props属性的副本
    因为我要修改的数据是selectType和onlyContent,这两个数据都是父组件传递过来的

    1
    2
    3
    4
    5
    6
    data: function () {
    return {
    mySelectType: this.selectType,
    myOnlyContent: this.onlyContent
    };
    }
  2. 创建针对props属性的watch来同步组件外对props的修改

    1
    2
    3
    4
    5
    6
    7
    8
    watch: {
    selectType: function (val) {
    this.mySelectType = val;
    },
    onlyContent: function (val) {
    this.myOnlyContent = val;
    }
    }

此时在组件外修改了组件的props,会同步到组件内对应的props上,但是不会同步到你刚刚在data对象中创建的那个副本上,所以需要再创建一个针对props属性的watch(监听),当props修改后对应data中的副本也要同步数据。

  1. 创建针对props副本的watch,通知到组件外
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    watch: {
    selectType: function (val) {
    this.mySelectType = val;
    },
    mySelectType: function (val) {
    this.$emit('on-type-change', val);
    },
    onlyContent: function (val) {
    this.myOnlyContent = val;
    },
    myOnlyContent: function (val) {
    this.$emit('on-only-change', val);
    }
    }

此时在组件内修改了props的副本,组件外不知道组件内的props状态,所以需要再创建一个针对props副本,即对应data属性的watch。
在组件内向外层(父组件)发送通知,通知组件内属性变更,然后由外层(父组件)自己来变更它的数据。

  1. 父组件添加v-on事件
    1
    2
    3
    <ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" 
    :ratings="food.ratings" @on-type-change="onTypeChange" @on-only-change="onOnlyChange">
    </ratingselect>

最后在methods注册

1
2
3
4
5
6
7
8
methods: {
onTypeChange: function (val) {
this.selectType = val;
},
onOnlyChange: function (val) {
this.onlyContent = val;
}
}

至此,实现了组件内数据与组件外的数据的双向绑定,组件内外数据的同步。

详细参考

vue-router