Vue 初体验

Vue.js初体验

认识Vue.js

Vue是一个渐进式的框架:渐进式意味着Vue可以作为一部分嵌入到原来的应用中

Vue中存在很多web开发中的常见功能:

  • 解耦合和数据
  • 可复用组件
  • 状态管理
  • 虚拟DOM

Vue.js安装

安装Vue的方式有很多:

1、CDN引入

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

2、下载和引入

https://cn.vuejs.org/js/vue.js
https://cn.vuejs.org/js/vue.min.js

3、npm安装

npm install vue

Vue.js初体验

1、Vue的初体验

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- Vue引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>

<!-- 使用ID绑定使用{{xx}}绑定data中的数据并显示 -->
<div id="app">{{message}}</div>


<script>
    // let定义局部变量、var定义全局变量、const定义常量
    const app = new Vue({
        // 用于挂载要管理的元素
        el: '#app',
        // 定义数据
        data: {
            message: 'Hello'
        }

    })

</script>


</body>
</html>

2、Vue的列表演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../js/vue.js"></script>

  <div id="app">

    <ul>
      <li v-for="item in movies">{{item}}</li>
    </ul>


  </div>
</head>
<body>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      movies: ['海王', '星际穿越', '大话西游', '盗梦空间']
    }
  })
</script>
</body>
</html>

Vue.js基础语法

插值操作

1、Mustache

我们之前的双大括号其实有一个名字,叫做Mustache语法,也叫做双大括号语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- Mustache语法中,不仅可以直接写变量,也可以写一些简单的表达式 -->
        <h1>{{firstName + ' ' + lastName}}</h1>
        <h1>{{couter*2}}</h1>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            firstName: 'bobe',
            lastName: 'bryant',
            couter: 2
        }
    })

</script>
</body>
</html>

2、一些基本指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>


    <style>
        /*
            v-cloak,cloak斗篷。
            有的时候卡住,没有来得及渲染,用户会看到{{message}}而不是立刻渲染出来的内容
            加入这个属性之后,在Vue解析之前会起作用,解析之后就不会起作用
            所以使用这个属性我们可以在Vue解析之前隐藏界面,让界面渲染之后才显示内容
        */
        [v-cloak]{
            display: none;
        }
    </style>
    <div id="app">
        <!-- v-once不会随着数据的改变而改变,也就是说只是加载一次 -->
        <h1 v-once>{{message}}</h1>

        <!-- v-html可以直接插入标签,就像是在HTML页面直接写标签一样 -->
        <h1 v-html="url"></h1>

        <!-- v-text和{{message}}一样,但是我们一般不使用,因为这种方式会直接覆盖标签内的内容,直接覆盖Hello -->
        <h1 v-text="message">Hello</h1>

        <!-- v-pre会直接将{{message}}显示出来,而不是解析{{message}}的内容 -->
        <h1 v-pre>{{message}}</h1>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好',
            url: '<a href="https://www.baidu.com">百度一下</a>'
        }
    })

</script>
</body>
</html>

动态绑定属性和样式

刚才我们的插值属性是动态绑定的文本,但是假如我们想要动态绑定我们的属性(比如src),那么我们就需要v-bind

我们的双括号只能绑定到标签的内容方面,假如是属性则不能使用

v-bind的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 给某一个属性赋值 -->
        <img v-bind:src="imgURL" alt="图片">
        <a v-bind:href="baidu"></a>
        
        <!-- v-bind的语法糖,使用一个冒号就可以绑定属性 -->
        <a :href="baidu"></a>
        
        
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            imgURL: 'https://gitee.com/howling/picgo/raw/master/img/background.png',
            baidu: 'https://www.baidu.com'
        }
    })

</script>
</body>
</html>

动态绑定属性

1、对象语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <style>
        .active{
            color: red;
        }
    </style>

    <div id="app">
        <!--
            v-bind中可以加一个对象,这个对象使用一个花括号表示
            花括号中可以定义键值对,值确认键,然后用来控制属性的值

            从这个标签中,最后得到的结果我们可以看到,渲染出来的结果是:<h2 class="active">Hello</h2>
            也就是说只保留了active
        -->
        <h2 :class="{active: isActive,line: isLine}">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            isActive: true,
            isLine: false
        }
    })

