Vue基础语法

学前准备

vue官网:https://cn.vuejs.org/

工具: webstorm, vscode

Vue基础

初体验

<div id="app">{{message}}</div>

<script>
    // 声明式编程
    const app = new Vue({
        //用于挂载要管理的元素
        el: '#app',
        // 定义数据
        data: {
            message: '你好, 李银河!'
        }
    })
</script>

效果

你好, 李银河!

列表展示

<body>
    <div id="app">
        <ul>
            <li v-for="item in movies">{{item}}</li>
        </ul>
    </div>

    <script>
        const app = new Vue({
            el: '#app',
            data:{
                message: "电影名单",
                movies:['星际穿越', '大话西游', '少年派', '盗梦空间']
            }
        })
    </script>
</body>

效果展示

image

浏览器追加数据

app.movies.push('海王')

image

小案例:计数器

<div id="app">
    <h2>当前计数:{{counter}}</h2>
    <button @click="add">+</button>
    <button @click="sub">-</button>
</div>

<script>
    const app = new Vue({
        el: '#app',
        data:{
            counter:0
        },
        methods:{
            add: function () {
                this.counter++
            },
            sub:function () {

                if(this.counter <= 0){
                    this.counter = 0;
                }else if(this.counter>0){
                    this.counter--;
                }

            }
        }
    })
</script>

实现效果

image

mvvm思想

mvvm简介

MVVMModel–view–viewmodel)是一种软件架构模式

MVVM有助于将图形用户界面的开发与业务逻辑后端逻辑(数据模型)的开发分离开来,这是通过置标语言或GUI代码实现的。MVVM的视图模型是一个值转换器,[1] 这意味着视图模型负责从模型中暴露(转换)数据对象,以便轻松管理和呈现对象。在这方面,视图模型比视图做得更多,并且处理大部分视图的显示逻辑。[1] 视图模型可以实现中介者模式,组织对视图所支持的用例集的后端逻辑的访问。

MVVM是马丁·福勒的PM(Presentation Model)设计模式的变体。[2][3] MVVM以相同的方式抽象出视图的状态和行为,[3] 但PM以依赖于特定用户界面平台的方式抽象出视图(创建了视图模型)。
MVVM和PM都来自MVC模式。

MVVM由微软架构师Ken Cooper和Ted Peters开发,通过利用WPF(微软.NET图形系统)和Silverlight(WPF的互联网应用派生品)的特性来简化用户界面的事件驱动程序设计。[3] 微软的WPF和Silverlight架构师之一John Gossman于2005年在他的博客上发表了MVVM。

MVVM也被称为model-view-binder,特别是在不涉及.NET平台的实现中。ZK(Java写的一个Web应用框架)和KnockoutJS(一个JavaScript)使用model-view-binder。[3][4][5]

MVVM模式的组成部分

  • 模型

    模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。

  • 视图

    就像在MVCMVP模式中一样,视图是用户在屏幕上看到的结构、布局和外观(UI)。[6]

  • 视图模型

    视图模型是暴露公共属性和命令的视图的抽象。MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信。[7]

  • 绑定器

    声明性数据和命令绑定隐含在MVVM模式中。在Microsoft解决方案堆中,绑定器是一种名为XAML标记语言。[8] 绑定器使开发人员免于被迫编写样板式逻辑来同步视图模型和视图。在微软的堆之外实现时,声明性数据绑定技术的出现是实现该模式的一个关键因素。[4][9]

理论基础

MVVM旨在利用WPF中的数据绑定函数,通过从视图层中几乎删除所有GUI代码(代码隐藏),更好地促进视图层开发与模式其余部分的分离。[10] 不需要用户体验(UX)开发人员编写GUI代码,他们可以使用框架标记语言(如XAML),并创建到应用程序开发人员编写和维护的视图模型的数据绑定。角色的分离使得交互设计师可以专注于用户体验需求,而不是对业务逻辑进行编程。这样,应用程序的层次可以在多个工作流中进行开发以提高生产力。即使一个开发人员在整个代码库上工作,视图与模型的适当分离也会更加高效,因为基于最终用户反馈,用户界面通常在开发周期中经常发生变化,而且处于开发周期后期。

