V-model指令

     

    摘要

      限制

      v-model只能用在:<input>    <select>    <textarea>  <components>

     修饰符

  • .lazy - 取代 input 监听 change 事件
  • .number - 输入字符串转为数字
  • .trim - 输入首尾空格过滤

   

  基础用法

     v-model 会忽略所有表单元素的 valuecheckedselected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

   文本
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

多行文本
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

 

复选框

       单个复选框,绑定到布尔值

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

 

    多个复选框,绑定到同一个数组  

<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})

单选按钮
<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>

 

选择框

    单选时

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: '#example-5',
  data: {
    selected: ''
  }
})

       注意:如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

     多选时 (绑定到一个数组)

<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: '#example-6',
  data: {
    selected: []
  }
})

    用 v-for 渲染的动态选项  

<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
  el: '...',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

 

 

值绑定

 对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):

<!--看到这里上面的你都应该明白了-->
<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" value="a">

<!-- `toggle` 为 true 或 false -->
<input type="checkbox" v-model="toggle">

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

 思考:有时我们可能想把值绑定到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串。

 

修饰符

  .lazy

     在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
  .number

  如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<input v-model.number="age" type="number">
<!--这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串-->
<!--我想它主要是用来限制用户输入的时候只能是数字-->
  .trim
<!--如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符->
<input v-model.trim="msg">

 

  

在组件上使用 v-model

用自定义事件的表单输入组件

     讲这个前,首先我们要明白的是:  

<input v-model="something">
<!--它其实是个语法糖,而真正的其实如下:-->

<input
  v-bind:value="something"
  v-on:input="something = $event.target.value">

<!--所以在组件中使用时,它相当于下面的简写-->
<custom-input
  v-bind:value="something"
  v-on:input="something = arguments[0]">
</custom-input>

    看了上面我们就明白,父主键是无法直接向子主键传值的,它其实绑定了父主键的click事件。

    所以要让组件的 v-model 生效,它应该 (从 2.2.0 起是可配置的):

  • 接受一个 value prop
  • 在有新的值时触发 input 事件并将新值作为参数    
  案例:

   货币输入的自定义控件,限制最多小数点保留两位    

<currency-input v-model="price"></currency-input>

Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
      >\
    </span>\
  ',
  props: ['value'],
  methods: {
    // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
    updateValue: function (value) {
      var formattedValue = value
        // 删除两侧的空格符
        .trim()
        // 保留 2 位小数
        .slice(
          0,
          value.indexOf('.') === -1
            ? value.length
            : value.indexOf('.') + 3
        )
      // 如果值尚不合规,则手动覆盖为合规的值
      if (formattedValue !== value) {
        this.$refs.input.value = formattedValue
      }
      // 通过 input 事件带出数值
      this.$emit('input', Number(formattedValue))
    }
  }
})

     最后结果,就你可以没有小数,但如果有小数后面最后只能有两位小数

上面案例我理解的:

    slice方法

  

 

ref ($refs)用法

ref 有三种用法

1.ref 加在普通的元素上,用this.ref.name 获取到的是dom元素

2.ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。

3.如何利用v-for 和ref 获取一组数组或者dom 节点

一、ref使用在外面的组件上

HTML 部分

<div id="ref-outside-component" v-on:click="consoleRef">
    <component-father ref="outsideComponentRef">
    </component-father>
    <p>ref在外面的组件上</p>
</div>

js部分

var refoutsidecomponentTem={
        template:"<div class='childComp'><h5>我是子组件</h5></div>"
    };
    var  refoutsidecomponent=new Vue({
        el:"#ref-outside-component",
        components:{
            "component-father":refoutsidecomponentTem
        },
        methods:{
            consoleRef:function () {
                console.log(this); // #ref-outside-component     vue实例
                console.log(this.$refs.outsideComponentRef);  // div.childComp vue实例
            }
        }
    });

二、ref使用在外面的元素上

HTML部分

<!--ref在外面的元素上-->
<div id="ref-outside-dom" v-on:click="consoleRef" >
   <component-father>
   </component-father>
   <p  ref="outsideDomRef">ref在外面的元素上</p>
</div>

JS部分

var refoutsidedomTem={
        template:"<div class='childComp'><h5>我是子组件</h5></div>"
    };
    var  refoutsidedom=new Vue({
        el:"#ref-outside-dom",
        components:{
            "component-father":refoutsidedomTem
        },
        methods:{
            consoleRef:function () {
                console.log(this); // #ref-outside-dom    vue实例
                console.log(this.$refs.outsideDomRef);  //   <p> ref在外面的元素上</p>
            }
        }
    });

