vue支持雙向數據流嗎?
除了最開始angularJs支持數據的雙向流動之外,其他兩大框架是均不支持的
vue之所以被常說數據流,其實是錯誤的。是因為它是雙向綁定被有些人理解為雙向數據流。
如果發現了一下的錯誤信息,那就是你違反了不能雙向數據流的規定
vue.runtime.esm.js?2b0e:619 [Vue warn]:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
Instead, use a data or computed property based on the prop's value. Prop being mutated: "userName"
雙向數據流的利弊
首先肯定,弊肯定是大於利的,不然vue直接就支持‘雙向數據流’了。
弊端是數據流動不可追蹤,無法保證數據源的唯一性,一旦出現問題很難找到錯誤的位置。
優點是有的時候,在某些特定的場景下,會很方便。比如封裝的彈窗顯隱控制,表單數據等。
vue如何使用雙向數據流
1、props傳入引用類型
vue檢測props只能檢測基本類型的值,而對於復合類型(即對象),只能檢測引用地址有沒有變化,而屬性值變化,不會被加測到。
利用這一特性,我們可以偷偷的繞過“props是只讀的”這一檢測,來達到“雙向數據流”目的。
子組件
<template> <div class="hello"> 姓名:<input type="text" v-model="formData.name"><br/> 年齡:<input type="text" v-model="formData.age"> </div> </template> <script> export default { name: 'userInfo', props: { formData: Object } } </script>
父組件
<template> <div id="app"> <user-info :formData="userInfoForm"/> <button @click="getUserInfoForm">提交</button> </div> </template> <script> import UserInfo from './components/user-info.vue'; // 用戶信息表單 export default { name: 'app', components: { UserInfo }, data(){return{ userInfoForm:{ name:'小丁', age: 20 } }}, methods:{ getUserInfoForm(){ console.log(this.userInfoForm); } } } </script>
效果圖
2.利用.async來支持雙向數據流(原自定組件使用v-model)
父組件
<template> <div class="hello"> 姓名:<input type="text" :value="userName" @input="userNameChange"><br/> </div> </template> <script> export default { name: 'userInfo', props: { userName: String }, methods:{ userNameChange(e){ // 會直接修改父組件的數據 this.$emit('update:userName', e.target.value) } } } </script>
子組件
<template> <div class="hello"> 姓名:<input type="text" :value="userName" @input="userNameChange"><br/> </div> </template> <script> export default { name: 'userInfo', props: { userName: String }, methods:{ userNameChange(e){ // 會直接修改父組件的數據 this.$emit('update:userName', e.target.value) } } } </script>
原理
<user-info :userName.sync="userNameVal"/> <!-- 會被擴展為: --> <user-info :userName="userNameVal" @update:userName="val => userNameVal = val"/> 當子組件需要更新 userName 的值時,它需要顯式地觸發一個更新事件: this.$emit('update:userName', newValue)