MVVM模式试图获得MVC提供的功能性开发分离的两个优点,同时利用数据绑定的优势和通过绑定数据的框架尽可能接近纯应用程序模型。[10][11][12] 它使用绑定器、视图模型和任何业务层的数据检查功能来验证传入的数据。结果是模型和框架驱动尽可能多的操作,消除或最小化直接操纵视图的应用程序逻辑(如代码隐藏)。

MVVM模式不同于MVC,在MVVM模式中,将ViewModel层绑定到View层后,它基本不使用点击事件,而是使用命令(Command)来控制。数据的显示也是不同于MVC,而是使用Binding来绑定相关数据。

值得一提的是,MVVM通常会使用属性更改通知,即数据驱动而不是事件驱动。在WPF中当数据发生改变时,会通过接口INotifyPropertyChanged通知到对应的组件绑定的数据,实现同步数据刷新。

MVVM简述

View层:

  • 视图层
  • 在我们前端开发中,通常就是DOM层。
  • 主要的作用是给用户展示各种信息。

Model层:

  • 数据层
  • 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
  • 在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。

VueModel层:

  • 视图模型层
  • 视图模型层是View和Model沟通的桥梁。
  • 一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
  • 另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

vue基础语法

v-once

  • 该指令之后不需要跟任何表达式
  • 该指令表示元素和组件直渲染一次,不会随着数据的改变而改变

示例

<body>
<div id="app">
    <h2>{{message}}</h2>
    <h2 v-once>{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '你好'
        }
    })
</script>
</body>

效果

image

v-html

  • 改指令往往会跟上一个string类型
  • 将string的html解析出来并进行渲染

实例

<div id="app">
    <h2>{{url}}</h2>
    <h2 v-html="url"></h2>
</div>


<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '',
            url: "<a href="https://cn.bing.com/?mkt=zh-cn">必应</a>"
        }
    })

</script>

效果

image

绑定属性:v-bind

<div id="app">
<!--    绑定属性-->
    <img :src="imageURL" alt="">
    <a :href="aHref">1234</a>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '',
            imageURL:'https://cn.vuejs.org/images/logo.svg?_sw-precache=346e12ee28bb0e5f5600d47beb4c7a47',
            aHref:'https://www.cnblogs.com/',
        }
    })
</script>

v-bind绑定class

<head>
    <meta charset="UTF-8">
    <title>v-bind绑定class</title>
    <style>
        .active{
            color: red;
        }
    </style>
</head>
<body>
<div id="app">
    <h2 :class="active">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: 'v-bind绑定class',
            active: 'active',

        }
    })
</script>
效果

image

小案例: 利用button按钮切换class
<head>
    <meta charset="UTF-8">
    <title>v-bind绑定class</title>
    <style>
        .active{
            color: red;
        }
    </style>
</head>
<body>
<div id="app">

    <h2 :class="{active: active, line:isLine}">{{message}}</h2>
    <button @click="btnClick">切换</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: 'v-bind绑定class',
            active: true,
            isLine:true,
        },
        methods:{
            // 状态切换
            btnClick: function () {
                this.active = !this.active
            }
        }
    })
</script>
点击切换按钮前

image

点击切换按钮后

image

v-bind绑定style

对象语法
<div id="app">
    <h2 :style = "{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2>
    <h2 :style = "getStyles()">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: 'Hello',
            finalSize: 100,
            finalColor: 'red',
        },
        methods:{
            getStyles: function () {
                return {fontSize: this.finalSize+ 'px', backgroundColor: this.finalColor}
            }
        }
    })
</script>

image

数组语法
<div id="app">
    <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: 'Hello',
            baseStyle:{backgroundColor: 'red'},
            baseStyle1:{fontsize: '100px'}
        }
    })
</script>

计算属性

示例

<div id="app">
    <h2>{{fullName}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '',
            firstName:'Lebron',
            lastName: 'James'
        },
        //计算机属性
        computed:{
            fullName: function () {
                return this.firstName + ' '+ this.lastName
            }
        }
    })
</script>

效果:

image

复杂些的

