案例一:watch用法
<!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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<!-- push pop尾部追加或移除;shift unshift头部追加或移除,splice分割 -->
<body>
<div id="Application">
<div>{{type}} {{count}}</div>
<button @click="click">增加</button>
<button @click="jian">减少</button>
<input v-model="searchText" />
</div>
</body>
<script>
Vue.createApp({
data() {
return {
count: 0,
searchText:""
}
},
computed:{
type(){
return this.count>5?"大":"小"
}
},
watch:{
searchText(newValue,old){
this.count = newValue.length
if(this.type == "大"){
alert("文本太长")
}
}
},
methods: {
click(){
this.count = this.count+1;
},
jian(){
this.count = this.count-1;
}
}
}).mount("#Application");
</script>
</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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
.red {
color: red;
}
.blue {
color: blue;
}
</style>
</head>
<!-- push pop尾部追加或移除;shift unshift头部追加或移除,splice分割 -->
<body>
<div id="Application">
<div>{{type}} {{count}}</div>
<button @click="click">增加</button>
<button @click="jian">减少</button>
<input v-model="searchText" />
<textarea v-model="textareaT"></textarea>
<p style="white-space: pre-line;">多行文本内容:<br/>{{textareaT}}</p>
<input type="checkbox" v-model="singleCheck" value="足球" />
<input type="checkbox" v-model="singleCheck" value="排球" />
<p>{{singleCheck}}</p>
<input type="radio" v-model="qiu" value="足球2" />
<input type="radio" v-model="qiu" value="排球1" />
<p>{{qiu}}</p>
<select v-model="selectList" multiple>
<option>三国志</option>
<option>DNF</option>
<option>崩坏3</option>
</select>
<p :class="style">{{selectList}}</p>
</div>
</body>
<script>
Vue.createApp({
data() {
return {
count: 0,
searchText:"",
textareaT:"",
singleCheck:[],
qiu:"",
selectList:[],
style:{
red: true,
blue: false
},
}
},
computed:{
type(){
return this.count>5?"大":"小"
}
},
watch:{
searchText(newValue,old){
this.count = newValue.length
if(this.type == "大"){
alert("文本太长")
}
}
,
qiu(nv,oldv){
if(nv == '排球1'){
this.style.red = true;
this.style.blue =false;
}else{
this.style.red = false;
this.style.blue =true;
}
}
},
methods: {
click(){
this.count = this.count+1;
},
jian(){
this.count = this.count-1;
}
}
}).mount("#Application");
</script>
</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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
.red {
color: red;
}
.blue {
color: blue;
}
.container {
margin: 0 auto;
margin-top: 70px;
text-align: center;
width: 300px;
}
.subTitle {
color: gray;
font-size: 14px;
}
.title {
font-size: 45px;
}
.input {
width: 90%;
}
.inputContainer {
text-align: left;
margin-bottom: 20px;
}
.subContainer {
text-align: left;
}
.field {
font-size: 14px;
}
.input {
border-radius:
6px;
height: 25px;
margin-top: 10px;
border-color: silver;
border-style: solid;
background-color: cornsilk;
}
.tip {
margin-top: 5px;
font-size: 12px;
color: gray;
}
.setting {
font-size: 9px;
color: black;
}
.label {
font-size: 12px;
margin-left: 5px;
height: 20px;
vertical-align: middle;
}
.checkbox {
height: 20px;
vertical-align: middle;
}
.btn {
border-radius: 10px;
height: 40px;
width: 300px;
margin-top: 30px;
background-color: deepskyblue;
border-color: blue;
Color: white;
}
</style>
</head>
<!-- push pop尾部追加或移除;shift unshift头部追加或移除,splice分割 -->
<body>
<div class="container" id="app">
<div class="container">
<div class="subTitle">
加入我们,一起创造美好世界
</div>
<h1 class="title">创建你的账号</h1>
<div v-for="(item,index) in fields" class="inputContainer">
<div class="field">{{item.title}}
<span v-if="item.required" style="color:red">*</span>
<input class="input" :type="item.type" v-model="item.model" />
<div class="tip" v-if="index==2">请确认密码长度大于6</div>
</div>
</div>
<div class="subContainer">
<div class="setting">偏好设置</div>
<input class="checkbox" type="checkbox" /><label class="label">接受更新邮件</label>
</div>
<button @click="createAccount" class="btn">创建账号</button>
</div>
</div>
</body>
<script>
Vue.createApp({
data() {
return {
fields: [
{
title: "用户名",
required: true,
type: "text",
model:""
},
{
title: "邮箱地址",
required: false,
type: "text",
model:""
},
{
title: "密码",
required: true,
type: "password",
model:""
},
]
}
},
computed: {
name: {
get() {
return this.fields[0].model
},
set(value){
this.fields[0].model= value
}
},
email: {
get() {
return this.fields[1].model
},
set(value){
this.fields[1].model= value
}
},
password: {
get() {
return this.fields[2].model
},
set(value){
this.fields[2].model= value
}
}
},
methods: {
emailCheck() {
alert('email检查')
},
createAccount(){
alert(`name=${this.name}`)
}
},
}).mount("#app")
</script>
</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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
.container {
margin: 0;
padding: 0;
/* position: absolute; */
width: 440px;
height: 440px;
background-color: blanchedalmond;
border-radius: 30px;
z-index: 100;
}
.bail {
position: absolute;
width: 60px;
height: 60px;
left: 100px;
top: 100px;
background-color: red;
border-radius: 30px;
z-index: 100;
}
</style>
</head>
<body>
<div id ="move2">
<div class="container" @mousemove.stop="move">
<div class = "bail" :style="{left:offsetX+'px', top:offsetY+'px'}">
</div>
</div>
</div>
<div id="app">
<div @click="click">单击事件</div>
<div @dblclick="dblclick">双击事件</div>
<input @focus="focus" @blur="blur" @change="change" @select="select"></input>
<div @mousedown="mousedown">鼠标按下</div>
<div @mouseup="mouseup">鼠标抬起</div>
<div @mousemove="mousemove">鼠标移动</div>
<div @mouseout="mouseout" @mouseover="mouseover">鼠标移入移出</div>
<input @keydown="keydown" @keyup="keyup"></input>
<div @click.left="click">左键单击事件</div>
<div @click.right="click">右键单击事件</div>
<div @click.middle="click">中键单击事件</div>
</div>
</body>
<script>
const App = {
methods: {
click() {
console.log("单击事件");
},
dblclick() {
console.log("双击事件");
},
focus() {
console.log("获取焦点")
},
blur() {
console.log("失去焦点")
},
change() {
console.log("内容改变")
},
select() {
console.log("文本选中")
},
mousedown() {
console.log("鼠标按键按下")
},
mouseup() {
console.log("鼠标按键抬起")
},
mousemove() {
console.log("鼠标移动")
},
mouseout() {
console.log("鼠标移出")
},
mouseover() {
console.log("鼠标移入")
},
keydown() {
console.log("键盘按键按下")
},
keyup() {
console.log("键盘按键抬起")
}
}
}
app1 = Vue.createApp(App).mount("#app");
Vue.createApp({
data() {
return {
offsetX:0,
offsetY:0
}
},
methods:{
move(event){
if(event.clientX +30>440){
this.offsetX = 440 -60
}
else if (event.clientX - 30 <0){
this.offsetX = 0
}
else{
this.offsetX = event.clientX-30
}
if(event.clientY +30>440){
this.offsetY = 440 -60
}
else if (event.clientY - 30 <0){
this.offsetY = 0
}
else{
this.offsetY = event.clientY-30
}
}
}
}).mount("#move2");
</script>
</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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
margin: 0 auto;
width: 440px;
height: 440px;
background-color: blanchedalmond;
}
.ball {
position: absolute;
width: 30px;
height: 30px;
left: 0px;
top: 0px;
background-color: orange;
border-radius: 30px;
}
.board {
position: absolute;
left: 0;
bottom: 0;
height: 10px;
width: 80px;
border-radius: 5px;
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<!--游戏区域-->
<div class="container">
<!--底部挡板-->
<div class="board" :style="{left: boardX + 'px'}"></div>
<!--弹球-->
<div class="ball" :style="{left: ballX+'px', top: ballY+'px' }"></div>
<!--游戏结束提示-->
<h1 v-if="fail" style="text-align: center;">游戏失败</h1>
</div>
</div>
</body>
<script>
var app = {
data() {
return {
// 挡板位置
boardX: 0,
// 球位置
ballX: 0,
ballY: 0,
// 速度
rateX: 0.1,
rateY: 0.1,
fail: false
}
},
mounted() {
this.enterKeyup();
// 随即弹球速度和轨迹
this.rateX = Math.random() + 0.1
this.rateY = Math.random() + 0.1
this.timer = setInterval(() => {
if (this.ballX + this.rateX >= 440 - 30) {
this.rateX *= -1
}
if (this.ballX + this.rateX <= 0) {
this.rateX *= -1
}
if (this.ballY + this.rateY <= 0) {
this.rateY *= -1
}
this.ballX += this.rateX
this.ballY += this.rateY
if (this.ballY >= 440 - 30 - 10) {
if (this.boardX <= this.ballX + 30 && this.boardX + 80 >= this.ballX) {
// 反弹
this.rateY *= -1
} else {
clearInterval(this.timer)
this.fail = true
}
}
}, 2)
},
methods: {
keydown(event) {
if (event.key == "ArrowLeft") {
if (this.boardX > 10) {
this.boardX -= 20
}
} else if (event.key == "ArrowRight") {
if (this.boardX < 440 - 80) {
this.boardX += 20
}
}
},
enterKeyup(){
document.addEventListener("keydown", this.keydown)
}
},
}
Vue.createApp(app).mount("#app");
</script>
</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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<!-- 父组件传值到子组件,子组件回传参数到父组件的事件 -->
<myalert-com @myclick="alert1" title="崩坏3" ><template #header>具名header插槽</template><template #foot>具名foot22插槽</template></myalert-com>
<myalert-com @myclick="alert2" title="DNF" ><template #foot>具名foot插槽</template></myalert-com>
<!-- 子组件传值到父组件 -->
<myinput-com v-model="modelValue1"></myinput-com>
<myinput-com v-model="modelValue2"></myinput-com>
<label for="myalert-com">myalert-com</label>
<input type="radio" value="myalert-com" v-model="page" />
<label for="myinput-com">myinput-com/label>
<input type="radio" value="myinput-com" v-model="page" />
<!-- 组件切换 -->
<component :is="page"></component>
</div>
</body>
<script>
const App = Vue.createApp({
data(){
return {
modelValue1:"input1",
modelValue2:"input2",
page:"myinput-com"
}
},
methods:{
alert1(var1,var2){
alert("方法1,参数1="+var1+"参数2="+var2)
},
alert2(var1,var2){
alert("方法2,参数1="+var1+"参数2="+var2)
}
},
watch:{
modelValue1(nv,ov){
alert(nv+"__1__"+ov)
},
modelValue2(nv,ov){
alert(nv+"__2__"+ov)
}
}
})
const alertCompent = {
data(){
return {
msg:"警告提示",
count:0
}
},
computed:{
countString:{
get(){
return this.count + "次"
}
}
},
methods:{
click(){
this.count +=1
this.$emit('myclick', this.count, this.title)
}
},
// 外部属性
props:["title"],
watch:{
count(nv,oldv){
console.log(nv, oldv)
}
},
template:`<div><button @click="click">{{title}}按钮+1<slot name="header"></slot><slot name="foot"></slot></button></div>`
}
const inputCompent = {
props:["modelValue"],
methods:{
action(event){
this.$emit("update:modelValue", event.target.value)
}
},
template:`<div><input :value="modelValue" @input="action" /></div>`
}
App.component("myalert-com", alertCompent)
App.component("myinput-com", inputCompent)
App.mount("#app")
</script>
</html>