[前端] VUE基础 (3) (computed计算属性、watch侦听器、v-model双向绑定、v-model修饰符)

一、计算属性

当我们使用模板语言的时候,模板语言中可能会使用逻辑语句(函数调用等),如果业务比较复杂,我们的计算语句也会比较复杂,例如:

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

如上所示,在模板语言中计算message的翻转字符串。

我们可以使用计算属性,将计算翻转字符串的逻辑写到计算属性中:

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

这样,我们使用模板语言,就可以直接插入reversedMessage:

<div id="example">
  <p>message: "{{ message }}"</p>
  <p>reversed message: "{{ reversedMessage }}"</p>
</div>

二、侦听器

侦听器是用来侦听某个属性是否被改变的。例如修改message:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Watch</title>
</head>
<body>
<div id="app">
    <p>{{ message }}</p>
    <button @click="clickHandler">修改</button>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message: "leo"
            }
        },
        methods: {
            clickHandler() {
                this.message = 'Alex';
            }
        },
        watch: {
            'message': function (value) {
                //todo...
                alert("message被修改了");
            }
        }
    })
</script>
</body>
</html>

当我们点击修改按钮的时候,message从"leo"被修改为"Alex",此时该修改操作会被watch侦听器所发现,并在修改之前(执行clickHandler之前)执行我们所指定的匿名函数,在页面上弹出alert框。

三、v-model双向数据绑定

v-model实现双向数据绑定的意思是,我们可以在一些输入标签(text输入框、textarea、select、checkbox等)使用v-model,使其值与某个vue属性绑定。

当我们在输入框中输入字符时,vue对应的属性值也同步变化。这就是数据双向绑定。

1.手工实现简单的双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>双向绑定</title>
</head>
<body>
<div id="app">
    <input type="text"  @input="changeHandler" :value="message">
    <br>
    {{message}}
    <button @click="clickHandler">leo</button>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message: ""
            }
        },
        methods:{
            clickHandler(){
                this.message = "leo";
            },
            changeHandler(e){
                this.message = e.target.value;
            }
        }
    })
</script>
</body>
</html>

当我们修改text输入框的值时,触发oninput事件,changeHandler函数被执行,将输入框中的值赋值给message。

然后使用v-bind:value来绑定value和message的值,完成另一个方向的绑定。(这里使用v-bind,而不是真正的手工实现。真正的实现,应该要借助于侦听器,侦听message值的变化,并赋值给text标签的value)

2.v-model双向绑定简单例子

标签-->属性的绑定方向:

简单例子:

<body>
<div id="app">
    <input type="text" v-model="message">
    <p>{{message}}</p>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message: ""
            }
        }
    })
</script>
</body>

我们给text输入框绑定了message属性,message的初始值是空字符串,实现效果:

3.v-model简单例子2

属性-->标签的绑定方向:

当我们直接在某个事件函数中修改message属性的值,输入框中的值也会对应发生同步变化:

<body>
<div id="app">
    <input type="text" v-model="message">
    <br>
    <button @click="changeValue">将message的值修改为"hello world"</button>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message: ""
            }
        },
        methods:{
            changeValue(){
                this.message = "hello world";
            }
        }
    })
</script>
</body>

实现效果:

当我们点击"将message的值修改为'hello world'"按钮是,text中的值也改变了。

4.各种表单输入标签的双向绑定

主要是注意每种输入标签绑定的值的类型,例如bool、列表、字符串。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>双向绑定</title>
</head>
<body>
<div id="app">
    <div> <!-- text输入框 -->
        <input type="text" v-model="message">
    </div>
    <div> <!-- textarea输入框 -->
        <textarea v-model="message" placeholder="add multiple lines"></textarea>
    </div>
    {{message}}
    <hr>
    <div> <!-- 单个复选框 -->
        <input type="checkbox" id="checkbox" v-model="checked">
        <label for="checkbox">{{ checked }}</label>
    </div>
    <hr>
    <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>
    <hr>
    <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>
    <hr>
    <div id="example-5"> <!-- select 单选 -->
        <select v-model="selected">
            <option disabled value="">请选择</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
        <span>Selected: {{ selected }}</span>
    </div>
    <hr>
    <div id="example-6"> <!-- select多选 -->
        <select v-model="multiselected" multiple style="width: 50px;">
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
        <br>
        <span>Selected: {{ multiselected }}</span>
    </div>
    <hr>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message: "",  // text和textarea文本输入框
                checked: false,  // 单个复选框
                checkedNames: [],  //多个复选框
                picked: '',  // 单选按钮
                selected: '',  // select,单选时
                multiselected: []  // select,多选时
            }
        },
        methods: {}
    })
</script>
</body>
</html>

实现效果:

5.v-for实现动态选项

<body>
<div id="app">
    <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
        {{ option.text }}
        </option>
    </select>
<span>Selected: {{ selected }}</span>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                selected: 'A',
                options:[
                    { text: 'One', value: 'A' },
                    { text: 'Two', value: 'B' },
                    { text: 'Three', value: 'C' }
                ]
            }
        }
    })
</script>
</body>

select标签中的option是使用v-for遍历options列表属性动态生成的。

6.v-model与v-bind配合实现动态值绑定

<body>
<div id="app">
    <input id='rad1' type="radio" v-model="pick" v-bind:value="a">
    <label for="rad1">Leo</label>
    <input id='rad2' type="radio" v-model="pick" v-bind:value="b">
    <label for="rad2">Alex</label>
    <br>
    pick:{{pick}}
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                pick: '',
                a: {name: 'leo'},
                b: {name: 'alex'}
            }
        }
    })
</script>
</body>

实现结果:

我们发现,v-model双向绑定的属性pick的值是来自value属性的,value属性由和a、b绑定,a、b可能是字符串、布尔值、或者对象等任意类型。

在5.中,也是这种用法,而且5.中使用的是循环获取动态值来产生动态选项。

四、v-model修饰符

1.lazy

lazy修饰符的作用是当我们进行了双向绑定后,在我们输入的使用,不对绑定的属性赋值,而是等我们输入完后使用回车,或光标切换到其他标签时,值才会赋予绑定的属性:

<body>
<div id="app">
    <input type="text" v-model.lazy="message"/>
    <br>
    message:{{message}}
    <br>
    <input type="text"/>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                message:""
            }
        }
    })
</script>
</body>

实现效果:

2.number

number修饰符是让输入框中只有输入数字才有效(输入e3或e-3这种科学计数法可以)。

<body>
<div id="app">
    <input type="text" v-model.number="number"/>
    <br>
    message:{{number}}
    <br>
    <input type="text"/>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                number:0
            }
        }
    })
</script>
</body>

实现效果:

3.trim

trim修饰符是清除输入数据前面和后面的空格。

<body>
<div id="app">
    <input type="text" v-model.trim="trimedstring"/>
    <br>
    trimedstring:{{trimedstring}}
    <br>
    <input type="text"/>
</div>
<script src="static/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                trimedstring:''
            }
        }
    })
</script>
</body>

实现效果:

注意,字符串中间有空格的话,不管有多少个,都只保存一个空格。前面的空格会被直接去掉。

 

 

 

☜(ˆ▽ˆ)

posted @ 2020-02-04 21:58  风间悠香  阅读(1208)  评论(0编辑  收藏  举报