<div id="app">
    <h2>总价格:{{totalPrice}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            books:[
                {id:110, name: 'Unix编程艺术', price:119},
                {id:111, name: '代码大全', price:105},
                {id:112, name: '深入理解计算机原理', price:98},
                {id:113, name: '现代操作系统', price:87},
            ]
        },
        computed:{
            totalPrice: function () {
                let result = 0;
                for(let i=0; i<this.books.length;i++){
                    result += this.books[i].price
                }
                return result
            }
        }
    })
</script>

效果

image

get与set属性

通常情况下, 计算属性中没有set,方法,默认只有get方法,即只读

<!--本质上属性中的方法都是属性,所以不需要添加圆括号-->
<div id="app">{{fullName}}</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            firstName: 'Kobe',
            lastName: 'Bryant'
        },
        // computed完整写法
        computed:{
            fullName:{
                set: function (newValue) {
                    const names = newValue.split(' ');
                    this.firstName = names[0];
                    this.lastName = names[1];
                },
                get: function () {
                    return this.firstName+ ' '+ this.lastName
                }
            }
        }
    })
</script>

image

计算属性与methods对比

1.如果一个业务流程没有返回值,则用methods实现,有返回值,用computed和methods都可以实现

2.计算属性和方法都是函数,计算属性一定有返回值,它通过对数据进行处理,返回一个结果

3.在模板中调用时,计算属性不加(),而methods必须需要加()

4.计算属性和方法最主要的区别是计算属性有缓存功能。
方法被调用时每次都要重复执行函数
计算属性初次调用时执行函数,然后会缓存结果。当再次被调用时,如果依赖的响应式数据没有发生改变,则直接返回之前缓存的结果 。如果依赖发生了改变,则会再次执行函数并缓存结果

v-on

语法糖

v-on:click="sub"
// 语法糖
@click="sub"

v-on修饰符

Vue提供了修饰符来帮助我们方便的处理一些事件:

  • .stop - 调用 event.stopPropagation()。
  • .prevent - 调用 event.preventDefault()。
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。

image

vue条件判断

<div id="app">{{result}}</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            score: '59'
        },
        computed:{
            result(){
                let result = '';
                if(this.score < 60){
                    result = '不及格'
                }else if(this.score>=60 && this.score<85){
                    result = '合格'
                }else{
                    result = '优秀'
                }

                return result
            }
        }
    })
</script>

image

小案例

用户点击按钮,进行登陆操作的切换

<body>
<div id="app">
    <span v-if="isUser">
        <label for="username">用户账号</label>
        <input type="text" id="username" placeholder="用户账号" key="usename">
    </span>

    <span v-else>
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="用户邮箱" key="email">
    </span>

    <button @click="isUser = !isUser">切换类型</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            isUser: true
        }
    })
</script>
</body>

切换

image

v-show

<div id="app" >
        <button @click="toggle">切换显示状态</button>
        <h2 v-show="show">显示</h2>
    </div>


<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            show: true
        },
        methods: {
            toggle() {
                this.show = !this.show
            }
        }
    })
</script>

效果

image

v-if与v-show的对比

  • v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢?
  • v-if当条件为false时,压根不会有对应的元素在DOM中。
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已。

开发中如何选择呢?

  • 当需要在显示与隐藏之间切片很频繁时,使用v-show
  • 当只有一次切换时,通过使用v-if

循环(v-for)

v-for遍历数组

不使用下标值

<div id="app">
<!--在遍历的过程中,没有使用索引值(下标值)-->
        <ul>
            <li v-for="item in names">{{item}}</li>
        </ul>
    </div>

    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data:{
                names:['why', 'kobe', 'james', 'curry']
            }
        })
    </script>

效果:

image

使用下标值

<!--在遍历的过程中,获取索引值-->
        <ul>
            <li v-for="(item, index) in names">
                {{index+1}}.{{item}}
            </li>
        </ul>
    </div>

    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data:{
                names:['why', 'kobe', 'james', 'curry']
            }
        })
    </script>

效果

image

v-for遍历对象

只获取value

<div id="app">
    <!--在遍历对象的过程中,如果只是获取一个值, 那么获取到的是value-->
    <ul>
        <li v-for="item in info">{{item}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            info: {
                name: 'why',
                age: 18,
                height: 1.88
            }
        }
    })
</script>