</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <style>
        .active {
            color: red;
        }
    </style>

    <div id="app">
        <!--
            v-bind还可以直接绑定一个函数或者计算属性,这里演示一下绑定函数的内容
        -->
        <h2 :class="getClass()">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            isActive: true,
            isLine: false
        },
        methods: {
            /* 注意这里的返回值是this.不要忘记加上this. */
            getClass: function () {
                return {active: this.isActive, line: this.isLine}
            }
        }
    })

</script>
</body>
</html>

2、数组语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <style>
        .active {
            color: red;
        }
    </style>

    <div id="app">
        <!--
            除了对象语法之外,还可以使用数组语法,但是这种方式不能动态改变,所以这种方式一般不会使用

            使用引号的使用会当成字符串解析,不使用引号会当成变量解析data中的内容
        -->
        <h2 :class="[a,'line']">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            a: 'active'
        }
    })

</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <style>
        .active {
            color: red;
        }
    </style>

    <div id="app">
        <!--
            除了对象语法之外,还可以使用数组语法,但是这种方式不能动态改变,所以这种方式一般不会使用

            使用引号的使用会当成字符串解析,不使用引号会当成变量解析data中的内容
        -->
        <h2 :class="getClass()">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            active: 'active'
        },
        methods: {
            getClass: function () {
                return [this.active];
            }
        }
    })

</script>
</body>
</html>

动态绑定样式

1、动态绑定style

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!--
            这是我们的基础的写法,只能固定在50px

            这里注意一件事情,假如key不加单引号不报错,那么可以不加单引号
            但是value必须要加上单引号才可以解析为原本的50px,否则会认为它是一个变量
         -->
        <h2 :style="{'font-size': '50px'}">{{message}}</h2>

        <!-- 动态决定字体大小和颜色 -->
        <h2 :style="{'font-size': fontSize+'px','color': fontColor}">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            fontSize: '50',
            fontColor: 'red'
        }
    })

</script>
</body>
</html>

2、使用对象语法来代替颜色返回值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 动态决定字体大小和颜色 -->
        <h2 :style="getStyles()">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            fontSize: '50',
            fontColor: 'red'
        },
        methods: {
            getStyles: function (){
                return {'font-size': this.fontSize+'px','color': this.fontColor}
            }
        }
    })

</script>
</body>
</html>

3、使用数组语法来代替样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 动态决定字体大小和颜色 -->
        <h2 :style="getStyles()">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            baseStyle: {backgroundColor: 'red'},
            otherStyle: {color: 'blue'}
        },
        methods: {
            getStyles: function (){
                return [this.baseStyle,this.otherStyle]
            }
        }
    })

</script>
</body>
</html>

计算属性

在DOM中我们其实可以直接通过插值语法渲染出内容吗,但是假如我们想要对数据进行一些转换之后进行显示,或者要将多个数据结合起来进行显示,那么插值语法就有些缺陷了

1、计算属性基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 使用这个方式有点长,很难受 -->
        <h2>{{firstName + lastName}}</h2>

        <!-- 将两个内容进行结合,但是使用方法的方式还是不太好,因为看起来很low -->
        <h2>{{getFullName()}}</h2>

        <!-- 使用计算属性进行两个内容的结合,可以十分方便,而且计算属性不需要加上括号 -->
        <h2>{{fullName}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            firstName: 'Lebron',
            lastName: 'James'
        },
        methods: {
            getFullName: function () {
                return this.firstName + this.lastName
            }
        },
        // 计算属性,所以我们一般使用属性的方式起名字,比如getFullName就不如fullName
        computed: {
            fullName: function (){
                return this.firstName + this.lastName
            }
        }
    })

</script>
</body>
</html>

