准备:新建项目
1、使用Vite创建Vue Typescript 项目(instructions)
npm create vite@latest
2、项目文件结构
3、运行
一、文本插值
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
1、基本用法:
template
<span>Message: {{ msg }}</span>
双大括号标签会被替换为相应组件实例中 msg 属性的值。同时每次 msg 属性更改时它也会同步更新。
2、案例:修改App.vue:
<script setup lang="ts">
const msg = "Hello World!"
</script>
<template>
<h1>{{ msg }}</h1>
</template>
3、案例运行结果
二、 v-bind 绑定id或属性
v-bind 指令指示 Vue 将元素的 id attribute 与组件的 dynamicId 属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。
1、基本用法:
<div v-bind:id="dynamicId"></div>
2、简写:
<div :id="dynamicId"></div>
3、案例运行结果
4、案例(修改App.vue)
<script setup lang="ts">
const imgUrl = "https://img2.baidu.com/it/u=617579813,2960860841&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
const url = "http://www.gengdan.cn"
const className = 'title1'
</script>
<template>
<img :src="imgUrl"/>
<br/>
<a :href="url">耿丹官网</a>
<h1 :class="className">我是标题一,请把我变成红色</h1>
</template>
<style>
img{
height: 200px;
}
a{
font-size:28px;
}
.title1 {
color: red;
}
</style>
三、 v-model 双向绑定
v-model 可以在组件上使用以实现双向绑定。
1、v-model 在原生元素上的用法:
template
<input v-model="searchText" />
2、案例运行结果
3、案例(修改App.vue)
<script setup lang="ts">
let username = "admin";
let password = "123456";
let intro = "我是系统管理员";
function doLogin(){
console.log(username);
console.log(password);
console.log(intro);
}
</script>
<template>
<div id="app">
<div>
<label>
账号:
<input type="text" v-model="username" />
</label>
</div>
<div>
<label>
密码:
<input type="text" v-model="password" />
</label>
</div>
<div>
个人简介:
<textarea v-model="intro"></textarea>
</div>
<div>
<button @click="doLogin">登录系统</button>
</div>
</div>
</template>
四、 v-on 给元素绑定事件监听器。
缩写:@
期望的绑定值类型:Function | Inline Statement | Object (不带参数)
参数:event (使用对象语法则为可选项)
修饰符:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 在捕获模式添加事件监听器。
.self - 只有事件从元素本身发出才触发处理函数。
.{keyAlias} - 只在某些按键下触发处理函数。
.once - 最多触发一次处理函数。
.left - 只在鼠标左键事件触发处理函数。
.right - 只在鼠标右键事件触发处理函数。
.middle - 只在鼠标中键事件触发处理函数。
.passive - 通过 { passive: true } 附加一个 DOM 事件。
1、v-on基本用法:
<button v-on:click="doThis">方法一</button>
2、v-on简写用法:
<button @click="doThis">方法二</button>
3、v-on内联语句调用方法:
<button v-on:click="say('hi')">方法三</button>
4、v-on单击事件案例运行结果:
5、v-on单击事件案例:
<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
let n = "";
// 分数加1函数
function add() {
count.value = count.value + 1;
console.log(count);
}
// 分数减1函数
function reduce() {
if (count.value == 0) {
alert("得分不能小于0");
} else {
count.value = count.value - 1;
}
}
// 加分函数
function enterAdd() {
if (count.value + parseInt(n) < 0) {
alert("得分不能小于0");
} else {
count.value = count.value + parseInt(n);
}
n = "";
}
</script>
<template>
<div id="app">
总分:{{ count }} <br />
<button v-on:click="add">加分</button>
<button @click="reduce">减分</button>
<br />
<!-- 回车调用加法事件 -->
加分:<input type="text" v-on:keyup.enter="enterAdd" v-model="n" />
</div>
</template>
6、v-on键盘、鼠标事件案例:
(1)事件的基本使用: 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
(2)键盘和鼠标事件监听
v-on:click(@click) ——>注册点击事件
v-on:keydown(@keydown) ——>注册键盘按下事件
v-on:keyup(@keyup) ——>注册键盘弹起事件
v-on:mousedown(@mousedown) ——>注册鼠标按下事件
v-on:mouseover(@mouseover) ——>注册鼠标弹起事件
v-on:submit(@submit) ——>注册表单事件
v-on:scroll(@scroll) ——>注册滚动条(上下按键)事件
v-on:wheel(@wheel) ——>注册滚轮事件
(3)常用的七种按键:
@keyup.enter enter键触发
@keyup.delete delete和backspace键触发(删除键 和 退格键 都能触发,但delete不会删除输入内容)
@keyup.esc esc键触发
@keyup.space space键触发
@keyup.tab tab键触发 (特殊按键,因tab本身功能是切换焦点,按下tab时就会切换,所以tab常用在@keydown.tab)
@keyup.up up键触发
@keyup.down down键触发
@keyup.left left键触发
@keyup.right right键触发 除tab外其它特殊按键: 系统修饰键: ctrl, alt, shift, meta(win键) (1) 配合keyup使用: 按下修饰键,在按下其它键,随后释放其它键,事件才触发, 如@keyup.ctrl.y='绑定方法' (2) 配合keydown使用: 正常触发事件
(4)键盘、鼠标案例
<script setup lang="ts">
import { ref } from "vue";
function mouseDown() {
console.log("鼠标被按下了!");
}
function mouseUp() {
console.log("鼠标被抬起了!");
}
function onKeyUp(e:any) {
console.log(e.key, e.keyCode, "键被抬起了"); // 显示按键的名称和编码
}
function onKeyPress(e:any) {
console.log(e.key, e.keyCode, "键被按下了"); // 显示按键的名称和编码
}
function onEnterEvent() {
console.log("您按下了回车");
}
function onTabKeyDown(){
console.log("Tab键被按下!");
}
function onDelKeyDown(){
console.log("删除键被按下!");
}
function onUpKeyDown(){
console.log("向上的键被按下了!");
}
function onDownKeyDown(){
console.log("向下的键被按下了!");
}
function onLeftKeyDown(){
console.log("向左的键被按下了!");
}
function onRightKeyDown(){
console.log("向右的键被按下了!");
}
</script>
<template>
<div id="app">
回车引发事件:<input type="text" @keyup.enter="onEnterEvent" /><br/>
Tab键、退格或删除键引发事件: <input @keydown.tab="onTabKeyDown" @keydown.delete="onDelKeyDown" /><br/>
上、下、左、右键引发事件: <input @keydown.up="onUpKeyDown" @keydown.down="onDownKeyDown" @keydown.left="onLeftKeyDown" @keydown.right="onRightKeyDown"/><br/>
<button v-on="{ mousedown: mouseDown, mouseup: mouseUp }">鼠标事件</button>
<button @keyup="onKeyUp" @keypress="onKeyPress">键盘事件</button>
</div>
</template>
<style>
* {
font-size: 28px;
margin-top: 50px;
margin: 10px;
}
</style>
(5)滚轮事件
参考源码:
<template>
<div>
<ul @wheel="wheelFun">
<li v-for="item in 100">{{ item }}</li>
</ul>
</div>
</template>
<script setup lang="ts">
import {ref} from "vue"
const conter = ref(0)
const wheelFun = () => {
console.log(conter.value++ + "滚轮滚动了!");
}
</script>
<style scoped>
</style>
五、 v-text 更新元素的文本内容
期望的绑定值类型:string
<span v-text="msg"></span>
<!-- 等同于 -->
<span>{{msg}}</span>
<script setup lang="ts">
let msg = `<h1 style="color:blue">v-text用法</h1><p>原样的字符串,还是挺简单的吧?</p>`;
</script>
<template>
<div id="app">
<span v-text="msg"></span>
</div>
</template>
六、 v-html 更新元素的 innerHTML
期望的绑定值类型:string
v-html 的内容直接作为普通 HTML 插入。
<script setup lang="ts">
let htmlContent = `<h1 style="color:blue">v-html用法</h1><p>还是挺简单的吧?</p>`;
</script>
<template>
<div id="app">
<div v-html="htmlContent"></div>
</div>
</template>
七、v-once 仅渲染元素和组件一次,并跳过之后的更新
在随后的重新渲染,元素/组件及其所有子项将被当作静态内容并跳过渲染。这可以用来优化更新时的性能。
<script setup lang="ts">
let msg = "Hello v-once";
const list = ["苹果", "香蕉", "香梨", "菠萝"];
</script>
<template>
<div id="app">
<!-- 单个元素 -->
<span v-once>我不变: {{ msg }}</span>
<!-- 带有子元素的元素 -->
<div v-once>
<h1>comment</h1>
<p>{{ msg }}</p>
</div>
<!-- 组件 -->
<MyComponent v-once :comment="msg" />
<!-- `v-for` 指令 -->
<ul>
<li v-for="i in list" v-once>{{ i }}</li>
</ul>
</div>
</template>
<style>
* {
font-size: 28px;
margin-top: 50px;
margin: 10px;
}
</style>
八、v-pre 跳过该元素及其所有子元素的编译
元素内具有 v-pre,所有 Vue 模板语法都会被保留并按原样渲染。最常见的用例就是显示原始双大括号标签及内容。
示例:
template
<span v-pre>{{ this will not be compiled }}</span>
九、v-cloak 用于隐藏尚未完成编译的 DOM 模板。
该指令只在没有构建步骤的环境下需要使用。
当使用直接在 DOM 中书写的模板时,可能会出现一种叫做“未编译模板闪现”的情况:用户可能先看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。
v-cloak 会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像 [v-cloak] { display: none } 这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。
<div v-cloak>
{{ message }}
</div>
[v-cloak] {
display: none;
}
十、v-slot 用于声明具名插槽或是期望接收 props 的作用域插槽
缩写:#
期望的绑定值类型:能够合法在函数参数位置使用的 JavaScript 表达式。支持解构语法。绑定值是可选的——只有在给作用域插槽传递 props 才需要。
参数:插槽名 (可选,默认是 default)
1、实例:子获取父的值
App.vue是父组件,HelloWorld.vue是子组件
(1)App.vue参考源码
<template>
<div class="container-component-a">
<h1>组件A</h1><hr>
<HelloWorld name1="abc">
<div>父组件的div</div>
</HelloWorld>
</div>
</template>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
</script>
(2)HelloWorld.vue参考源码
<template>
<div class="container-component-b">
<h1>组件HelloWorld</h1>
<div>
<div>子组件HelloWorld的div</div>
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts"></script>
2、实例:父子相互取值
(1)运行结果
App.vue是父组件,HelloWorld.vue是子组件
(2)App.vue参考源码
<template>
<div class="container-component-a">
<h1>组件A</h1><hr>
<HelloWorld>
<template v-slot:name1="data1">
{{ data1 }}
</template>
</HelloWorld>
</div>
</template>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
</script>
(3)HelloWorld.vue参考源码
<template>
<div class="container-component-b">
<h1>组件HelloWorld</h1>
<slot name="name1" :data2="user"></slot>
</div>
</template>
<script setup lang="ts">
const user = { lastName: "Huang" };
</script>
3、实例:todo列表
(1)运行结果
(2)App.vue参考源码
<template>
<div class="container-component-a">
<h1>组件A</h1><hr>
<HelloWorld>
<template v-slot:name1="data1">
<span v-if="data1.data2.isCompleted">√</span>
{{data1.data2.title}}
</template>
</HelloWorld>
</div>
</template>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
</script>
(3)HelloWorld.vue参考源码
<template>
<div class="container-component-b">
<h1>组件HelloWorld</h1>
<ul>
<li v-for="todo in todoLists" v-bind:key="todo.id">
<slot name="name1" :data2="todo"></slot>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
const todoLists = [
{
id: 1,
title: "吃饭",
isCompleted: true,
},
{
id: 2,
title: "睡觉",
},
{
id: 3,
title: "打逗逗",
},
];
</script>