效果

image

获取键值对

<div id="app">
    <!--在遍历对象的过程中,如果只是获取一个值, 那么获取到的是value-->
<!--    <ul>-->
<!--        <li v-for="item in info">{{item}}</li>-->
<!--    </ul>-->
    <!--获取键值对-->
    <ul>
        <!--在vue中value在前-->
        <li v-for="(value, key) in info">{{value}}-{{key}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            info: {
                name: 'why',
                age: 18,
                height: 1.88
            }
        }
    })
</script>

效果

image

获取键值对和索引

<div id="app">
    <!--获取键值对和索引-->
    <ul>
        <li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            info: {
                name: 'why',
                age: 18,
                height: 1.88
            }
        }
    })
</script>

效果
image

添加key属性

<div id="app">
    <ul>
    	<!--在循环时,key属性中的值,应与要显示的值相一致-->
        <li v-for="item in letters" :key="item">{{item}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            letters: ['A', 'B', 'C', 'D', 'E']
        }
    })
</script>

image

小案例

需求: 在页面中显示列表内容,并伴随点击使对应的选项变红

<head>
    <meta charset="UTF-8">
    <title>05-作业的回顾和完成</title>
    <style>
        .active{
            color: red;
        }
    </style>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="(item, index) in movies"
            :class="{active: currentIndex === index}"
            @click="liClick(index)">
            {{index}}.{{item}}
        </li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            movies:['海王', '海贼王', '加勒比海盗', '海尔兄弟'],
            currentIndex: 0
        },
        methods:{
            liClick(index){
                this.currentIndex = index
            }
        }
    })
</script>

效果
image

购物车案例

详见资料中购物车案例文档

效果

image

完整代码

<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>购物车</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div id="app" v-if="books.length">
    <table class="table table-bordered text-center">
        <thead>
            <tr>
                <th></th>
                <th class="text-center">书籍名称</th>
                <th class="text-center">出版日期</th>
                <th class="text-center">价格</th>
                <th class="text-center">购买数量</th>
                <th class="text-center">操作</th>
            </tr>
        </thead>

        <tbody>
            <tr v-for="(item, index) in books">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.date}}</td>
                <td>{{item.price}}</td>

                <td>
                    <!--当数量为1时,不允许点击-->
                    <button class="btn btn-default btn-sm" @click="sub(index)" :disabled="item.count<=1">-</button>
                    {{item.count}}
                    <button class="btn btn-default btn-sm" @click="add(index)">+</button>
                </td>

                <td>
                    <button class="btn btn-primary btn-sm" @click="remove(index)">移除</button>
                </td>


            </tr>
        </tbody>
    </table>

    <h2>总价格: {{totalPrice | showPrice}}</h2>
    <h2 v-else>购物车为空</h2>
</div>


<script src="../js/vue.js"></script>
<script src="main.js"></script>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
const app = new Vue({
    el: '#app',
    data:{
        books: [
            {
                id: 1,
                name: '《算法导论》',
                date: '2006-9',
                price: 85.00,
                count: 1
            },
            {
                id: 2,
                name: '《UNIX编程艺术》',
                date: '2006-2',
                price: 59.00,
                count: 1
            },
            {
                id: 3,
                name: '《编程珠玑》',
                date: '2008-10',
                price: 39.00,
                count: 1
            },
            {
                id: 4,
                name: '《代码大全》',
                date: '2006-3',
                price: 128.00,
                count: 1
            },
        ]
    },
    methods:{
        // 点击移除按钮移除对应的行
        remove(index){
            this.books.splice(index, 1)
        },
        // 增加数量
        add(index){
            this.books[index].count++
        },
        // 缩减数量
        sub(index){
            this.books[index].count--
        },
    },
    computed:{
        // 计算全部价格
        totalPrice(){
            let totalPrice = 0;
            for(let i=0; i<this.books.length; i++){
                totalPrice += this.books[i].price*this.books[i].count
            }
            return totalPrice
        }
    },
    filters: {
        showPrice(price) {
            return '¥' + price.toFixed(2)
        }
    }
});

v-model

基本使用

<div id="app">
    <input type="text" v-model="message">
    {{message}}
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: 'Hello'
        }
    })