2、计算属性的复杂用法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        {{totalPrice}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            books: [
                {id: 110,name: 'Linux', price: 119},
                {id: 110,name: 'Java', price: 79},
                {id: 110,name: 'MySQL', price: 89},
                {id: 110,name: 'Vue', price: 100}
            ]
        },
        computed: {
            totalPrice: function (){
                let result = 0
                for (let i = 0; i < this.books.length;i++){
                    result+=this.books[i].price
                }
                return result
            }
        }
    })

</script>
</body>
</html>

计算属性还有一点比较高级,就是它会将得到的结果缓存起来,然后使用缓存的结果

但是method就会每次都会执行

3、计算属性的本质其实就是getter和setter

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        {{totalPrice}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            books: [
                {id: 110,name: 'Linux', price: 119},
                {id: 110,name: 'Java', price: 79},
                {id: 110,name: 'MySQL', price: 89},
                {id: 110,name: 'Vue', price: 100}
            ]
        },
        computed: {
            totalPrice: {
                get: function (){
                    return this.firstName + this.lastName
                },
                set: function (){
                }
            }
        }
    })

</script>
</body>
</html>

这才是计算属性的全写,刚才我们的其实是简写

但是计算属性一般没有set方法,set方法我们一般是删除掉的

所以我们直接就删掉了,就变为了我们上面的方法,也就是说set方法没有了


事件监听

事件监听,就是用户的点击、拖拽、键盘事件等,我们需要使用v-on来使用

1、基本语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <h2>{{counter}}</h2>
        
        <!-- v-on绑定点击事件 -->
        <button v-on:click="increment">+</button>
        <button v-on:click="decrement">-</button>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            counter: 0
        },
        methods: {
            increment(){
                this.counter++
            },
            decrement(){
                this.counter--
            }
        }
    })

</script>
</body>
</html>

我们注意到,上面的方法的小括号省略了,省略小括号是有条件的:

1、必须在事件监听的时候,也就是使用v-on绑定事件的时候

2、方法不需要传递参数

2、语法糖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

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

        <!-- v-on绑定点击事件,@可以代替v-on,也是语法糖 -->
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            counter: 0
        },
        methods: {
            increment(){
                this.counter++
            },
            decrement(){
                this.counter--
            }
        }
    })

</script>
</body>
</html>

3、v-on传递参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 事件定义时省略了小括号,但是函数需要一个参数,那么会自动传入事件本身event -->
        <button @click="btnClick">按钮1</button>
        <!-- 默认情况下,假如有参数那么event对象就不好使了,那么假如我们需要event对象就使用这种方式 -->
        <button @click="btnClick2('abc',$event)">按钮2</button>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        methods: {
            btnClick(obj){
                console.log(obj);
            },
            btnClick2(obj,event){
                console.log(obj+' -- '+event);
            }
        }
    })
</script>
</body>
</html>

假如在methods中定义方法,并且提供给事件调用的时候,那么方法的小括号可以不加

假如方法本身需要一个参数,那么不加入小括号会将原生事件event参数传递过去

假如需要同时传递多个参数,并且同时需要event时,可以通过$event传入

4、v-on的修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">

        <!-- 1、.stop 阻止外层事件 -->
        <div @click="divClick">
            DIVCLICK
            <!-- 假如我们点击了BUTTON,那么其实DIV上的方法也会被触发,我们显然不想这样 -->
            <button @click="btnClick">BUTTONCLICK</button>
        </div>

        <div @click="divClick">
            DIVCLICK
            <!-- 这个.stop就是v-on的修饰符,这个意思是说当我点击BUTTON时,只会执行Button的方法,而不会顺便执行DIV上的方法 -->
            <button @click.stop="btnClick">BUTTONCLICK</button>
        </div>

        <!-- 2、.prevent 阻止默认事件 -->
        <form action="baidu">
            <!-- 这个很明显会提交,但是假如我们不想让他提交,那么应该使用修饰符 -->
            <input type="submit" value="提交">
        </form>

        <br>

        <form action="baidu">
            <!-- .prevent会组织默认的事件,那么在这里它阻止了提交的事件 -->
            <input type="submit" value="提交" @click.prevent="submitClick">
        </form>


        <!-- 3、 .按键 监听键盘某个案件,比如.enter,比如.esc -->
        <input type="text" @keyup.enter="keyUp">

        <!-- 4、.once 执行一次 -->
        <button @click.once="once">Once</button>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        methods: {
            divClick(){
                console.log('DIVCLICK')
            },
            btnClick() {
                console.log('BUTTONCLICK')
            },
            submitClick(){
                console.log('阻止了默认提交')
            },
            keyUp(){
                console.log('Enter')
            },
            once(){
                console.log('once')
            }
        }
    })