三、ref使用在里面的元素上---局部注册组件

HTML

<!--ref在里面的元素上-->
<div id="ref-inside-dom">
    <component-father>
    </component-father>
    <p>ref在里面的元素上</p>
</div>

JS部分

var refinsidedomTem={
        template:"<div class='childComp' v-on:click='consoleRef'>" +
                       "<h5 ref='insideDomRef'>我是子组件</h5>" +
                  "</div>",
        methods:{
            consoleRef:function () {
                console.log(this);  // div.childComp   vue实例 
                console.log(this.$refs.insideDomRef);  // <h5 >我是子组件</h5>
            }
        }
    };
    var  refinsidedom=new Vue({
        el:"#ref-inside-dom",
        components:{
            "component-father":refinsidedomTem
        }
    });

四、ref使用在里面的元素上---全局注册组件

HTML

<!--ref在里面的元素上--全局注册-->
<div id="ref-inside-dom-all">
    <ref-inside-dom-quanjv></ref-inside-dom-quanjv>
</div>

JS部分

Vue.component("ref-inside-dom-quanjv",{
        template:"<div class='insideFather'> " +
                    "<input type='text' ref='insideDomRefAll' v-on:input='showinsideDomRef'>" +
                    "  <p>ref在里面的元素上--全局注册 </p> " +
                  "</div>",
        methods:{
            showinsideDomRef:function () {
                console.log(this); //这里的this其实还是div.insideFather
                console.log(this.$refs.insideDomRefAll); // <input  type="text">
            }
        }
    });

    var refinsidedomall=new Vue({
        el:"#ref-inside-dom-all"
    });

 

 

  $emit理解

  关于$emit的用法

   1、父组件可以使用 props 把数据传给子组件。
   2、子组件可以使用 $emit 触发父组件的自定义事件。

子组件

<template>  
  <div class="train-city">  
    <span @click='select(`大连`)'>大连</span>  
  </div>  
</template>  
<script>  
export default {  
  name:'trainCity',  
  methods:{  
    select(val) {  
      let data = {  
        cityname: val  
      };  
      this.$emit('showCityName',data);//select事件触发后,自动触发showCityName事件  
    }  
  }  
}  
</script>  

父组件

<template>  
    <trainCity @showCityName="updateCity" :index="goOrtoCity"></trainCity> //监听子组件的showCityName事件。  
<template>  
<script>  
export default {  
  name:'index',  
  data () {  
   return {  
      toCity:"北京"  
    }  
  }  
  methods:{  
    updateCity(data){//触发子组件城市选择-选择城市的事件    
      this.toCity = data.cityname;//改变了父组件的值  
      console.log('toCity:'+this.toCity)        
    }  
  }  
}  
</script>  

结果为:toCity: 大连

 

在找个例子:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="counter-event-example">
            <p>{{ total }}</p>
            <button-counter v-on:increment1="incrementTotal"></button-counter>
            <button-counter v-on:increment2="incrementTotal"></button-counter>
        </div>
    </body>
    <script src="vue/vue.min.js"></script>
    <script>
        Vue.component('button-counter',{
            template:'<button v-on:click="increment">{{ counter }}</button>',
            data:function(){
                return {counter: 0}<!--组件数据就是这样的,函数式的,请注意-->
            },
            methods:{
                increment:function(){
                    this.counter += 1;
                    this.$emit('increment1',[12,'kkk']);<!--$emit-->
                }
            }
        });
        new Vue({
            el:'#counter-event-example',
            data:{
                total:0
            },
            methods:{
                incrementTotal:function(e){
                    this.total += 1;
                    console.log(e);
                }
            }
        });
    </script>
</html>

先看组件 button-counter

绑定了事件click————>increment

然后 this.counter += 1; this.$emit('increment1',[12,'kkk']);

这边就是触发事件 increment1,参考文献里面有点乱,这边是不是清晰多了

然后 <button-counter v-on:increment1="incrementTotal"></button-counter> 

v-on相当于监听吧,就触发 incrementTotal

输出// [12, "kkk"]

 

想的太多,做的太少,中间的落差就是烦恼,要么去做,要么别想 中尉【13】

 

 

 

Logo

前往低代码交流专区

更多推荐