08-手动实现一个v-model-以及妙用

第一种方法:

父组件:

 1 <template>
 2   <div class="father">
 3       <p>{{name}}</p>
 4       <son v-model="name"></son>
 5       <!-- 等同于下面,因为model就是代表的value -->
 6       <!-- <son type="text" :value="name" @input="name=子组件传回来的值"> -->
 7 </div>
 8 </template>
 9 
10 <script type="text/javascript">
11 import Son from './son'
12 export default {
13   name: "",
14   data() {
15     return {
16         name:'123',
17     }
18   },
19   components: {
20       Son
21   }
22 }
23 </script>

子组件:

 1 <template>
 2   <div class="son">
 3       <input type="text" :value="value" @input="tellFather">
 4   </div>
 5 </template>
 6 
 7 <script type="text/javascript">
 8 export default {
 9   props:{
10       value:{
11           type: String,
12           defalut : ''
13       }
14   },
15   methods:{
16     tellFather(e){
17       this.$emit('input',e.target.value)
18     },
19   },
20 }
21 </script>
22 <style>
23 input{
24   border: 1px solid #666;
25 }
26 </style>

第二种方法:

父组件不变,子组件:

 1 <template>
 2   <div>
 3     <input type="text" :value="myVal" @input="tellFather" />
 4   </div>
 5 </template>
 6 
 7 <script type="text/javascript">
 8 export default {
 9   model:{
10     prop:'myVal',      //指定传过来的自定义名字作为value
11     event:'myEvent'   //可以自定义事件名,这个事件名就作为发送给父组件的事件名
12   },
13   props: {
14     myVal: {         //自定义传过来的value名字
15       type: String,
16       defalut() {
17         return "";
18       }
19     }
20   },
21   methods:{
22     tellFather(e){
23       this.$emit('myEvent',e.target.value)
24     },
25   },
26 };
27 </script>
28 <style>
29 input{
30   border: 1px solid #666;
31 }
32 </style>

一种非常绝妙的用法:

父组件中用v-model一个空对象,子组件去收这个对象,并用这个对象绑定到子组件上的各种input和select的v-model上,这样这些输入框和下拉框的值发生改变,父组件传来的这个对象就能实时的拿到,这就是v-model的妙用,再也不用子组件去麻烦的再去传值了。绝!

(基于elementUi,在项目中有element的直接复制粘贴就可以运行)

父组件代码:

 1 <template>
 2   <div class="father">
 3     <Son
 4       :formData="searchOptions"
 5       labelWidth="120px"
 6       v-model="filterObject"  
 7     ></Son>
 8     <!-- 
 9       通过v-model,父组件可以直接使用子组件里变动的数据,再也不用子组件变了哪通过传递告诉父组件了,非常之方便啊!!
10      -->
11   <h1>
12     状态:{{filterObject.status}}
13   </h1>
14   <h1>
15     地区:{{filterObject.region}}
16   </h1>
17   <h1>
18     顾问名称:{{filterObject.userName}}
19   </h1>
20   <h1>
21     手机号:{{filterObject.phone}}
22   </h1>
23   </div>
24 </template>
25 
26 <script>
27 import Son from './son'
28 export default {
29   components: {
30     Son,
31   },
32   data() {
33     return {
34       searchOptions: [
35         {
36           type: 'select',
37           prop: 'status',
38           label: '状态:',
39           span: 5,
40           placeholder: '请选择',
41           arr: [
42             {
43               value: '1',
44               label: '全部招生顾问',
45             },
46             {
47               value: 2,
48               label: '正常招顾',
49             },
50             {
51               value: 3,
52               label: '冻结招顾',
53             },
54           ],
55         },
56         {
57           type: 'select',
58           prop: 'region',
59           label: '地区:',
60           span: 5,
61           placeholder: '请选择',
62           arr: [
63             {
64               value: 4,
65               label: '北京',
66             },
67             {
68               value: 5,
69               label: '许昌',
70             },],
71         },
72         {
73           type: 'text',
74           prop: 'userName',
75           span: 8,
76           label: '招生顾问名称:',
77           placeholder: '选择或输入搜索',
78         },
79         {
80           type: 'text',
81           prop: 'phone',
82           label: '手机号:',
83           span: 5,
84           placeholder: '选择或输入搜索',
85         },
86       ],
87       // 这里
88       filterObject: {},
89     }
90   },
91 }
92 </script>
93 <style>
94 .father{
95   padding: 30px;
96 }
97 </style>

子组件:

 1 <template>
 2   <div class="form-container">
 3     <el-form
 4       :model="getFatherObject"
 5       label-position="left"
 6       :label-width="labelWidth"
 7     >
 8       <el-row :gutter="10">
 9         <el-col
10           v-for="item in formData"
11           :key="item.prop"
12           :span="item.span || 8"
13         >
14         <!-- 把子组件中的输入框的v-model绑定上父组件的getFatherObject对象上,这样父组件中的getFatherObject就有自动有这个值 -->
15           <el-form-item :label="item.label">
16             <el-input
17               v-if="item.type === 'text'"
18               v-model="getFatherObject[item.prop]"
19               clearable
20               :disabled="item.disabled || false"
21               :placeholder="item.placeholder"
22             ></el-input>
23             <!-- 也把下拉框的v-model绑定上,父组件中的getFatherObject对象自然也就添加上了下拉框的值,
24             这里直接赋值给下拉框的v-model,就相当于原来的整了个事件去emit发送让父组件更新 -->
25             <el-select
26               v-if="item.type === 'select'"
27               v-model="getFatherObject[item.prop]"
28               clearable
29               :placeholder="item.placeholder"
30               @change="handleChange"
31             >
32               <el-option
33                 v-for="sub in item.arr"
34                 :key="sub.value"
35                 :label="sub.label"
36                 :value="sub.value"
37               ></el-option>
38             </el-select>
39           </el-form-item>
40         </el-col>
41       </el-row>
42     </el-form>
43   </div>
44 </template>
45 
46 <script>
47 export default {
48   model: {
49     // 这里指定收到父组件的value叫这个名字
50     prop: 'getFatherObject',
51     // event: 'change',
52   },
53   props: {
54     // 这里指定收到父组件的v-model(value) 是叫做getFatherObject
55     getFatherObject: {
56       type: Object,
57       default() {
58         return {}
59       },
60     },
61     labelWidth: {
62       type: String,
63       default: '80px',
64     },
65     formData: {
66       type: Array,
67       default() {
68         return []
69       },
70     },
71   },
72   data() {
73     return {}
74   },
75   methods: {
76     handleChange() {
77       // 这里就能随时得到getFatherObject最新值,父组件同样,因为父组件v-model了getFatherObject,妙啊!
78       // console.log(this.getFatherObject);
79     },
80  
81   },
82 }
83 </script>

感谢原文作者,让学到了一个非常好的方法

 

 

posted @ 2021-04-12 01:20  猎奇游渔  阅读(346)  评论(0编辑  收藏  举报