</script>
</body>
</html>

条件判断

1、v-if

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <h2 v-if="isTrue">TRUE</h2>
        <h2 v-if="!isTrue">FALSE</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            isTrue: false
        }
    })

</script>
</body>
</html>

2、v-else

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- v-if中的值为true,则会显示 -->
        <h2 v-if="isTrue">TRUE</h2>
        <!-- 当v-if不显示,则显示v-else -->
        <h2 v-else>FALSE</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            isTrue: false
        }
    })

</script>
</body>
</html>

3、v-else-if

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <h2 v-if="score >=90">优秀</h2>
        <h2 v-else-if="score >=75">良好</h2>
        <h2 v-else-if="score >=60">及格</h2>
        <h2 v-else>不及格</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            score: 60
        }
    })

</script>
</body>
</html>

虽然可以这样使用,但是不推荐在HTML中写复杂的逻辑判断

4、v-show

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!--
            除了v-if作为条件判断,v-show也可以判断是否进行显示
            但是v-show和v-if有点不同
            
            v-if:当我们的条件为false时,我们的元素根本不会存在DOM中,所以当true和false切换的时候,本质上是进行创建元素和删除元素
            v-show:当我们的条件为false时,元素存在DOM中但是多了一个display:none的属性,也就是说这个true和false切换本质上是显示和隐藏
         -->
        <h2 v-show="isShow">{{message}}</h2>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            isShow: true
        }
    })

</script>
</body>
</html>

v-if:当我们的条件为false时,我们的元素根本不会存在DOM中,所以当true和false切换的时候,本质上是进行创建元素和删除元素

v-show:当我们的条件为false时,元素存在DOM中但是多了一个display:none的属性,也就是说这个true和false切换本质上是显示和隐藏

当切换频率很低时,我们使用v-if,否则使用v-show


循环遍历

1、遍历数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 1、在遍历的时候不使用下标 -->
        <ul>
            <li v-for="item in names">{{item}}</li>
        </ul>

        <!-- 2、在遍历的时候获取数组下标 -->
        <ul>
            <!-- 因为索引是从0开始的,所以要+1 -->
            <li v-for="(item,index) in names">{{index+1 + '-->' + item}}</li>
        </ul>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            names: ['why','Jack','Tom']
        }
    })

</script>
</body>
</html>

2、遍历对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 1、遍历对象的value -->
        <ul>
            <!-- 因为对象是key-value形式,假如只获取一个值,那么就获取value -->
            <li v-for="item in info">{{item}}</li>
        </ul>

        <!-- 2、获取对象key-value -->
        <ul>
            <!-- 获取的时候是获取 (value,key) -->
            <li v-for="(item,key) in info">{{item + ' ' + key}}</li>
        </ul>

        <!-- 3、获取对象key-value-index -->
        <ul>
            <!-- 获取的时候是获取 (value,key) -->
            <li v-for="(item,key,index) in info">{{item + ' ' + key + ' '}}{{index+1}}</li>
        </ul>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            info: {
                message: 'Hello',
                name: 'Jack',
                age: 18,
                height: 188
            }
        }
    })

</script>
</body>
</html>

3、v-for的:key属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <ul>
            <!-- 
                加上这个:key属性就会增加性能,但是一定要写一个一一对应的东西
                有人喜欢绑定index,但是绑定index不太好
                假如数组中间要插入什么元素,index和item就不会一一对应了

				但是value作为key的话很有可能会有重复值,那就不能保证唯一性,会报错
                所以这里建议绑定一个唯一的、确定的、一一对应的值,id最好
             -->
            <li v-for="item in letters" :key="item">{{item}}</li>
        </ul>
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            letters: ['A','B','C','D','E']
        }
    })

