vue踩坑

```html
<!--<!DOCTYPE html>-->
<!--<html lang="en">-->
<!--<head>-->
<!--    <meta charset="UTF-8">-->
<!--    <title>Title</title>-->
<!--</head>-->
<!--<body>-->

<!--</body>-->
<!--</html>-->





<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="hello-vue" class="demo">-->
<!--    {{ message }}-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Hello Vue!!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#hello-vue')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="hello-vue" class="demo">-->
<!--    {{ message }}-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Hello Vue!!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#hello-vue')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="hello-vue" class="demo">-->
<!--    {{ message }}-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Hello Vue!!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#hello-vue')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="hello-vue" class="demo">-->
<!--    {{ message }}-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Hello Vue!!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#hello-vue')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--刚开始学习vue,我们不推荐使用vue-cli命令行工具一体化来创建项目,-->
<!--更简单的方式是直接在页面引入vue.global.js文件来测试学习。-->
<!--Vue3中的应用是通过使用createApp函数来创建的,其语法格式如下:-->
<!--const app = Vue.createApp({/*选项*/})-->
<!--传递给createApp的选项用于配置根组件。在使用mount()挂载应用时,该组件被用作渲染的起点。-->
<!--比如:Vue.createApp(HelloVue).mount('#hello-vue')-->
<!--createApp的参数是根组件(HelloVue),在挂载应用时,该组件是渲染的起点。-->
<!--一个应用需要被挂载到一个DOM元素中,以上代码使用mount('#hello-vue')将Vue应用HelloVue挂载到-->
<!--<div id="hello-vue"></div>中。-->
<!--不过,我在vue高版本中还见到了createElement,这应该也是一个创建DOM节点的方法。-->

<!--data选项是一个函数。Vue在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后Vue会通过-->
<!--响应性系统将其包裹起来,并以$data的形式存储在组件实例中。-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app" class="demo"></div>-->

<!--<script>-->
<!--    const app = Vue.createApp({-->
<!--        data() {-->
<!--            const a = 4-->
<!--            return { count: 4 }-->
<!--        }-->
<!--    })-->

<!--    const vm = app.mount('#app')-->

<!--    document.write(vm.$data.count) // => 4-->
<!--    document.write("<br>")-->
<!--    document.write(vm.count)       // => 4-->
<!--    document.write("<br>")-->
<!--    // 修改 vm.count 的值也会更新 $data.count-->
<!--    vm.count = 5-->
<!--    document.write(vm.$data.count) // => 5-->
<!--    document.write("<br>")-->
<!--    // 反之亦然-->
<!--    vm.$data.count = 6-->
<!--    document.write(vm.count) // => 6-->
<!--    -->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--可以看到vm.count和vm.$data.count是紧密相连的,一个的修改会影响到另一个,-->
<!--它们之间的关系更像是引用和实体的关系,一个是另一个的引用。-->
<!--在这里,vm.count是实例属性、vm.$data.count是数据属性,数据属性更像是对实例属性的引用。-->
<!--实例属性仅在实例首次创建时被添加,所以需要确保对应的实例属性在data函数返回的对象中,这样才能得到相应的数据属性。-->
<!--如果data函数返回的对象中没有实例属性count,则组件的数据属性中也没有$data.count-->

<!--我们可以在组件中添加方法,使用methods选项,该选项包含了所需方法的对象,即data函数返回对象中的数据属性count-->
<!--以下实例我们添加了methods选项,选项中包含了increment()方法,它是vm实例的方法属性,由于没有在data函数返回的-->
<!--对象中,所以数据属性中并无此项。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app" class="demo"></div>-->

<!--<script>-->
<!--    const app = Vue.createApp({-->
<!--        data() {-->
<!--            return { count: 4 ,-->
<!--                increment1() {-->
<!--                this.count++-->
<!--            }}-->
<!--        },-->
<!--        methods: {-->
<!--            increment() {-->
<!--                // `this` 指向该组件实例-->
<!--                this.count++-->
<!--            }-->
<!--        }-->
<!--    })-->

<!--    const vm = app.mount('#app')-->

<!--    document.write(vm.count) // => 4-->
<!--    document.write("<br>")-->
<!--    vm.increment()-->

<!--    document.write(vm.count) // => 5-->
<!--    document.write("<br>")-->
<!--    -->
<!--    vm.$data.increment1()-->
<!--    document.write(vm.count) // => 5-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--可以看到,我在data函数返回的对象中添加了一个increment1()函数,然后我就可以在数据属性中调用vm.$data.increament1()了-->


<!--Vue使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。-->
<!--Vue的核心是一个允许你采用简洁的模板语法来声明式地将数据渲染进DOM的系统,-->
<!--结合响应系统,在应用状态改变时,vue能够智能的计算出重新渲染组件的最小代价并应用到DOM操作上。-->
<!--简而言之,vue就是代替你去操作DOM,就像是将手动挡汽车改装成自动挡的汽车,帮助你去操作档位。-->
<!--插值就是一项应用实例-->
<!--{{message}}标签的内容将会被替代为对应组件实例中message属性的值,如果message属性的值发生了改变,-->
<!--{{}}标签内容也会更新。如果不想改变标签的内容,可以通过使用v-once指令执行一次性地插值,当书记改变时,-->
<!--插值处的内容不会更新。-->


<!--使用v-html指令用于输出html代码,很少使用。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="example1" class="demo">-->
<!--    <p>使用双大括号的文本插值: {{ rawHtml }}</p>-->
<!--    <p>使用 v-html 指令: <span v-html="rawHtml"></span></p>-->
<!--</div>-->

<!--<script>-->
<!--    const RenderHtmlApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                rawHtml: '<span style="color: red">这里会显示红色!</span>'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(RenderHtmlApp).mount('#example1')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--    <style>-->
<!--        .class1{-->
<!--            background: #444;-->
<!--            color: #eee;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <label for="r1">修改颜色</label>-->
<!--    <input type="checkbox" v-model="use" id="r1">-->
<!--    <br><br>-->
<!--    <div v-bind:class="{'class1': use}">-->
<!--        v-bind:class 指令-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                use: false-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--注意class1是指定的css格式,以及使用处也用class1就行,-->
<!--你起名字叫什么都没关系,对应起来就行。-->
<!--v-bind是经常使用的,需要留意,非常重要。-->


<!--vue.js都提供了完全的JavaScript表达式支持-->
<!--一开始我没有看明白"'list-' + id",这是什么意思,其实是字符串拼接,即list-1-->
<!--表达式会在当前活动实例的数据作用域下作为JavaScript被解析,但是语句不行。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    {{5+5}}<br>-->
<!--    {{ ok ? 'YES' : 'NO' }}<br>-->
<!--    {{ message.split('').reverse().join('') }}-->
<!--    <div v-bind:id="'list-' + id">菜鸟教程</div>-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                ok: true,-->
<!--                message: 'RUNOOB!!',-->
<!--                id: 1-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--指令是带有v-前缀的特殊属性-->
<!--指令用于在表达式的值改变时,将某些行为应用到DOM上-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p v-if="seen">现在你看到我了</p>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                seen: true /* 改为false,信息就无法显示 */-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里,v-if指令将根据表达式seen的值来决定是否插入P元素-->
<!--另外还有其他很多指令,每个都有特殊的功能。例如,v-for指令可以-->
<!--绑定数组的数据来渲染一个项目列表:-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ol>-->
<!--        <li v-for="site in sites">-->
<!--            {{ site.text }}-->
<!--        </li>-->
<!--    </ol>-->
<!--</div>-->
<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                sites: [-->
<!--                    { text: 'Google' },-->
<!--                    { text: 'Runoob' },-->
<!--                    { text: 'Taobao' }-->
<!--                ]-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--其实,这就是foreach一样的遍历,用多了就会习惯。-->


<!--参数在指令后以冒号指明。例如,v-bind指令被用来响应地更新HTML属性:-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p><a v-bind:href="url">菜鸟教程</a></p>-->
<!--</div>-->

<!--<script>-->
<!--    const HelloVueApp = {-->
<!--        data() {-->
<!--            return {-->
<!--                url: 'https://www.runoob.com'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(HelloVueApp).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--在这里href是参数,告知v-bind指令将该元素的href属性与表达式url的值绑定-->
<!--另一个例子是v-on指令,它用于监听DOM事件-->
<!--<a v-on:click="dosomething"></a>-->
<!--此外,v-bind有很多其它用法,非常重要。-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>{{ message }}</p>-->
<!--    <input v-model="message">-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Runoob!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--v-model指令用来在input、select、textarea、checkbox、radio-->
<!--等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。-->
<!--按钮的事件我们可以使用v-on监听事件,并对用户的输入进行响应。-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>{{ message }}</p>-->
<!--    <button v-on:click="reverseMessage">反转字符串</button>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'Runoob!'-->
<!--            }-->
<!--        },-->
<!--        methods: {-->
<!--            reverseMessage() {-->
<!--                this.message = this.message.split('').reverse().join('')-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--v-bind缩写成:-->
<!--v-on缩写成@-->


<!--条件判断使用v-if指令,指令的表达式返回true时才会显示:-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p v-if="seen">现在你看到我了</p>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                seen: true /* 改为false,信息就无法显示 */-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--这里,v-if指令将根据表达式seen的值(true)或(false)来决定是否插入p元素,-->
<!--多条时,可以使用<div>包裹起来。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div v-if="Math.random() > 0.5">-->
<!--        随机数大于 0.5-->
<!--    </div>-->
<!--    <div v-else>-->
<!--        随机数小于等于 0.5-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div v-if="type === 'A'">-->
<!--        A-->
<!--    </div>-->
<!--    <div v-else-if="type === 'B'">-->
<!--        B-->
<!--    </div>-->
<!--    <div v-else-if="type === 'C'">-->
<!--        C-->
<!--    </div>-->
<!--    <div v-else>-->
<!--        Not A/B/C-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                type: "C"-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--我们也可以使用v-show指令来根据条件展示元素-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <h1 v-show="ok">Hello!</h1>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                ok: true-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--循环使用v-for指令-->
<!--v-for指令需要以site in sites形式的特殊语法,sites是源数据数组并且site是数组元素迭代的别名。-->
<!--v-for可以绑定数据到数组来渲染一个列表:-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ol>-->
<!--        <li v-for="site in sites">-->
<!--            {{ site.text }}-->
<!--        </li>-->
<!--    </ol>-->
<!--</div>-->
<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                sites: [-->
<!--                    { text: 'Google' },-->
<!--                    { text: 'Runoob' },-->
<!--                    { text: 'Taobao' }-->
<!--                ]-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--v-for还支持一个可选的第二个参数,参数值为当前项的索引-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ol>-->
<!--        <li v-for="(site, index) in sites">-->
<!--            {{ index }} -{{ site.text }}-->
<!--        </li>-->
<!--    </ol>-->
<!--</div>-->
<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                sites: [-->
<!--                    { text: 'Google' },-->
<!--                    { text: 'Runoob' },-->
<!--                    { text: 'Taobao' }-->
<!--                ]-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--v-for可以通过一个对象的属性来迭代数据,比如-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ul>-->
<!--        <li v-for="value in object">-->
<!--            {{ value }}-->
<!--        </li>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                object: {-->
<!--                    name: '菜鸟教程',-->
<!--                    url: 'http://www.runoob.com',-->
<!--                    slogan: '学的不仅是技术,更是梦想!'-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--也可以提供第二个参数为键名-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ul>-->
<!--        <li v-for="(value, key) in object">-->
<!--            {{ key }} : {{ value }}-->
<!--        </li>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                object: {-->
<!--                    name: '菜鸟教程',-->
<!--                    url: 'http://www.runoob.com',-->
<!--                    slogan: '学的不仅是技术,更是梦想!'-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--第三个参数为索引-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ul>-->
<!--        <li v-for="(value, key, index) in object">-->
<!--            {{ index+1 }}. {{ key }} : {{ value }}-->
<!--        </li>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                object: {-->
<!--                    name: '菜鸟教程',-->
<!--                    url: 'http://www.runoob.com',-->
<!--                    slogan: '学的不仅是技术,更是梦想!'-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--v-for也可以循环整数,其实就是一个函数的多态-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ul>-->
<!--        <li v-for="n in 10">-->
<!--            {{ n }}-->
<!--        </li>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--我们可以对数组的元素进行处理后再显示出来,一般可以通过创建一个-->
<!--计算属性,来返回过滤或排序后的数组。这里使用了过滤器fliter,-->
<!--这东西说到底就是一个迭代器,就是一个指针,往里面放函数就行。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <ul>-->
<!--        <li v-for="n in evenNumbers">{{ n }}</li>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                numbers: [ 1, 2, 3, 4, 5, 6]-->
<!--            }-->
<!--        },-->
<!--        computed: {-->
<!--            evenNumbers() {-->
<!--                return this.numbers.filter(number => number % 3 === 0)-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--还可以联合使用v-for/v-if给select设置默认值-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <select @change="changeVal($event)" v-model="selOption">-->
<!--        <template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">-->
<!--            &lt;!&ndash; 索引为 1 的设为默认值,索引值从0 开始&ndash;&gt;-->
<!--            <option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>-->
<!--            <option v-else :value="site.name">{{site.name}}</option>-->
<!--        </template>-->
<!--    </select>-->
<!--    <div>您选中了:{{selOption}}</div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                selOption: "Runoob",-->
<!--                sites: [-->
<!--                    {id:1,name:"Google"},-->
<!--                    {id:2,name:"Runoob"},-->
<!--                    {id:3,name:"Taobao"},-->
<!--                ]-->
<!--            }-->

<!--        },-->
<!--        methods:{-->
<!--            changeVal:function(event){-->
<!--                this.selOption = event.target.value;-->
<!--                alert("你选中了"+this.selOption);-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->





<!--组件(Component)是vue.js最强大的功能之一-->
<!--组件可以扩展HTML元素,封装可重用的代码-->
<!--组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件数-->
<!--每个vue应用都是通过用createApp函数创建的,传递给createApp的选项用于配置根组件。-->
<!--当我们挂载应用时,该组件被用作渲染的起点。一个应用需要被挂载到一个DOM元素中。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <runoob></runoob>-->
<!--</div>-->

<!--<script>-->

<!--    // 创建一个Vue 应用-->
<!--    const app = Vue.createApp({})-->

<!--    // 定义一个名为 button-counter 的新全局组件-->
<!--    app.component('runoob', {-->
<!--        template: '<h1>自定义组件!</h1>'-->
<!--    })-->

<!--    app.mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--父子组件通讯-->
<!--可以看到父组件todo-item中有一个@click="$emit('remove')来绑定实例的事件remove,-->
<!--即子组件将自己的实例事件remove丢给父组件的事件click,子组件中@remove="todos.splice(index, 1),-->
<!--将remove绑定到js数组todos的方法splice,这样父子组件之间就串联起来了。此外,父组件props: ['title'],-->
<!--{{ title }},这个title也是从子组件获得的,子组件中:title="todo.title",就把title通过props丢给了-->
<!--父组件。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="todo-list-example">-->
<!--    <form v-on:submit.prevent="addNewTodo">-->
<!--        <label for="new-todo">添加 todo</label>-->
<!--        <input-->
<!--                v-model="newTodoText"-->
<!--                id="new-todo"-->
<!--                placeholder="例如:明天早上跑步"-->
<!--        />-->
<!--        <button>添加</button>-->
<!--    </form>-->
<!--    <ul>-->
<!--        <todo-item-->
<!--                v-for="(todo, index) in todos"-->
<!--                :key="todo.id"-->
<!--                :title="todo.title"-->
<!--                @remove="todos.splice(index, 1)"-->
<!--        ></todo-item>-->
<!--    </ul>-->
<!--</div>-->

<!--<script>-->
<!--    const app = Vue.createApp({-->
<!--        data() {-->
<!--            return {-->
<!--                newTodoText: '',-->
<!--                todos: [-->
<!--                    {-->
<!--                        id: 1,-->
<!--                        title: '看电影'-->
<!--                    },-->
<!--                    {-->
<!--                        id: 2,-->
<!--                        title: '吃饭'-->
<!--                    },-->
<!--                    {-->
<!--                        id: 3,-->
<!--                        title: '上 RUNOOB 学习'-->
<!--                    }-->
<!--                ],-->
<!--                nextTodoId: 4-->
<!--            }-->
<!--        },-->
<!--        methods: {-->
<!--            addNewTodo() {-->
<!--                this.todos.push({-->
<!--                    id: this.nextTodoId++,-->
<!--                    title: this.newTodoText-->
<!--                })-->
<!--                this.newTodoText = ''-->
<!--            }-->
<!--        }-->
<!--    })-->

<!--    app.component('todo-item', {-->
<!--        template: `-->
<!--    <li>-->
<!--      {{ title }}-->
<!--      <button @click="$emit('remove')">删除</button>-->
<!--    </li>-->
<!--  `,-->
<!--        props: ['title'],-->
<!--        emits: ['remove']-->
<!--    })-->

<!--    app.mount('#todo-list-example')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--以上的实例中我们的组件都是通过component全局注册的,全局注册的组件可以在随后创建的app-->
<!--实例模板中使用,也包括根实例组件树中的所有子组件的模板中。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <runoob></runoob>-->
<!--</div>-->

<!--<script>-->

<!--    // 创建一个Vue 应用-->
<!--    const app = Vue.createApp({})-->

<!--    // 定义一个名为 runoob 的新全局组件-->
<!--    app.component('runoob', {-->
<!--        template: '<h1>自定义组件!</h1>'-->
<!--    })-->

<!--    app.mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--全局注册往往是不够理想的。比如,如果你使用一个像webpack这样的构建系统,全局注册所有的组件,-->
<!--意味着所有的组件即便你已经不再使用了,它仍然会包含在你最终的构建结果中。这造成了用户下载的-->
<!--JavaScript的无所谓的增加。在这些情况下,你可以通过一个普通的JacaScript对象来定义组件。-->
<!--const ComponentA = {-->
<!--    /**/-->
<!--}-->

<!--const ComponentB = {-->
<!--    /**/-->
<!--}-->

<!--const ComponentC = {-->
<!--    /**/-->
<!--}-->

<!--然后在components选项中定义你想要使用的组件:-->
<!--const app = Vue.createApp({-->
<!--    components:{-->
<!--        'component-a':ComponentA,-->
<!--        'component-b':ComponentB-->
<!--    }-->
<!--})-->
<!--对于components对象中的每个属性来说,其属性名就是自定义元素的名字-->
<!--(component-a、component-b),其属性值就是这个组件的选项对象-->
<!--(ComponentA、ComponentB)。我们也可以在实例选项中注册局部组件,这样-->
<!--组件只能在这个实例中使用。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <runoob-a></runoob-a>-->
<!--</div>-->
<!--<script>-->

<!--    var runoobA = {-->
<!--        template: '<h1>自定义组件!</h1>'-->
<!--    }-->

<!--    const app = Vue.createApp({-->
<!--        components: {-->
<!--            'runoob-a': runoobA-->
<!--        }-->
<!--    })-->

<!--    app.mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--prop是子组件用来接受父组件传递过来的数据的一个自定义属性。-->
<!--父组件的数据需要通过props把数据传给子组件,子组件需要显示地用props选项声明'prop':-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <site-name title="Google"></site-name>-->
<!--    <site-name title="Runoob"></site-name>-->
<!--    <site-name title="Taobao"></site-name>-->
<!--</div>-->

<!--<script>-->
<!--    const app = Vue.createApp({})-->

<!--    app.component('site-name', {-->
<!--        props: ['title'],-->
<!--        template: `<h4>{{ title }}</h4>`-->
<!--    })-->

<!--    app.mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--可以看到component和components还是有些区别的,通过vue实例去注册子组件是使用.component()这个函数,-->
<!--而通过.createApp()方法创建vue实例,采用属性伴随方法来一同注册组件时,是给vue实例塞一个components属性,-->
<!--这是两种方法(函数)的不同点。-->
<!--去看.component()方法,会发现,其实它是一个多态的方法,仔细查看以后发现,比较合适的是下面这个。-->
<!--component<Props>(id: string, definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;-->
<!--它的返回值是ExtendedVue,而这个ExtendedVue其实就是VueConstructor,也就是说,你给vue实例添加一个components属性以后,-->
<!--其实这个vue实例最后还是调用了vue构造函数,重新创建实例,替换当前的vue实例。其实如果去看component()方法就会发现,第一个多态-->
<!--的方法就是直接调用VueConstructor,即component(id: string): VueConstructor;-->

<!--一个组件默认可以拥有任意数量的prop,任何值东欧可以传递给任何prop-->
<!--下面来看动态prop-->
<!--类似于用v-bind绑定HTML特性到一个表达式,也可以用v-bind动态绑定props的值到父组件的数据中。-->
<!--每当父组件的数据变化时,该变化也会传导给子组件。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <site-info-->
<!--            v-for="site in sites"-->
<!--            :id="site.id"-->
<!--            :title="site.title"-->
<!--    ></site-info>-->
<!--</div>-->

<!--<script>-->
<!--    const Site = {-->
<!--        data() {-->
<!--            return {-->
<!--                sites: [-->
<!--                    { id: 1, title: 'Google' },-->
<!--                    { id: 2, title: 'Runoob' },-->
<!--                    { id: 3, title: 'Taobao' }-->
<!--                ]-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    const app = Vue.createApp(Site)-->

<!--    app.component('site-info', {-->
<!--        props: ['id','title'],-->
<!--        template: `<h4>{{ id }} - {{ title }}</h4>`-->
<!--    })-->

<!--    app.mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里使用了v-bind来绑定,但是采用了简写的方式,即:-->

<!--prop验证-->
<!--组件可以为props指定验证要求-->
<!--为了定制prop的验证方式,你可以为props中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:-->
<!--Vue.component('my-component',{-->
<!--    props:{-->
<!--        //基础的类型检查('null'和'undefined'会通过任何类型验证)-->
<!--        propA:Number,-->
<!--        //多个可能的类型-->
<!--        propB:[String,Number],-->
<!--        //必填的字符串-->
<!--        propC:{-->
<!--            type:String,-->
<!--            required:true-->
<!--        },-->
<!--        //带有默认值的数字-->
<!--        propD:{-->
<!--            type:Number,-->
<!--            default:100-->
<!--        },-->
<!--        //带有默认值的对象-->
<!--        propE:{-->
<!--            type:Object,-->
<!--            //对象或数组默认值必须从一个工厂函数获取-->
<!--            default:function(){-->
<!--                return {message:'hello'}-->
<!--            }-->
<!--        },-->
<!--        //自定义验证函数-->
<!--        propF:{-->
<!--            validator:function(value){-->
<!--            //这个值必须匹配下列字符串中的一个-->
<!--            return['success','warning','danger'].indexOf(value) !== -1-->
<!--            }-->
<!--        }-->

<!--    }-->
<!--})-->

<!--当prop验证失败的时候,(开发环境构建版本的)vue将会产生一个控制台的警告-->


<!--计算属性computed,计算属性在处理一些复杂逻辑时是很有用的。-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    {{ message.split('').reverse().join('') }}-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'RUNOOB!!'-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>原始字符串: {{ message }}</p>-->
<!--    <p>计算后反转字符串: {{ reversedMessage }}</p>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'RUNOOB!!'-->
<!--            }-->
<!--        },-->
<!--        computed: {-->
<!--            // 计算属性的 getter-->
<!--            reversedMessage: function () {-->
<!--                // `this` 指向 vm 实例-->
<!--                return this.message.split('').reverse().join('')-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--上面的例子中声明了一个计算属性reversedMessage。-->
<!--提供的函数将用作属性vm.reversedMessage的getter。-->
<!--vm.reversedMessage依赖于vm.message,在vm.message发生改变时,-->
<!--vm.reversedMessage也会更新。其实这就是给对象添加了一个get方法。-->
<!--这种思想是非常重要的,即添加get方法的思想。-->

<!--computed vs methods-->
<!--我们可以使用methods来替代computed,效果上两个都是一样的,但是computed是基于它的依赖缓存,-->
<!--只有相关依赖发送改变时才会重新取值。而使用methods,在重新渲染的时候,函数总会重新调用执行。-->
<!--这里可以认为methods里面的写的函数是普通函数,而computed里面写的函数是get类型函数,这就跟-->
<!--java里面的东西串联起来了,思想是一致的。java里面的get和set方法是针对对象属性必备的,而自定义-->
<!--函数是自由写的。-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>原始字符串: {{ message }}</p>-->
<!--    <p>使用 computed 计算后反转字符串: {{ reversedMessage }}</p>-->
<!--    <p>使用 methods 计算后反转字符串: {{ reversedMessage2() }}</p>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                message: 'RUNOOB!!'-->
<!--            }-->
<!--        },-->
<!--        computed: {-->
<!--            // 计算属性的 getter-->
<!--            reversedMessage: function () {-->
<!--                // `this` 指向 vm 实例-->
<!--                return this.message.split('').reverse().join('')-->
<!--            }-->
<!--        },-->
<!--        methods: {-->
<!--            reversedMessage2: function () {-->
<!--                return this.message.split('').reverse().join('')-->
<!--            }-->
<!--        }-->
<!--    }-->

<!--    Vue.createApp(app).mount('#app')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--可以说使用computed性能会更好,但是如果不希望缓存,可以使用methods属性。-->
<!--computed属性默认只有getter,不过在需要时也可以提供一个setter:-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->

<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                name: 'Google',-->
<!--                url: 'http://www.google.com'-->
<!--            }-->
<!--        },-->
<!--        computed: {-->
<!--            site: {-->
<!--                // getter-->
<!--                get: function () {-->
<!--                    return this.name + ' ' + this.url-->
<!--                },-->
<!--                // setter-->
<!--                set: function (newValue) {-->
<!--                    var names = newValue.split(' ')-->
<!--                    this.name = names[0]-->
<!--                    this.url = names[names.length - 1]-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    }-->
<!--    vm = Vue.createApp(app).mount('#app')-->
<!--    document.write('name: ' + vm.name);-->
<!--    document.write('<br>');-->
<!--    document.write('url: ' + vm.url);-->
<!--    document.write('<br>&#45;&#45;&#45;&#45;&#45;&#45; 更新数据 &#45;&#45;&#45;&#45;&#45;&#45;<br>');-->
<!--    // 调用 setter, vm.name 和 vm.url 也会被对应更新-->
<!--    vm.site = '菜鸟教程 https://www.runoob.com';-->
<!--    document.write('name: ' + vm.name);-->
<!--    document.write('<br>');-->
<!--    document.write('url: ' + vm.url);-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这就更能说明,这其实就是设置get、set方法,和java里面很像-->


<!--本章节,我们将介绍vue3监听属性watch,我们可以通过watch来响应数据的变化-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id = "app">-->
<!--    <p style = "font-size:25px;">计数器: {{ counter }}</p>-->
<!--    <button @click = "counter++" style = "font-size:25px;">点我</button>-->
<!--</div>-->

<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                counter: 1-->
<!--            }-->
<!--        }-->
<!--    }-->
<!--    vm = Vue.createApp(app).mount('#app')-->
<!--    vm.$watch('counter', function(nval, oval) {-->
<!--        alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');-->
<!--    });-->
<!--    vm.$data()-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--其实watch就是一个迭代器,往里面塞一个函数,这个函数在watch()里面也是-->
<!--有声明的,callback: (this: this, n: any, o: any) => void,-->
<!--这个回调函数是无返回值的,有三个参数,第一个参数是默认的,这里的this是vue实例app-->
<!--这里的watch是在vue实例app创建之后,通过.$watch()函数添加的。当然了,也可以通过另一种方式,-->
<!--在创建vue实例app的时候,直接给它一个watch:{}属性,伴随vue实例一同创建。-->
<!--如果不是一同创建,之后添加,就需要加$符来调用相应的实例函数或者实例属性,其它的比如$emit()用的-->
<!--是比较多的,还有$props、$listener、$createElement等-->

<!--export interface Vue {-->
<!--readonly $el: Element;-->
<!--readonly $options: ComponentOptions<Vue>;-->
<!--    readonly $parent: Vue;-->
<!--    readonly $root: Vue;-->
<!--    readonly $children: Vue[];-->
<!--    readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };-->
<!--    readonly $slots: { [key: string]: VNode[] | undefined };-->
<!--    readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined };-->
<!--    readonly $isServer: boolean;-->
<!--    readonly $data: Record<string, any>;-->
<!--    readonly $props: Record<string, any>;-->
<!--    readonly $ssrContext: any;-->
<!--    readonly $vnode: VNode;-->
<!--    readonly $attrs: Record<string, string>;-->
<!--    readonly $listeners: Record<string, Function | Function[]>;-->

<!--    $mount(elementOrSelector?: Element | string, hydrating?: boolean): this;-->
<!--    $forceUpdate(): void;-->
<!--    $destroy(): void;-->
<!--    $set: typeof Vue.set;-->
<!--    $delete: typeof Vue.delete;-->
<!--    $watch(-->
<!--    expOrFn: string,-->
<!--    callback: (this: this, n: any, o: any) => void,-->
<!--    options?: WatchOptions-->
<!--    ): (() => void);-->
<!--    $watch<T>(-->
<!--        expOrFn: (this: this) => T,-->
<!--        callback: (this: this, n: T, o: T) => void,-->
<!--        options?: WatchOptions-->
<!--        ): (() => void);-->
<!--        $on(event: string | string[], callback: Function): this;-->
<!--        $once(event: string | string[], callback: Function): this;-->
<!--        $off(event?: string | string[], callback?: Function): this;-->
<!--        $emit(event: string, ...args: any[]): this;-->
<!--        $nextTick(callback: (this: this) => void): void;-->
<!--        $nextTick(): Promise<void>;-->
<!--            $createElement: CreateElement;-->
<!--            }-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id = "app">-->
<!--    千米 : <input type = "text" v-model = "kilometers">-->
<!--    米 : <input type = "text" v-model = "meters">-->
<!--</div>-->
<!--<p id="info"></p>-->
<!--<script>-->
<!--    const app = {-->
<!--        data() {-->
<!--            return {-->
<!--                kilometers : 0,-->
<!--                meters:0-->
<!--            }-->
<!--        },-->
<!--        watch : {-->
<!--            kilometers:function(val) {-->
<!--                this.kilometers = val;-->
<!--                this.meters = this.kilometers * 1000-->
<!--            },-->
<!--            meters : function (val) {-->
<!--                this.kilometers = val/ 1000;-->
<!--                this.meters = val;-->
<!--            }-->
<!--        }-->
<!--    }-->
<!--    vm = Vue.createApp(app).mount('#app')-->
<!--    vm.$watch('kilometers', function (newValue, oldValue) {-->
<!--        // 这个回调将在 vm.kilometers 改变后调用-->
<!--        document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里还有一个知识点,那就是innerHTML,先去获取info节点,然后给它添加一个节点以改变它。-->
<!--下面就是英文结束,return and change it-->
<!--/**-->
<!--* Returns the value of element's id content attribute. Can be set to-->
<!--* change it.-->
<!--*/-->
<!--id: string;-->
<!--innerHTML: string;-->


<!--异步加载中使用watch-->
<!--异步数据的加载,Vue通过watch选项提供了一个更通用的方法,-->
<!--来响应数据的变化。以下实例我们使用axios库。-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    &lt;!&ndash; 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 &ndash;&gt;-->
<!--    &lt;!&ndash; 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 &ndash;&gt;-->
<!--    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>-->
<!--    <script src="https://unpkg.com/vue@next"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="watch-example">-->
<!--    <p>-->
<!--        输入一个问题,以 ? 号结尾输出答案:-->
<!--        <input v-model="question" />-->
<!--    </p>-->
<!--    <p>{{ answer }}</p>-->
<!--</div>-->
<!--<script>-->
<!--    const watchExampleVM = Vue.createApp({-->
<!--        data() {-->
<!--            return {-->
<!--                question: '',-->
<!--                answer: '每个问题结尾需要输入 ? 号。'-->
<!--            }-->
<!--        },-->
<!--        watch: {-->
<!--            // 每当问题改变时,此功能将运行,以 ? 号结尾-->
<!--            question(newQuestion, oldQuestion) {-->
<!--                if (newQuestion.indexOf('?') > -1) {-->
<!--                    this.getAnswer()-->
<!--                }-->
<!--            }-->

<!--        },-->
<!--        methods: {-->
<!--            getAnswer() {-->
<!--                this.answer = '加载中...'-->
<!--                axios.get('https://yesno.wtf/api').then(response => {-->
<!--                        this.answer = response.data.answer-->
<!--                    }).catch(error => {-->
<!--                        this.answer = '错误! 无法访问 API。 ' + error-->
<!--                    })-->
<!--                alert('使用了axios')-->
<!--            }-->
<!--        }-->
<!--    }).mount('#watch-example')-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--上面的question写法是缩写方式,其实也可以写成下面这种,实际上是对data里面question的监控,更像是给-->
<!--question添加一个附属方法。-->
<!--question : function(newQuestion, oldQuestion) {-->
<!--    if (newQuestion.indexOf('?') > -1) {-->
<!--        this.getAnswer()-->
<!--    }-->
<!--}-->


<!--axios主要就是这么用的,这个得记住。-->
<!--axios.get('https://yesno.wtf/api').then(response => {-->
<!--    this.answer = response.data.answer-->
<!--}).catch(error => {-->
<!--    this.answer = '错误! 无法访问 API。 ' + error-->
<!--})-->



<!--class与style是HTML元素的属性,用于设置元素的样式,我们可以用-->
<!--v-bind来设置样式属性。v-bind在处理class和style时,表达式除了-->
<!--可以使用字符串之外,还可以是对象或数组。-->
<!--v-bind:class可以简写为:class-->
<!--我们可以为v-bind:class设置一个对象,从而动态的切换class-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .active {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--            background: green;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div :class="{ 'active': isActive }"></div>-->
<!--</div>-->

<!--<script>-->
<!--    var app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                isActive: true-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--以上实例div class的渲染结果为-->
<!--<div class="active"></div>-->
<!--我们也可以在对象中传入更多属性用来动态切换多个class。-->
<!--此外,:class指令也可以与普通的class属性共存。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .static {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--        }-->
<!--        .active {-->
<!--            background: green;-->
<!--        }-->
<!--        .text-danger {-->
<!--            background: red;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div class="static" :class="{ 'active': isActive, 'text-danger': hasError }">-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    var app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                isActive: false,-->
<!--                hasError: true-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--以上实例div class渲染结果为:-->
<!--<div class="static text-danger"></div>-->

<!--我们也可以直接绑定数据里的一个对象-->
<!--比如classobject就是一个对象,里面的属性来指定HTML节点用不用样式属性-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .static {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--        }-->
<!--        .active {-->
<!--            background: green;-->
<!--        }-->
<!--        .text-danger {-->
<!--            background: red;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div class="static" :class="classObject"></div>-->
<!--</div>-->

<!--<script>-->
<!--    var app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                classObject: {-->
<!--                    'active': false,-->
<!--                    'text-danger': true-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--上面两个实例的渲染结果是一样的,此外我们也可以在这里绑定-->
<!--一个返回对象的计算属性,这是一个常用且强大的模式。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .static {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--        }-->
<!--        .active {-->
<!--            background: green;-->
<!--        }-->
<!--        .text-danger {-->
<!--            background: red;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div class="static" :class="classObject"></div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                isActive: true,-->
<!--                error: null-->
<!--            }-->
<!--        },-->
<!--        computed: {-->
<!--            classObject() {-->
<!--                return {-->
<!--                    active: this.isActive && !this.error,-->
<!--                    'text-danger': this.error && this.error.type === 'fatal'-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--渲染出来的结果是-->
<!--<div class="static active"></div>-->

<!--我们可以把一个数组传给v-bind:class,-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .static {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--        }-->
<!--        .active {-->
<!--            background: green;-->
<!--        }-->
<!--        .text-danger {-->
<!--            background: red;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div class="static" :class="[activeClass, errorClass]"></div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                activeClass: 'active',-->
<!--                errorClass: 'text-danger'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--我们还可以使用三元表达式来切换列表中的class-->
<!--errorClass是始终存在的,isActive为true时添加activeClass类-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .static {-->
<!--            width: 100px;-->
<!--            height: 100px;-->
<!--        }-->
<!--        .active {-->
<!--            background: green;-->
<!--        }-->
<!--        .text-danger {-->
<!--            background: red;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                isActive: false,-->
<!--                activeClass: 'active',-->
<!--                errorClass: 'text-danger'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--上面实例div class渲染结果为-->
<!--<div class="static text-danger"></div>-->

<!--上面讲完了class,下面是style。我们可以在v-bind:style直接设置样式,-->
<!--可以简写为:style-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div :style="{ color: activeColor, fontSize: fontSize }">菜鸟教程</div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                activeColor: 'red',-->
<!--                fontSize: '30px'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--上面实例div style渲染结果是-->
<!--<div style="color:red;font-size:30px"></div>-->


<!--也可以直接绑定到一个样式对象,让模板更清晰-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div v-bind :style="styleObject">菜鸟教程</div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                styleObject: {-->
<!--                    color: "red",-->
<!--                    fontSize: "30px"-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--也就是<div :style="styleObject"></div>与-->
<!--<div :style="{ color: activeColor, fontSize: fontSize }">菜鸟教程</div>-->
<!--的关系-->
<!--:style是v-bind:style的缩写-->


<!--v-vind:style可以使用数组将多个样式对象应用到一个元素上:-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <div :style="[baseStyles, overridingStyles]">菜鸟教程</div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                baseStyles: {-->
<!--                    color: 'green',-->
<!--                    fontSize: '30px'-->
<!--                },-->
<!--                overridingStyles: {-->
<!--                    'font-weight': 'bold'-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--渲染出来以后-->
<!--<div style="color: green; font-size: 30px; font-weight: bold;">菜鸟教程</div>-->

<!--注意:当v-bind:style使用需要特定前缀的CSS属性时,如transform,Vue.js会自动侦测并添加相应的前缀-->

<!--多重值,可以为style绑定中的property提供一个包含多个值的数组,常用于提供多个带前缀的值。-->
<!--<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>-->
<!--这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的flexbox,-->
<!--那么就只会渲染display:flex-->

<!--组件上使用class属性-->
<!--当你在带有单个根元素的自定义组件上使用class属性时,这些class将被添加到该元素中。此元素上的现有class将不会被覆盖-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <runoob></runoob>-->
<!--</div>-->

<!--<script>-->
<!--    var app = new Vue({-->
<!--        el:'#app',-->
<!--        components:{-->
<!--            "runoob":{-->
<!--                template: '<h1 class="classA classB">I like runoob!</h1>'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--重要的是上面的-->
<!--<h1 class="classA classB">I like runoob!</h1>-->
<!--会渲染出来-->
<!--有些template中`是反引号,才有用,单引号'没有用。-->




