The owner of the building recently practiced vue in the project, and encountered some pits during the project. Now record it.
First up code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <script src="vue.js"></script> <body> <div id="app"> <select name="" id="" @change="getCity(provinceId)" v-model="provinceId"> <option value="">Please choose</option> <option v-for="province in provinces" :value="province.id">{{province.text}}</option> </select> <select name="" id=""> <option value="">Please choose</option> <option :value="city.id" v-for="city in citys">{{city.text}}</option> </select> </div> </body> <script> new Vue({ el:'#app', data:{ provinces:[], provinceId:'', citys:[], areas:[] }, created:function() { this.areas = [ {text:'Guangdong Province',id:1,pid:0}, {text:'Shanghai City',id:2,pid:0}, {text:'Guangzhou City',id:11,pid:1}, {text:'zhongshan',id:12,pid:1} ]; var provinces=this.areas.filter(function (area) { return area.pid == 0; }); this.provinces = provinces; }, methods:{ getCity:function (id) { var citys=this.areas.filter(function (city) { return city.pid == id; }) this.citys = citys; } } }) </script> </html>
If you follow the usual usage habits, it seems that there is not much problem. When you switch the parent element, you can listen for the changes of the values of the change event linkage child elements, which is in line with the habit of using jQuery for many years. The effect is as follows:
image.png
What if there are multiple places on the page that use the same linkage effect? Let's see how it works, as shown in the figure.
<select name="" id="" @change="getCity(provinceId)" v-model="provinceId"> <option value="">Please choose</option> <option v-for="province in provinces" :value="province.id">{{province.text}}</option> </select> <select name="" id=""> <option value="">Please choose</option> <option :value="city.id" v-for="city in citys">{{city.text}}</option> </select> <select name="" id="" @change="getCity(provinceId)" v-model="provinceId"> <option value="">Please choose</option> <option v-for="province in provinces" :value="province.id">{{province.text}}</option> </select> <select name="" id=""> <option value="">Please choose</option> <option :value="city.id" v-for="city in citys">{{city.text}}</option> </select>
image.png
The results are mutually affected, which is not what we want to see.
My solution is to change cities to an array computed in real time instead of binding the same array as the existing one. The code is rewritten as follows:
<select name="" id=""> <option value="">Please choose</option> <option :value="city.id" v-for="city in getCity(provinceId)">{{city.text}}</option> </select> getCity:function (id) { var citys=this.areas.filter(function (city) { return city.pid == id; }) return citys; }
The results are as follows:
image.png
As you can see, there is no interaction now.
Summary: vue-like mvvm frameworks are bi-directionally bound to data and views, and change events are often used to manipulate data when views change. This is unnecessary in mvvm frameworks. The framework itself has mapped the changes of views to data, so most change event monitoring is unnecessary, corresponding to vue. It can be rewritten to methods or computed to compute properties.