Vue.createApp(对象).mount(dom容器)
对象里面可以有 template模板 data数据(函数形式)methods方法
dom容器 “#root” ‘#app’ 带有选择器的dom容器
其中template有两种写法
方式一:在另一个script里面写,注明选择器类型 在对象里面直接取(这里是通过id) template: ‘#why’
<script type="x-template" id="why">
<div>
<h2>{{message}}</h2>
<h2>{{counter}}</h2>
<button @click='increment'>+1</button>
<button @click='decrement'>-1</button>
</div>
</script>
<script src="../js/vue.js"></script>
<script>
document.querySelector("#why")
Vue.createApp({
template: '#why',
data: function() {
return {
message: "Hello World",
counter: 100
}
},
// 定义各种各样的方法
methods: {
increment() {
console.log("点击了+1");
this.counter++;
},
decrement() {
console.log("点击了-1");
this.counter--;
}
}
}).mount('#app');
</script>
方式二:写在与app同级的html页面结构中 同样是通过选择器获取 (这里是通过id)
<body>
<div id="app"></div>
<template id="why">
<div>
<h2>{{message}}</h2>
<h2>{{counter}}</h2>
<button @click='increment'>+1</button>
<button @click='decrement'>-1</button>
<button @click="btnClick">按钮</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
document.querySelector("#why")
Vue.createApp({
template: '#why',
data: function() {
return {
message: "Hello World",
counter: 100
}
},
// 定义各种各样的方法
methods: {
increment() {
console.log("点击了+1");
this.counter++;
},
decrement() {
console.log("点击了-1");
this.counter--;
},
btnClick: () => {
// this === window? 不可以
// 写成一个箭头函数时, 这个this就是window
// 在箭头函数中是不绑定this, 但是函数中如果使用了this
console.log(this);
},
btn2Click: function() {
// this === window? 不可以
// 写成一个箭头函数时, 这个this就是window
// 在箭头函数中是不绑定this, 但是函数中如果使用了this
console.log(this);
}
}
}).mount('#app');
</script>
</body>
双大括号语法 (mustache语法) {{ }}
是一个js表达式
<h2>{{counter * 10}}</h2>
可以调用函数
<h2>{{ message.split(" ").reverse().join(" ") }}</h2>
可以使用computed(计算属性)
<h2>{{getReverseMessage()}}</h2>
三元运算符
<h2>{{ isShow ? "哈哈哈": "" }}</h2>
基本指令: v-once 只渲染一次 即使里面数据改变也保持第一次的状态 在容器上加 表示只渲染一次不改变
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{counter}}</h2>
<div v-once>
<h2>{{counter}}</h2>
<h2>{{message}}</h2>
</div>
<button @click="increment">+1</button>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
counter: 100,
message: "abc"
}
},
methods: {
increment() {
this.counter++;
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
基本指令 v-text 会覆盖容器里面的children 展示v-text里面赋的data里面的函数数据注意是文本 字符串标签不会
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2 v-text="message"></h2>
<h2>{{message}}</h2>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
message: "Hello World"
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
基本指令 v-html 会覆盖容器里面的children 展示v-html里面赋的data里面的函数数据 可以把结构(包含里面的样式)渲染出来
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<div>{{msg}}</div>
<div v-html="msg"></div>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
msg: '<span style="color:red; background: blue;">哈哈哈</span>'
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
基本指令 v-pre 能把{{}}展示在页面中 和html中</pre/>标签一样 把你写的内容原封不动的展示出来
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2 v-pre>{{message}}</h2>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
message: "Hello World"
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
基本指令:v-cloak 可以给模板中模板字符串中的标签设置样式
<!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>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2 v-cloak>{{message}}</h2>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
message: "Hello World11"
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
基本指令 v-bind
基本使用:后面跟的是的属性 把data里面的属性赋给被绑定的属性
<img v-bind:src="imgUrl" alt="">
<a v-bind:href="link">百度一下</a>
data() {
return {
imgUrl: "https://avatars.githubusercontent.com/u/10335230?s=60&v=4",
link: "https://www.baidu.com"
}
}
v-bind语法糖: 一个英文冒号
<img :src="imgUrl" alt="">
<img src="imgUrl" alt="">
绑定class对象语法 {“active”:boolean}
<div :class="{'active': isActive}">呵呵呵呵</div>
也可以是多个键值对
<div :class="{active: isActive, title: true}">呵呵呵呵</div>
默认的class和动态class结合
<div class="abc cba" :class="{active: isActive, title: true}">
对象放到一个单独的属性重中
<div class="abc cba" :class="classObj">呵呵呵呵</div>
data() {
return {
className: "why",
isActive: true,
title: "abc",
classObj: {
active: true,
title: true
},
};
},
将返回的对象放到一个methods(computed)方法中
<div class="abc cba" :class="getClassObj()">呵呵呵呵</div>
methods: {
toggle() {
this.isActive = !this.isActive;
},
getClassObj() {
return {
active: true,
title: true
}
}
},
绑定class数组语法:
<div :class="['abc', title]">哈哈哈哈</div>
<div :class="['abc', title, isActive ? 'active': '']">哈哈哈哈</div>
<div :class="['abc', title, {active: isActive}]">哈哈哈哈</div>
data() {
return {
title: "cba",
isActive: true
}
}
绑定style样式 对象语法
data() {
return {
message: "Hello World",
finalColor: 'red',
finalFontSize: 50,
finalStyleObj: {
'font-size': '50px',
fontWeight: 700,
backgroundColor: 'red'
}
}
},
methods: {
getFinalStyleObj() {
return {
'font-size': '50px',
fontWeight: 700,
backgroundColor: 'red'
}
}
}
<div :style="{color: finalColor, 'font-size': '30px'}">哈哈哈哈</div>
<div :style="{color: finalColor, fontSize: '30px'}">哈哈哈哈</div>
<div :style="{color: finalColor, fontSize: finalFontSize + 'px'}">哈哈哈哈</div>
绑定data中的属性值,并且是一个对象
<div :style="finalStyleObj">呵呵呵呵</div>
调用一个方法
<div :style="getFinalStyleObj()">呵呵呵呵</div>
绑定style样式 数组语法
data() {
return {
message: "Hello World",
style1Obj: {
color: 'red',
fontSize: '30px'
},
style2Obj: {
textDecoration: "underline"
}
}
}
<div :style="[style1Obj, style2Obj]">哈哈哈</div>
<img :src="" alt="">
<a :href=""></a>
<div :class></div>
动态绑定属性名称
data() {
return {
name: "cba",
value: "kobe"
}
}
<div :[name]="value">哈哈哈</div>
直接绑定一个对象
data() {
return {
info: {
name: "why",
age: 18,
height: 1.88
}
}
}
<div v-bind="info">哈哈哈哈</div>
<div :="info">哈哈哈哈</div>
基本指令 v-on
methods: {
btn1Click() {
console.log("按钮1发生了点击");
},
mouseMove() {
console.log("鼠标移动");
}
}
v-on:监听的事件 =“methods中的方法”
<button v-on:click="btn1Click">按钮1</button>
<div class="area" v-on:mousemove="mouseMove">div</div>
语法糖
<button @click="btn1Click">按钮1</button>
绑定一个表达式 inline statement
<button @click="counter++">{{counter}}</button>
绑定一个对象
<div class="area" v-on="{click: btn1Click, mousemove: mouseMove}"></div>
<div class="area" @="{click: btn1Click, mousemove: mouseMove}"></div>
参数传递
默认传如event独享 可以在方法中获取
<button @click="btn1Click">按钮1</button>
$event可以获取到事件发生时的事件·1对象
<button @click="btn2Click($event, 'coderwhy', 18)">按钮2</button>
methods: {
btn1Click(event) {
console.log(event);
},
btn2Click(event, name, age) {
console.log(name, age, event);
}
}
按钮1:
PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
按钮2:
coderwhy 18 PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
v-on修饰符
键盘enter键按下触发 默认有一个参数是event对象 必须通过value来取
<input type="text" @keyup.enter="enterKeyup">
methods: {
enterKeyup(event) {
console.log("keyup", event.target.value);
}
}
只有btn触发 div不触发
<div @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
methods: {
divClick() {
console.log("divClick");
},
btnClick() {
console.log('btnClick');
}
}
条件渲染
基本使用
data() {
return {
message: "Hello World",
isShow: true
}
},
methods: {
toggle() {
this.isShow = !this.isShow;
}
}
<h2 v-if="isShow">哈哈哈哈</h2>
<button @click="toggle">切换</button>
多个渲染条件
data() {
return {
score: 95
}
}
}
<input type="text" v-model="score">
<h2 v-if="score > 90">优秀</h2>
<h2 v-else-if="score > 60">良好</h2>
<h2 v-else>不及格</h2>
和template和v-if结合使用
data() {
return {
isShowHa: true
}
}
<template id="my-app">
<template v-if="isShowHa">
<h2>哈哈哈哈</h2>
<h2>哈哈哈哈</h2>
<h2>哈哈哈哈</h2>
</template>
<template v-else>
<h2>呵呵呵呵</h2>
<h2>呵呵呵呵</h2>
<h2>呵呵呵呵</h2>
</template>
</template>
v-show的条件渲染
data() {
return {
isShow: true
}
}
<h2 v-show="isShow">哈哈哈哈</h2>
v-if和v-show的区别
data() {
return {
isShow: false
}
}
<h2 v-if="isShow">哈哈哈哈</h2>
<h2 v-show="isShow">呵呵呵呵</h2>
v-if 是有个<!--v-if-->占位 是完全在页面中消失
v-show是利用加上行内样式 style=“display:none” 使元素隐藏 结构还在页面中
列表渲染
data() {
return {
movies: [
"星际穿越",
"盗梦空间",
"大话西游",
"教父",
"少年派"
],
info: {
name: "why",
age: 18,
height: 1.88
}
}
}
注意参数次序
遍历数组
<li v-for="(movie, index) in movies">{{index+1}}.{{movie}}</li>
遍历对象
<li v-for="(value,key,index) in info "> {{value}}-{{key}}-{{index}}</li>
遍历数字
<li v-for="(num, index) in 10">{{num}}-{{index}}</li>
v-for和template结合使用
data() {
return {
info: {
name: "why",
age: 18,
height: 1.88
}
}
}
<template v-for="(value, key) in info">
<li>{{key}}</li>
<li>{{value}}</li>
<li class="divider"></li>
</template>
数组修改方法
data() {
return {
newMovie: "",
movies: [
"星际穿越",
"盗梦空间",
"大话西游",
"教父",
"少年派"
]
}
},
methods: {
addMovie() {
this.movies.push(this.newMovie);
this.newMovie = "";
// this.movies = this.movies.filter(item => item.length > 2);
}
}
<input type="text" v-model="newMovie">
<button @click="addMovie">添加电影</button>
实例
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>电影列表</h2>
<ul>
<li v-for="(movie, index) in movies">{{index+1}}.{{movie}}</li>
</ul>
<input type="text" v-model="newMovie">
<button @click="addMovie">添加电影</button>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
newMovie: "",
movies: [
"星际穿越",
"盗梦空间",
"大话西游",
"教父",
"少年派"
]
}
},
methods: {
addMovie() {
this.movies.push(this.newMovie);
this.newMovie = "";
// this.movies = this.movies.filter(item => item.length > 2);
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
key案例 插入f元素
补充:splice第一个参数表示开始插入的索引位置,0表示删除0个,后面的表示添加的元素
arr=['0赵','1钱','2孙','3李']
arr.splice(2,0,'李')
console.log(arr);
(5) ['0赵', '1钱', '李', '2孙', '3李']
<!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>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
<button @click="insertF">插入F元素</button>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
letters: ['a', 'b', 'c', 'd']
}
},
methods: {
insertF() {
this.letters.splice(2, 0, 'f')
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>