Vue3不用任何构建的原始HTML
-
导入vue.global.js,完成Hello vue!的显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>初识vue</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app">{{ message }}</div> <script> const { createApp, ref } = Vue createApp({ setup() { const message = ref('Hello vue!') return { message } } }).mount('#app') </script> </body> </html>
-
模板语法
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
双大括号标签会被替换为相应组件实例中 msg 属性的值。同时每次 msg 属性更改时它也会同步更新。
-
显示Message的信息
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <span>Message: {{ message }}</span> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { // “ref”是用来存储值的响应式数据源。 // 理论上我们在展示该字符串的时候不需要将其包装在 ref() 中, // 但是在下一个示例中更改这个值的时候,我们就需要它了。 const message = ref('神奇的布欧') return { message } } }).mount('#app') </script> </body> </html>
-
处理用户输入:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <!-- 注意我们不需要在模板中写 .value,因为在模板中 ref 会自动“解包”。 --> <h1>{{ message }}</h1> <!-- 绑定到一个方法/函数。这个 @click 语法是 v-on:click 的简写。 --> <button @click="reverseMessage">翻转文字</button> <!-- 也可以写成一个内联表达式语句 --> <button @click="message += '!'">Append "!"</button> <!-- Vue 也为一些像 e.preventDefault() 和 e.stopPropagation()这样的常见任务提供了修饰符。 --> <a href="https://vuejs.org" @click.prevent="notify"> A link with e.preventDefault() </a> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const message = ref('神奇的布欧') function reverseMessage() { // 通过其 .value 属性 // 访问/修改一个 ref 的值。 message.value = message.value.split('').reverse().join('') } function notify() { alert('navigation was prevented.') } return { message, reverseMessage, notify } } }).mount('#app') </script> </body> </html>
-
Attribute绑定:
v-bind 指令指示 Vue 将元素的 id attribute 与组件的 dynamicId 属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。
因为 v-bind 非常常用,我们提供了特定的简写语法:
开头为 : 的attribute 可能和一般的 HTML attribute 看起来不太一样,但它的确是合法的 attribute 名称字符,并且所有支持 Vue 的浏览器都能正确解析它。此外,他们不会出现在最终渲染的 DOM 中。简写语法是可选的,但相信在你了解了它更多的用处后,你应该会更喜欢它。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./css/2-3.模板语法-Attribute绑定.css"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <p> <span :title="message"> 鼠标停留一会可以看见Title! </span> </p> <!--除了普通字符串之外,class 绑定还特别支持了对象和数组--> <p :class="{ red: isRed }" @click="toggleRed"> 现在是红色吧,你点击一下就变了!!! </p> <!-- 样式绑定也支持对象和数组 --> <p :style="{ color }" @click="toggleColor"> 点击我,我可以把颜色蓝绿转换。 </p> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const message = ref('神奇的布欧!') const isRed = ref(true) const color = ref('green') function toggleRed() { isRed.value = !isRed.value } function toggleColor() { color.value = color.value === 'green' ? 'blue' : 'green' } return { message, isRed, color, toggleRed, toggleColor } } }).mount('#app') </script> </body> </html>
-
条件与循环:
指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的 v-for、v-on 和 v-slot)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。以 v-if 为例:
这里,v-if 指令会基于表达式 seen 的值的真假来移除/插入该
元素。
<p v-if="seen">Now you see me</p>
某些指令会需要一个“参数”,在指令名后通过一个冒号隔开做标识。例如用 v-bind 指令来响应式地更新一个 HTML attribute:
这里 href 就是一个参数,它告诉 v-bind 指令将表达式 url 的值绑定到元素的 href attribute 上。在简写中,参数前的一切 (例如 v-bind:) 都会被缩略为一个 : 字符。
<a v-bind:href="url"> ... </a> <!-- 简写 --> <a :href="url"> ... </a>
另一个例子是 v-on 指令,它将监听 DOM 事件:
这里的参数是要监听的事件名称:click。v-on 有一个相应的缩写,即 @ 字符。
<a v-on:click="doSomething"> ... </a> <!-- 简写 --> <a @click="doSomething"> ... </a>
动态参数
同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:
这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName,其值为 “href”,那么这个绑定就等价于 v-bind:href。
在此示例中,当 eventName 的值是 “focus” 时,v-on:[eventName] 就等价于 v-on:focus。
<a v-on:[eventName]="doSomething"> ... </a> <!-- 简写 --> <a @[eventName]="doSomething"> ... </a>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <button @click="show = !show">显示\隐藏</button> <button @click="list.push(list.length + 1)">增加数字</button> <button @click="list.pop()">减少数字</button> <button @click="list.reverse()">反转</button> <ul v-if="show && list.length"> <li v-for="item of list">{{ item }}</li> </ul> <p v-else-if="list.length">数字列表非空,但是隐藏了!</p> <p v-else>狮子列表为空。</p> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const show = ref(true) const list = ref([1, 2, 3]) return { show, list } } }).mount('#app') </script> </body> </html>
-
表单绑定:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <h2>输入文字</h2> <input v-model="text"> {{ text }} <h2>Checkbox</h2> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">Checked: {{ checked }}</label> <!--多个复选框可以绑定到相同的 v-model 数组 --> <h2>Multi Checkbox</h2> <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> <p>Checked names: <pre>{{ checkedNames }}</pre> </p> <h2>Radio</h2> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> <h2>Select</h2> <select v-model="selected"> <option disabled value="">请选择一个吧</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> <h2>Multi Select</h2> <select v-model="multiSelected" multiple style="width:100px"> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ multiSelected }}</span> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const text = ref('输入文字吧') const checked = ref(true) const checkedNames = ref(['Jack']) const picked = ref('One') const selected = ref('A') const multiSelected = ref(['A']) return { text, checked, checkedNames, picked, selected, multiSelected } } }).mount('#app') </script> </body> </html>
-
列表渲染
v-for的使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <li v-for="item in items"> {{ item.message }} </li> <li v-for="(item, index) in items"> {{index}}:{{ item.message }} </li> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const items = ref([{ message: 'Foo' }, { message: 'Bar' }, { message: 'Tom' }, { message: 'Cat' }]); return { items } } }).mount('#app') </script> </body> </html>
v-for嵌套循环:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <li v-for="item in items1"> <span v-for="childItem in items2"> {{ item }}: {{ childItem.message }} </span> </li> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const items1 = ref([1, 2, 3]); const items2 = ref([{ message: 'Foo' }, { message: 'Bar' }, { message: 'Tom' }, { message: 'Cat' }]); return { items1, items2 } } }).mount('#app') </script> </body> </html>
对象的循环key-value:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <ul> <li v-for="value in myObject"> {{ value }} </li> <br /> <li v-for="(value, key) in myObject"> {{ key }}: {{ value }} </li> </ul> </div> <script type="module"> const { createApp, ref, reactive } = Vue createApp({ setup() { const myObject = reactive({ title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' }); return { myObject } } }).mount('#app') </script> </body> </html>
-
事件处理
事件监听-click
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <button @click="count++">Add</button> <p>Count is: {{ count }}</p> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { // “ref”是用来存储值的响应式数据源。 // 理论上我们在展示该字符串的时候不需要将其包装在 ref() 中, // 但是在下一个示例中更改这个值的时候,我们就需要它了。 const count = ref(0) return { count } } }).mount('#app') </script> </body> </html>
方法事件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <!-- `greet` 是上面定义过的方法名 --> <button @click="greet">Greet</button> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { const name = ref('神奇的布欧'); function greet(event) { alert(`Hello ${name.value}!`) // `event` 是 DOM 原生事件 if (event) { alert(event.target.tagName) } }; return { name, greet } } }).mount('#app') </script> </body> </html>
传参方法事件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板语法</title> <!-- 引入Vue --> <script type="text/javascript" src="./js/vue.global.js"></script> </head> <body> <div id="app"> <button @click="say('hello')">Say hello</button> <button @click="say('bye')">Say bye</button> </div> <script type="module"> const { createApp, ref } = Vue createApp({ setup() { function say(message) { alert(message) }; return { say } } }).mount('#app') </script> </body> </html>
事件修饰符:
在处理事件时调用 event.preventDefault() 或 event.stopPropagation() 是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理 DOM 事件的细节会更好。
为解决这一问题,Vue 为 v-on 提供了事件修饰符。修饰符是用 . 表示的指令后缀,包含以下这些:
.stop
.prevent
.self
.capture
.once
.passive<!-- 单击事件将停止传递 --> <a @click.stop="doThis"></a> <!-- 提交事件将不再重新加载页面 --> <form @submit.prevent="onSubmit"></form> <!-- 修饰语可以使用链式书写 --> <a @click.stop.prevent="doThat"></a> <!-- 也可以只有修饰符 --> <form @submit.prevent></form> <!-- 仅当 event.target 是元素本身时才会触发事件处理器 --> <!-- 例如:事件处理器不来自子元素 --> <div @click.self="doThat">...</div>
<!-- 添加事件监听器时,使用 `capture` 捕获模式 --> <!-- 例如:指向内部元素的事件,在被内部元素处理前,先被外部处理 --> <div @click.capture="doThis">...</div> <!-- 点击事件最多被触发一次 --> <a @click.once="doThis"></a> <!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 --> <!-- 以防其中包含 `event.preventDefault()` --> <div @scroll.passive="onScroll">...</div>
按键修饰符:
在监听键盘事件时,我们经常需要检查特定的按键。Vue 允许在 v-on 或 @ 监听按键事件时添加按键修饰符。
<!-- 仅在 `key` 为 `Enter` 时调用 `submit` --> <input @keyup.enter="submit" />
你可以直接使用 KeyboardEvent.key 暴露的按键名称作为修饰符,但需要转为 kebab-case 形式。
<input @keyup.page-down="onPageDown" />
按键别名:
.enter
.tab
.delete (捕获“Delete”和“Backspace”两个按键)
.esc
.space
.up
.down
.left
.right系统按键修饰符:
你可以使用以下系统按键修饰符来触发鼠标或键盘事件监听器,只有当按键被按下时才会触发。
.ctrl
.alt
.shift
.meta<!-- Alt + Enter --> <input @keyup.alt.enter="clear" /> <!-- Ctrl + 点击 --> <div @click.ctrl="doSomething">Do something</div>
.exact 修饰符
.exact 修饰符允许控制触发一个事件所需的确定组合的系统按键修饰符。<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 --> <button @click.ctrl="onClick">A</button> <!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 --> <button @click.ctrl.exact="onCtrlClick">A</button> <!-- 仅当没有按下任何系统按键时触发 --> <button @click.exact="onClick">A</button>
鼠标按键修饰符
.left
.right
.middle
-