</script>
</body>
</html>

官方建议加上这个:key,会提高性能

4、哪些数组方法是响应式的

1、push():在数组最后添加元素,可以一次性添加多个元素
2、pop():删除数组中最后一个元素
3、shift():删除数组中第一个元素
4、unshift():在数组最前面添加元素,可以一次性添加多个元素
5、splice(v1,v2,...v3):v1是从哪一个开始,v2是删除几个元素,v3是插入几个元素(可变参数)
6、sort():排序
7、reverse():反转

并不是所有方法能够做到响应式的,比如通过索引直接改变数组不是响应式的,但是可以使用Vue.set()来代替

Vue.set(v1,v2,v3):v1是要改变的对象,v2是要改变的下标,v3是要改变为什么东西


表单绑定(双向绑定)

表单在实际开发中十分重要

1、基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 使用 v-model 实现双向绑定 -->
        <input type="text" v-model="message">
        
        {{message}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        }
    })

</script>
</body>
</html>

v-model其实是一个语法糖,他的背后本质上包含v-bind和v-on

2、radio结合双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- radio 其实v-model可以替代name属性,下面的例子中就不写name了-->
        <label for="male">
            <input type="radio" id="male" name="sex" v-model="sex" value="男">
        </label>

        <label for="female">
            <input type="radio" id="female" name="sex" v-model="sex" value="女">
        </label>
        {{sex}}

        <br>
        ----
        <br>

        <!-- checkbox -->
        <label for="lesson">
            我同意以上协议 <input type="checkbox" id="lesson" v-model="isAgree">
            <br>
            <button :disabled="!isAgree">下一步</button>
        </label>


        <br>
        ----
        <br>

        <select name="Fruits" id="" v-model="fruit">
            <option value="苹果">苹果</option>
            <option value="香蕉">香蕉</option>
            <option value="菠萝">菠萝</option>
            <option value="榴莲">榴莲</option>
        </select>
        {{fruit}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            sex: '男',
            isAgree: false,
            fruit: '香蕉'
        }
    })

</script>
</body>
</html>

3、修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 1、修饰符:lazy,会让绑定不会这么频繁,会在输入框失去焦点或者敲回车时绑定过来 -->
        <input type="text" v-model.lazy="message">{{message}}
        <br>

        <!-- 2、修饰符:number,输入框只能输入数字 -->
        <input type="number" v-model.number="age">

        <!-- 3、trim,剪切两边的空格 -->
        <input type="text" v-model.trim="message">
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello',
            age: 0
        }
    })

</script>
</body>
</html>

4、v-model的本质

之前我们说过,v-model其实就是一个语法糖,它是v-bind:valuev-on:input的结合使用,其实我们也可以这样做

并且我们还可以实现一些更复杂的操作,但是我们首先还是看一下如何使用v-bind:valuev-on:input来替代吧

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 使用 v-bind:value 和 v-on:input 来代替 -->
        <input type="text" :value="message" @input="message = $event.target.value">
        {{message}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        }
    })

</script>
</body>
</html>

5、v-model进行更多操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 使用 v-bind:value 和 v-on:input 来代替 -->
        <input type="text" :value="message" @input="inputmessage">
        {{message}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        methods: {
            inputmessage(event){
                this.message = event.target.value
                console.log('进行更多操作')
            }
        }
    })

</script>
</body>
</html>

属性监听

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>

    <div id="app">
        <!-- 使用 v-bind:value 和 v-on:input 来代替 -->
        <input type="text" v-model="message">
        {{message}}
    </div>
</head>
<body>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        // watch用于监听某一个属性的改变,只要这个属性改变了,那么就跳转到这个函数中,这个方法名字和属性名字是一样的
        watch: {
            message(newValue, oldValue) {
                console.log('newValue:' + newValue + '   oldValue:' + oldValue)
            }
        }
    })

</script>
</body>
</html>


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。