</script>

效果

文本效果随着输入框的内容改变,并与输入框内容保持一致

image

v-model结合raido使用

<div id="app">
    <label for="male">
        <input type="radio" v-model="sex" id="male" value="男">男
    </label>

    <label for="female">
        <input type="radio" v-model="sex" id="female" value="女">女
    </label>
    <h2>您选择的性别是:{{sex}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            sex: '男'
        }
    })
</script>

效果

image

v-model结合checkbox

模拟同意协议(单选)

<div id="app">
    <label for="agree">
        <input type="checkbox" id="agree" v-model="isAgree">
    </label>
    <h2>是否同意:{{status}}</h2>
    <button :disabled="!isAgree">下一步</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            isAgree: false
        },
        computed:{
            status(){
                let status = ''
                if (this.isAgree === false){
                    status = '不同意'
                }else{
                    status = '同意'
                }
                return status
            }
        }
    })
</script>
效果

image

多选

<div id="app">
<!--多选-->
    <input type="checkbox" v-model="hobbies" value="羽毛球">羽毛球
    <input type="checkbox" v-model="hobbies" value="乒乓球">乒乓球
    <input type="checkbox" v-model="hobbies" value="足球">足球
    <input type="checkbox" v-model="hobbies" value="篮球">篮球

    <h2>您选择的是:{{hobbies}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            isAgree: false, //单选
            hobbies: [], // 多选
        },
        computed:{
            status(){
                let status = '';
                if (this.isAgree === false){
                    status = '不同意'
                }else{
                    status = '同意'
                }
                return status
            }
        }
    })
</script>
效果

image

v-model结合select

单选

<div id="app">
    <select name="abc" v-model="fruit">
        <option value="苹果">苹果</option>
        <option value="香蕉">香蕉</option>
        <option value="榴莲">榴莲</option>
        <option value="葡萄">葡萄</option>
    </select>
    <h2>您选择的水果是:{{fruit}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            fruit:'香蕉'
        }
    })
</script>
效果

image

多选

<div id="app">
    <select name="abc" v-model="fruits" multiple>-->
        <option value="苹果">苹果</option>
        <option value="香蕉">香蕉</option>
        <option value="榴莲">榴莲</option>
        <option value="葡萄">葡萄</option>
    </select>
    <h2>您选择的水果是: {{fruits}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            fruit: '香蕉',
            fruits:[]
        }
    })
</script>
效果

image

属性值的绑定

<div id="app">
    <label for="item" v-for="item in originHobbies">
        <input type="checkbox" id="item" :value="item" :id="item" v-model="hobbies">{{item}}
    </label>

    <h2>您的爱好是: {{hobbies}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            hobbies: [],
            originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
        }
    })
</script>

效果

image

修饰符

(1).lazy

在改变后才触发(也就是说只有光标离开input输入框的时候值才会改变)

<div id="app">
    <!--修饰符 lazy-->
    <!--在改变后才触发(也就是说只有光标离开input输入框的时候值才会改变)-->
    <input type="text" v-model.lazy="message">
    <h2>{{message}}</h2>

</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '',
            age: 0,
            name: ''
        }
    })
</script>
效果

image

(2).number

将输出字符串转为Number类型·(虽然type类型定义了是number类型,但是如果输入字符串,输出的是string)

<div id="app">
    <!--修饰符:number-->
    <!--将输出字符串转为Number类型·(虽然type类型定义了是number类型,但是如果输入字符串,输出的是string)-->
    <input type="number" v-model.number="age">
    <h2>{{age}}-{{typeof age}}</h2>

</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data:{
            message: '',
            age: 0,
            name: ''
        }
    })
</script>
效果

image

(3).trim

自动过滤用户输入的首尾空格

<body>
    <div id="app">
        <!--修饰符:trim  自动过滤用户输入的首尾空格-->
        <input type="text" v-model.trim="name">
        <h2>您输入的名字:{{name}}</h2>

    </div>

    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data:{
                message: '',
                age: 0,
                name: ''
            }
        })
    </script>
</body>
效果

image

不考虑业务场景,一味的争执技术的高下,都是耍流氓。
原文地址:https://www.cnblogs.com/leoych/p/15085290.html