<!--对于带数据绑定class,组件也同样适用。-->
<!--如果你的组件中有多个根元素,你需要定义哪个元素可以-->
<!--来接收这个class类。可以使用$attrs组件属性执行此操作-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--    <style>-->
<!--        .classA {-->
<!--            color: red;-->
<!--            font-size:30px;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <runoob class="classA"></runoob>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        components:{-->
<!--            runoob:{-->
<!--                template: `<p :class="$attrs.class">I like runoob!</p>-->
<!--                            <span>这是一个子组件</span>`-->
<!--            }-->
<!--        }-->

<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--vue3事件处理-->
<!--我们可以使用v-on指令来监听DOM事件,从而执行javascript代码-->
<!--v-on指令可以缩写为@符号-->
<!--v-on:click="methodName"-->
<!--或-->
<!--@click="methodName"-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <button @click="counter += 1">增加 1</button>-->
<!--    <p>这个按钮被点击了 {{ counter }} 次。</p>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                counter: 0-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->


<!--通常情况下,我们需要使用一个方法来调用javascript方法。-->
<!--v-on可以接收一个定义的方法来调用。-->

<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    &lt;!&ndash; `greet` 是在下面定义的方法名 &ndash;&gt;-->
<!--    <button @click="greet">点我</button>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                name: 'Runoob'-->
<!--            }-->
<!--        },-->
<!--        methods: {-->
<!--            greet(event) {-->
<!--                // `methods` 内部的 `this` 指向当前活动实例-->
<!--                alert('Hello ' + this.name + '!')-->
<!--                // `event` 是原生 DOM event-->
<!--                if (event) {-->
<!--                    alert(event.target.tagName)-->
<!--                }-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里的event是原生DOM的事件,通过它可以去追溯到原生事件的相关信息-->
<!--这里的this.name自然是指vue实例里面的name,javascript不太容易理解的地方就是,它的书写不够传统。-->
<!--这里new Vue是调用了vueconstructor构造函数,但是这个构造函数里面又塞了一堆东西,甚至还有一些方法和属性之类的东西-->


<!--除了直接绑定到一个方法,也可以用法内联javascript语句,即传参的方式-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <button @click="say('hi')">Say hi</button>-->
<!--    <button @click="say('what')">Say what</button>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->

<!--        },-->
<!--        methods: {-->
<!--            say(message) {-->
<!--                alert(message)-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里是把参数写在button上,更好的方式是将它写在输入框中。-->


<!--事件处理程序中可以有多个方法,这些方法由逗号运算符分隔-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    &lt;!&ndash; 这两个 one() 和 two() 将执行按钮点击事件 &ndash;&gt;-->
<!--    <button @click="one($event), two($event)">-->
<!--        点我-->
<!--    </button>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--        },-->
<!--        methods: {-->
<!--            one(event) {-->
<!--                alert("第一个事件处理器逻辑...")-->
<!--            },-->
<!--            two(event) {-->
<!--                alert("第二个事件处理器逻辑...")-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->

<!--vue.js为v-on提供了事件修饰符来处理DOM事件细节,如:event.preventDefault()-->
<!--或event.stopPropagation()-->
<!--Vue.js通过由点.表示的指令后缀来调用修饰符-->

<!--.stop阻止冒泡-->
<!--.prevent阻止默认事件-->
<!--.capture阻止捕获-->
<!--.self只监听触发该元素的事件-->
<!--.once只触发一次-->
<!--.left左键事件-->
<!--.right右键事件-->
<!--.middle中间滚轮事件-->


<!--vue3表单-->
<!--这节我们为大家介绍vue表单上的应用。-->
<!--我们可以用你v-model指令在表单<input>、<textarea>及<select>等-->
<!--元素上创建双向数据绑定-->



<!--v-model会根据控件类型自动选取正确的方法来更新元素-->
<!--v-model会忽略所有表单元素的value、checked、selected属性的-->
<!--初始值,使用的是data选项中声明的初始值。-->
<!--v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件-->
<!--text和textarea元素使用value属性和input事件-->
<!--checkbox和radio使用checked属性和change事件-->
<!--select字段将value作为属性并将change作为事件。-->


<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>input 元素:</p>-->
<!--    <input v-model="message" placeholder="编辑我……">-->
<!--    <p>input 表单消息是: {{ message }}</p>-->

<!--    <p>textarea 元素:</p>-->
<!--    <textarea v-model="message2" placeholder="多行文本输入……"></textarea>-->
<!--    <p>textarea 表单消息是:</p>-->
<!--    <p style="white-space: pre">{{ message2 }}</p>-->

<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                message: '',-->
<!--                message2: '菜鸟教程\r\nhttps://www.runoob.com'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--实例中演示了input和textarea元素中使用v-model实现双向数据绑定-->


<!--在文本区域textarea插值是不起作用的,需要使用v-model来代替-->
<!--错误-->
<!--<textarea>{{text}}</textarea>-->

<!--正确-->
<!--<textarea v-model="text"></textarea>-->
<!--<div>{{text}}</div>-->


<!--以下实例中演示了复选框的双向数据绑定-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <p>单个复选框:</p>-->
<!--    <input type="checkbox" id="checkbox" v-model="checked">-->
<!--    <label for="checkbox">{{ checked }}</label>-->

<!--    <p>多个复选框:</p>-->
<!--    <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">-->
<!--    <label for="runoob">Runoob</label>-->
<!--    <input type="checkbox" id="google" value="Google" v-model="checkedNames">-->
<!--    <label for="google">Google</label>-->
<!--    <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">-->
<!--    <label for="taobao">taobao</label>-->
<!--    <br>-->
<!--    <span>选择的值为: {{ checkedNames }}</span>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                checked : false,-->
<!--                checkedNames: []-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--复选框如果是一个为逻辑值,如果是多个则绑定到同一个数组。-->
<!--这里复选框的type都是checkbox,但是checked的value是false,而checkedNames的值是[],所以vue组件的内部-->
<!--应该是有一个判断机制,判断处理,如果是布尔值,复选框自动了解到true or false。-->
<!--对第一个复选框,我补充一个value="true"可以帮助理解,不加的话,它也有这个效果,它在渲染后是-->
<!--<input type="checkbox" id="checkbox" value="true">-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <input type="radio" id="runoob" value="Runoob" v-model="picked">-->
<!--    <label for="runoob">Runoob</label>-->
<!--    <br>-->
<!--    <input type="radio" id="google" value="Google" v-model="picked">-->
<!--    <label for="google">Google</label>-->
<!--    <br>-->
<!--    <span>选中值为: {{ picked }}</span>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                picked : 'Runoob'-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这个实例中演示了单选按钮的双向数据绑定-->
<!--单选按钮是radio、双选按钮是checkbox-->
<!--可以看到他们是通过v-model去绑定data中的值的,而id是给label去绑定的,-->
<!--而type是限定input的类型是单选还是复选框,而value是input给data中泰的数据的-->



<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <select v-model="selected" name="fruit">-->
<!--        <option value="">选择一个网站</option>-->
<!--        <option value="www.runoob.com">Runoob</option>-->
<!--        <option value="www.google.com">Google</option>-->
<!--    </select>-->

<!--    <div id="output">-->
<!--        选择的网站是: {{selected}}-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                selected: ''-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里是在select标签里面绑定v-model,在option里面绑定value-->



<!--多选时会绑定到一个数组,其实是select里面添加一个multiple-->
<!--需要辅助以ctr键-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app">-->
<!--    <select v-model="selected" name="fruit" multiple>-->
<!--        <option value="www.runoob.com">Runoob</option>-->
<!--        <option value="www.google.com">Google</option>-->
<!--        <option value="www.taobao.com">Taobao</option>-->
<!--    </select>-->

<!--    <div id="output">-->
<!--        选择的网站是: {{selected}}-->
<!--    </div>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                selected: ''-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->



<!--使用v-for循环输出选项-->
<!--<!DOCTYPE html>-->
<!--<html>-->
<!--<head>-->
<!--    <meta charset="utf-8">-->
<!--    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>-->
<!--    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app" class="demo">-->
<!--    <select v-model="selected">-->
<!--        <option v-for="option in options" :value="option.value">-->
<!--            {{ option.text }}-->
<!--        </option>-->
<!--    </select>-->
<!--    <span>选择的是: {{ selected }}</span>-->
<!--</div>-->

<!--<script>-->
<!--    const app = new Vue({-->
<!--        el:'#app',-->
<!--        data() {-->
<!--            return {-->
<!--                selected: 'www.runoob.com',-->
<!--                options: [-->
<!--                    { text: 'Runoob', value: 'www.runoob.com' },-->
<!--                    { text: 'Google', value: 'www.google.com' },-->
<!--                    { text: 'Taobao', value: 'www.taobao.com' }-->
<!--                ]-->
<!--            }-->
<!--        }-->
<!--    })-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
<!--这里不但使用了v-for,还使用了v-bind,即:value="option.value",将选项的值绑定到option.vale-->
<!--这里没有使用v-model-->

<!--<input type="checkbox" v-model="toggle" true-value="yes" fail-value=""no/>-->
<!--相当于-->
<!--<input type="checkbox" v-model="toggle" vale="yes">-->


<!--值绑定-->
<!--对于单选按钮,复选框及选择框的选项,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>-->


<!--但是有时我们可能想把值绑定到当前活动实例的一个动态属性上,-->
<!--这时可以用v-bind实现,此外,使用v-bind可以将输入值绑定到非字符串-->

<!--<input type="radio" v-model="pick" v-bind:value="a"/>-->
<!--当选中时-->
<!--vm.pick === vm.a-->
<!--这里就共同使用了v-model和v-bind-->

<!--<select v-model="selected">-->
<!--&lt;!&ndash;    内联对象字面量&ndash;&gt;-->
<!--    <option :value="{number:123}">123</option>-->
<!--</select>-->
<!--当被选中时-->
<!--typeof vm.selected // => 'object'-->
<!--vm.selected.number // =>123-->



<!--修饰符-->
<!--.lazy-->
<!--在默认情况下,v-model在input事件中同步输入框的值与数据,但你可以添加一个修饰符lazy,-->
<!--从而转变为在change事件中同步:-->
<!--在"change"而不是"input"事件中更新,其实就是懒加载-->
<!--<input v-model.lazy="msg">-->


<!--.number-->
<!--如果想自动将用户的输入值转为Number类型(如果原值的转换结果为NaN则返回原值),可以添加一个修饰符number-->
<!--给v-model来处理输入值-->
<!--<input v-model.number="age" type="number">-->
<!--这通常很有用,因为在type="number"时,HTML中输入的值也总是会返回字符串类型-->


<!--.trim-->
<!--如果要自动过滤用户输入的首尾空格,可以添加trim修饰符到v-model上过滤输入-->
<!--<input v-model.trim="msg">-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
    <div>model</div>
    <h3>{{msg}}</h3>

    <div>v-bind 只能实现数据的单向绑定,从 M 绑定到 V ,无法实现数据的双向绑定</div>
    <!-- v-bind 只能实现数据的单向绑定,从 M 绑定到 V ,无法实现数据的双向绑定 -->
    <input type="text" style="width:300px;" v-bind:value="msg">

    <!-- 使用v-model 指令可以实现表单元素和 Model 中的数据的双向数据绑定 -->
    <!-- v-model 指令只能运用在表单元素 -->
    <!-- input (radio text address email...) select checkbox textarea -->
    <div>使用v-model 指令可以实现表单元素和 Model 中的数据的双向数据绑定</div>
    <input type="text" style="width:300px;" v-model="msg">
</div>

<script>
    let vm=new Vue({
        el:'#app',
        data:{
            msg:'肥肥好可爱啊啊啊'
        }
    })
</script>
</body>
</html>


“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值