数据绑定
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-学习</title>
</head>
<style>
#app {
text-align: center;
margin-top: 100px;
}
ol,
ul li {
list-style-position: inside;
}
</style>
<body>
<div id="app">
<!-- 使用“Mustache”语法 (双大括号)的文本插值:
Mustache 标签将会被替代为对应数据对象上 msg 属性的值。
无论何时,绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。
Vue.js 都提供了完全的 JavaScript 表达式支持。
-->
<span>{{ msg }}</span>
<!--
<a v-on:click="doSomething">...</a>
<a @click="doSomething">...</a>
<a @[event]="doSomething"> ... </a>
-->
<button @[event]="reverseMessage">反转消息</button></br>
</br>
<!-- 使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。 -->
<p><span v-once>这个将不会改变: {{ msg }}</span></p>
<span>{{model_msg}}</span> <input v-model="model_msg">
<!-- v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定 -->
<p v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</p>
<!-- 条件渲染 -->
<p v-if="seen">条件渲染</p>
<!-- 列表渲染:
index:索引 可选
todo:被迭代的数组元素的别名
todos:源数据数组
可以用 of 替代 in 作为分隔符
v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。
带有 v-for 的 <template> 来循环渲染一段包含多个元素的内容
-->
<ol>
<!-- <li v-for="(todo,inde) of todos"> -->
<li v-for="(todo,index) in todos">
{{index}}-{{ todo.text }}
</li>
</ol>
<!-- 在控制台输入app.todos.push({'text':'学习springboot'}) 页面增加新的选项 -->
<!-- 可以用 v-for 来遍历一个对象的属性。
第一个参数为一个对象的属性
第二个的参数为 property 名称 (也就是键名) 可选
第三个参数为索引 可选
在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。
-->
<ul id="v-for-object" class="demo">
<li v-for="(value, name, index) in object">
{{ index }} - {{ name }} - {{ value }}
</li>
</ul>
<ol>
<!--
现在我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”,
-->
<todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item>
</ol>
<!--
完整语法:<a v-bind:href="url">...</a>
缩写:<a :href="url">...</a>
动态参数的缩写 (2.6.0+) <a :[key]="url"> ... </a>
-->
<p><a :[key]="url"> {{url}} </a></p>
<!-- 一个数组传给 v-bind:class,以应用一个 class 列表 -->
<div v-bind:class="[activeClass, errorClass]"></div>
<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>
<!--用 key 管理可复用的元素 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。-->
<template v-if="loginType === 'username'">
<label>Username</label>
<!-- <input placeholder="Enter your username" key="username-input"> -->
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<!-- <input placeholder="Enter your email address" key="email-input"> -->
<input placeholder="Enter your email address">
</template>
<!-- v-show:用于根据条件展示元素的选项,带有 v-show 的元素始终会被渲染并保留在 DOM 中
v-show 只是简单地切换元素的 CSS 属性 display
v-show 不支持 <template> 元素,也不支持 v-else。
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销
当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级
-->
<h1 v-show="seen">Hello!</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
});
//每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var app = new Vue({
el: '#app',
data: {
msg: 'Hello Vue!',
message: '页面加载于 ' + new Date().toLocaleString(),
key: 'href',
url: 'https://cn.vuejs.org/',
seen: true,
event: 'click',
activeClass: 'active',
errorClass: 'text-danger',
type: 'B',
loginType: 'username',
todos: [{
text: '学习HTML5+CSS3+JavaScript'
}, {
text: '学习 Vue'
}, {
text: '学习 vue-cli'
}],
model_msg: '',
groceryList: [{
id: 0,
text: '蔬菜'
}, {
id: 1,
text: '奶酪'
}, {
id: 2,
text: '随便其它什么人吃的东西'
}],
object: {
title: 'How to do lists in Vue',
author: 'antRain',
publishedAt: '2020/4/1'
}
},
methods: {
reverseMessage: function() {
this.msg = this.msg.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
事件处理
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-学习</title>
</head>
<style>
#app {
text-align: center;
margin-top: 100px;
}
ol,
ul li {
list-style-position: inside;
}
</style>
<body>
<div id="app">
<!-- 用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。 -->
<button v-on:click="counter += 1">Add 1</button>
<button v-on:click="add(2)">调用方法Add 2</button>
<p>The button above has been clicked {{ counter }} times.</p>
<!--
事件修饰符:.stop
.prevent
.capture
.self
.once
.passive
阻止单击事件继续传播: <a v-on:click.stop="doThis"></a>
提交事件不再重载页面: <form v-on:submit.prevent="onSubmit"></form>
修饰符可以串联:<a v-on:click.stop.prevent="doThat"></a>
只有修饰符:<form v-on:submit.prevent></form>
添加事件监听器时使用事件捕获模式,即内部元素触发的事件先在此处理,然后才交由内部元素进行处理
<div v-on:click.capture="doThis">...</div>
只当在 event.target 是当前元素自身时触发处理函数即事件不是从内部元素触发的<div v-on:click.self="doThat">...</div>
点击事件将只会触发一次:<a v-on:click.once="doThis"></a>
-->
<!-- 按键修饰符
只有在 `key` 是 `Enter` 时调用 `vm.submit():只有在 `key` 是 `Enter` 时调用 `vm.submit()
可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符:
<input v-on:keyup.page-down="onPageDown">
-->
<!--
v-model:双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
-->
<input v-model="message" placeholder="edit me">
<span>Message is: {{ message }}</span></br>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label><br>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<span>Checked names: {{ checkedNames }}</span><br>
<br>
<input type="radio" id="male" value="male" v-model="sex">
<label for="male">male</label>
<input type="radio" id="female" value="female" v-model="sex">
<label for="female">female</label>
<span>sex: {{ sex }}</span><br>
<select v-model="selectLang">
<option disabled value="">请选择</option>
<option>Java</option>
<option>C++</option>
<option>python</option>
</select>
<span>Selected: {{ selectLang }}</span>
<br>
<!-- 用 v-for 渲染的动态选项: -->
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var app = new Vue({
el: '#app',
data: {
counter: 0,
message: '',
checkedNames: [],
checked: false,
sex: '',
selectLang: '',
selected: 'A',
options: [{
text: 'One',
value: 'A'
}, {
text: 'Two',
value: 'B'
}, {
text: 'Three',
value: 'C'
}]
},
methods: {
add: function(num) {
this.counter += num;
}
}
})
</script>
</body>
</html>
组件
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-学习</title>
</head>
<style>
#app {
text-align: center;
margin-top: 100px;
}
ol,
ul li {
list-style-position: inside;
}
</style>
<body>
<div id="app">
<!-- 可以将组件进行任意次数的复用 -->
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// 定义一个名为 button-counter 的新组件 先定义
/*
组件名大小写:使用 kebab-case (短横线分隔命名) 定义一个组件时,
你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>
当使用 PascalCase (首字母大写命名) 定义一个组件时,在引用这个自定义元素时两种命名法都可以使用。
也就是说 <my-component-name> 和 <MyComponentName> 都是可接受的。
*/
Vue.component('button-counter', {
// 全局注册:组件可以用在其被注册之后的任何新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
//一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
//局部注册.局部注册的组件在其子组件中不可用
var ComponentA = { /* ... */ };
var ComponentB = {
components: {
'component-a': ComponentA
}
};
/*
import/require 使用一个模块系统
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
*/
var app = new Vue({
el: '#app',
data: {
},
methods: {
},
component: {
'component-a': ComponentA,
}
});
</script>
</body>
</html>