使用js方式引入
在页面上引入Vue的js
<body>
<div id="app">
{{message}}
</div>
<!--引入Vue库 可以自行到官网上拷贝,自己建一份进行引入-->
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
<!--下面是复制上面建立的本地文件来引用Vue库-->
<script src="./js/vue3.js"></script>
<script>
/*vue就是对js的DOM进行了封装*/
//创建一个vue 的实例对象
const app=Vue.createApp({
//data里面存放变量信息
data () {
return {
message:'hello world',
count:0,
name:'张三'
}
},
//存放Vue中存放的方法
methods: {
/* add:function(){
} 下方简化方法*/
add(){
}
}
})
//vue对象绑定标签,指定作用范围
app.mount('#app')
</script>
</body>
插值表达式
<div>
文本数据{{ }}
</div>
{{ }}:书写在双标签之间,给标签中插入文本数据.
在HTML中使用{{ }},给页面指定位置插入数据, 内部可以写:
- 基本的js 表达式
- Vue中的数据变量,常量
- 调用Vue中提供的函数(方法调用)
<body> <div id="app1"> <!-- 差值表达式 {{常量 变量 表达式 方法调用}} --> {{message}} <p>{{3}}</p> <p>{{3+1}}</p> <p>{{age>=18?'成年':'未成年'}}</p> <p>{{add()}}</p> </div> <script src="./js/vue3.js"></script> <script> /*vue就是对js的DOM进行了封装*/ //创建一个vue 的实例对象 const app=Vue.createApp({ //data里面存放变量信息 data () { return { message:'hello world', count:0, name:'张三', age:20 } }, //存放Vue中存放的方法 methods: { /* add:function(){ } 下方简化方法*/ add(){ return '啊哈哈哈' } } }) //vue对象绑定标签,指定作用范围 app.mount('#app1') </script> </body>
v-html和v-text指令
指令Vue的指令都是以v-xxx格式书写的,在HTML标签的属性位置上使用.
<div class="box" id="b1" v-xxx="指令相关的代码">
</div>
代码演示:
<body>
<div id="app">
<!--v-html:相当于原生innerHTML,插入数据会覆盖标签原有数据,用来改变标签内容,内容中包含标签会被解析--->
<!--v-text:相当于原生innerText,插入数据会覆盖标签原有数据,用来改变标签内容,内容中包含标签不会被解析--->
<p>{{message}}</p>
<p v-html="news">原有内容</p>
<p v-text="news">原有内容</p>
</div>
<script src="./js/vue3.js"></script>
<script>
const app=Vue.createApp({
data () {
return {
news:"<b>啊哈哈哈哈</b>",
message:'插入数据演示'
}
},
methods: {
}
})
app.mount('#app')
</script>
</body>
v-show和v-if指令
v-show与v-if的异同:
相同点:都可以控制页面的标签显示和隐藏,当他们的值为true标签显示,值为false标签会被隐藏
不同点:
- v-show:它底层采用的css的display属性控制标签的显示与隐藏,也就是说,即使看不见标签,但是标签依然在html结构中。
- v-if:它底层控制的是dom结构,当值为false的时候,是将标签从页面上删除
- 安全方向:v-if更安全,标签被删除,无法操作,v-show,只是添加样式,可以通过浏览器的辅助功能进行标签的再次编辑
- 性能方向:v-show不改动dom结构,性能高一些。
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width: 200px;
height: 200px;
background-color: red;
}
.box2{
width: 200px;
height: 200px;
background-color:green ;
}
</style>
</head>
<body>
<div id="app">
<!--
v-show :控制标签的隐藏与显示 底层通过控制style的display中,在DOM结构中仍然存在
v-if :控制标签的隐藏与显示,隐藏标签时删除dom标签中的元素,实现显示与隐藏
安全:v-if更安全,v-show不安全,可以进入控制台手动控制
性能:v-show性能更高,v-if是控制标签的删除和添加,v-show只用改一个属性
应用场景:频繁切换使用v-show ,在考虑安全性时使用v-if
-->
<div class="box1" v-show="flag"></div>
<div class="box2" v-if="!flag"></div>
<button v-on:click="changeDiv()">切换</button>
</div>
<script src="./js/vue3.js"></script>
<script>
const app=Vue.createApp({
data () {
return {
flag:true
}
},
methods: {
changeDiv(){
this.flag=!this.flag;
}
}
})
app.mount('#app')
</script>
</body>
</html>
多条件判断渲染(v-if="条件" ,v-else-if="条件" ,v-else)
<body>
<div id="app">
<!-- <button v-on:click="changeImg()">切换图片{{num}}</button> -->
<button @click="changeImg()">切换图片{{num}}</button>
<br>
<img src="./imgs/qq.png" alt="" v-if="imgNum==0">
<img src="./imgs/wangpan.png" alt="" v-else-if="imgNum==1">
<img src="./imgs/weixin.png" alt="" v-else>
</div>
<script src="./js/vue3.js"></script>
<script>
// 需要从VueJS文件中得到创建Vue实例的方法
// let { createApp } = Vue;
// 得到Vue实例
const app=Vue.createApp({
data () {
return {
num:1,
imgNum:1
}
},
methods: {
changeImg(){
this.num++;
this.imgNum=this.num%3;
}
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
</body>
v-for指令
在页面上通过for循环,渲染数据
语法格式:
<div v-for="(value,key) in 字符串|数组|对象|数字" v-bind:key="唯一标识">
</div>
代码演示:
<body>
<div id="app">
<!--
v-for 循环遍历
遍历的数据:数组,字符串,对象,对象数组, 常量
v-for:第一个变量,可以用来接受循环遍历的每一个元素
v-for:第一个变量,可以用来接受循环遍历的每一个元素,第二个变量代表索引,
如果遍历的是对象,第二个变量是属性名
-->
<!-- 数组 -->
<ul>
<li v-for="item in news">{{item}}</li>
</ul>
<!-- 字符串 -->
<p v-for="letter in Str1">{{letter}}</p>
<!-- 对象 -->
<span v-for="p in user">{{p}}</span><br>
<!-- 数组 -->
<span v-for="(p1,index) in user">{{index+"====="+p1+" "}}</span>
<!-- 对象数组 -->
<table border="2px" align="center">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<tr v-for="(user,index) in userList">
<td>{{index+1}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
</table>
</div>
<script src="./js/vue3.js"></script>
<script>
//创建Vue实例
const app=Vue.createApp({
data () {
return {
news:["娱乐",'国际',"时政"],
Str1:"hello vue",
user:{
name:"张三",
age:18,
},
userList:[
{
name:"张三",
age:18,
},
{
name:"李四",
age:20,
},
{
name:"王五",
age:18,
}]
}
},
methods: {
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
</body>
v-on指令
v-on指令:给页面标签绑定js事件. 可以简化为@事件名="需执行函数"
书写格式:
<button v-on:事件名="需要执行的函数名">按钮</button>
<button v-on:事件名="需要执行的函数名(参数1,参数2,....)">按钮</button>
<button v-on:事件名="需要执行的函数名(参数1,参数2,$event,.....)">按钮</button>
<button @事件名="需要执行的函数名">按钮</button>
<body>
<!-- 使用vue开发前端页面,必须在页面给出vue所控制(管理)的区域 -->
<div id="app">
<!--
直接调用 ,本质是传递的事件对象自身,开发中可以省略不写
show($event)
-->
<button v-on:click="show">按钮:通过函数名直接调用</button>
<!-- 调用的同时传递参数 -->
<!--<button v-on:click="show(11,22,33)">按钮:通过函数名调用并传递参数</button>-->
<button @click="show(11,22,33)">按钮:通过函数名调用并传递参数</button>
<!--
在JS中事件四要素:
事件源:发生事件(动作)的源头
事件对象:在事件源上发生事件的时候,浏览器会将事件(动作)封装成对象传递给处理函数
事件类型:具体发生了什么事件(click、mouseover、mouseout、keyup、keydown、scroll....)
事件处理函数:事件发生之后,对应的需要执行的函数
-->
<!-- 在调用函数的时候,可以传递事件对象本身 -->
<div
v-on:mouseover="show(11,22,$event)"
style="width: 200px;height: 200px;background-color: #0a0;">
按钮:通过函数名调用并传递参数
</div>
</div>
<script src="./js/vue.js"></script>
<script>
// 1. 创建vue实例
const app = Vue.createApp({
methods: {
show(a, b, c) {
console.log("show", a, b, c);
}
}
});
// 2、将vue与页面绑定
app.mount("#app");
</script>
</body>
事件修饰符
在对应的时间名称后,书写下面的修饰符(支持链式编程),万和城呢个相关的一些时间关联性的操作.
-
.stop
- 调用event.stopPropagation()
。 阻止事件冒泡 -
.prevent
- 调用event.preventDefault()
。阻止事件的默认行为 -
.capture
- 在捕获模式添加事件监听器。 -
.self
- 只有事件从元素本身发出才触发处理函数。 -
.{keyAlias}
- 只在某些按键下触发处理函数。 -
.once
- 最多触发一次处理函数。 -
.left
- 只在鼠标左键事件触发处理函数。 -
.right
- 只在鼠标右键事件触发处理函数。 -
.middle
- 只在鼠标中键事件触发处理函数。 -
.passive
- 通过{ passive: true }
附加一个 DOM 事件。
代码演示:盒子模型
<body>
<div id="app">
<!--.capture 事件捕获 由外向内-->
<div class="box1" @click.capture="one">
<!--阻止事件冒泡(由内向外) @click.stop -->
<!-- .once 事件只会执行一次 注:设置once stop self都 失效-->
<div class="box2" @click.self="two">
<!-- <div class="box2" @click.stop.self="two"> -->
<div class="box3" @click="three">
</div>
</div>
</div>
<!-- 阻止事件的默认行为 -->
<a href="http://www.baidu.com" @click.prevent="tao">百度</a>
</div>
<script src="./js/vue3.js"></script>
<script>
//创建Vue实例
const app=Vue.createApp({
data () {
return {
}
},
methods: {
one(){
console.log('外');
},
two(){
console.log('中');
},
three(){
console.log('内');
},
tao(){
console.log("跳转百度");
}
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
</body>
按键修饰符
-
.enter
-
.tab
-
.delete
(捕获“Delete”和“Backspace”两个按键) -
.esc
-
.space
-
.up
-
.down
-
.left
-
.right
代码演示(点击回车键登录):
<body>
<div id="app">
<p>账号:<input type="text"></p>
<p>密码:<input type="password" @keydown.enter="login"></p>
<p><button @click="login">登录</button></p>
</div>
<script>
// 需要从VueJS文件中得到创建Vue实例的方法
let { createApp } = Vue;
// 得到Vue实例
let app = createApp({
data() {
return {
}
},
methods: {
demo(event) {
console.log(event);
if (event.which == 13) {
this.login()
}
console.log(111);
},
login() {
console.log("登录");
}
}
});
// 将Vue实例与页面绑定
app.mount("#app")
</script>
</body>
V-model指令
v-model:在表单输入元素或者组件上创建双向绑定 ,指令主要作用于表单的 input select textarea;
双向绑定(MVVM)
- M:Model(数据)模型
- V:View(页面)视图
- VM:ViewModel(视图模型),主要使用dom监听和数据绑定(Vue2和Vue3的底层算法diff不同,Vue2 中使用数据劫持,即拿出data里面的数据进行遍历. Vue3使用代理, 即原有的对象复制,更改有变化的数据,vue3的效率大概是Vue2的二到三倍);
代码演示(表单操作):
<div id="app">
<form action="#" method="get">
<p>用户名:<input type="text" name="username" v-model="username"></p>
<p>密码:<input type="text" name="password" v-model="password"></p>
<p>性别:<input type="radio" name="sex" value="1" v-model="sex">男<input type="radio" name="sex" value="0" v-model="sex">女</p>
<p>爱好:<input type="checkbox" name="hobby" value="java" v-model="hobby">java<input type="checkbox" name="hobby" value="HTML" v-model="hobby">HTML</p>
<p>
地址:
<select name="address" id="" v-model="address">
<option value="xy">信阳</option>
<option value="zz">郑州</option>
<option value="tj">天津</option>
<option value="bj">北京</option>
</select>
</p>
<p>简介:<textarea name="desc" v-model="desc"></textarea></p>
</form>
</div>
<script src="./js/vue3.js"></script>
<script>
//创建Vue实例
const app=Vue.createApp({
data () {
return {
username:"",
password:"",
sex:"",
hobby:[],
address:"",
desc:""
}
},
methods: {
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
</body>
v-model底层实现原理(DOM Listeners)
-
文本类型的
<input>
和<textarea>
元素会绑定value
property 并侦听input
事件; -
<input type="checkbox">
和<input type="radio">
会绑定checked
property 并侦听change
事件; -
<select>
会绑定value
property 并侦听change
事件。
v-model
会忽略任何表单元素上初始的value
、checked
或selected
attribute。它将始终将当前绑定的 JavaScript 状态视为数据的正确来源。你应该在 JavaScript 中使用data 选项来声明该初始值。
<body>
<!-- 使用vue开发前端页面,必须在页面给出vue所控制(管理)的区域 -->
<div id="app">
<!--oninput事件是在表单元素的值发生变化时立刻触发,而onchange事件是在表单元素的值发生变化并且元素失去焦点时触发。-->
<p>姓名:<input type="text" name="username" oninput="getData()" value="123"></p>
<button onclick="changeData()">修改数据</button>
<select id="addr" onchange="changeSelect()">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<script src="./js/vue3.js"></script>
<script>
function changeData() {
document.querySelector("input").value = "abcde"
}
function getData() {
let username = document.querySelector("input").value;
console.log(username);
}
function changeSelect() {
console.log(document.querySelector("#addr").value);
}
</script>
</body>
模拟拿出用户原有信息,对用户信息的修改功能:
<body>
<div id="app">
<form action="#" method="get">
<p>用户名:<input type="text" name="username" v-model="username"></p>
<p>密码:<input type="text" name="password" v-model="password"></p>
<p>性别:<input type="radio" name="sex" value="1" v-model="sex">男<input type="radio" name="sex" value="0" v-model="sex">女</p>
<p>爱好:<input type="checkbox" name="hobby" value="java" v-model="hobby">java<input type="checkbox" name="hobby" value="HTML" v-model="hobby">HTML</p>
<p>
地址:
<select name="address" id="" v-model="address">
<option value="xy">信阳</option>
<option value="hn">郑州</option>
<option value="tj">天津</option>
<option value="bj">北京</option>
</select>
</p>
<p>简介:<textarea name="desc" v-model="desc"></textarea></p>
<input type="button" value="修改" @click="updateUser">
</form>
</div>
<script src="./js/vue3.js"></script>
<script>
//创建Vue实例
const app=Vue.createApp({
data () {
return {
username:"",
password:"",
sex:"",
hobby:[],
address:"",
desc:""
}
},
methods: {
updateUser(){
//过程:发起请求,请求后台,获取后台的数据,此处为模拟数据
this.username="张三";
this.password="123";
this.sex="1";
this.hobby=['java'];
this.address="xy";
this.desc="撒哈哈哈";
}
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
v-model的修饰符
-
.lazy - 监听
change
事件而不是input
,等输入框中的数据输入完成之后,光标切换到其他位置才会触发 -
.number- 将输入的合法字符串转为数字,不能限制用户输入非数字内容 - 移除输入内容两端空格,
<input type="text" v-model.lazy="student.username">
<input type="text" v-model.number="student.grade">
<textarea cols="30" rows="10" v-model.trim="student.desc"></textarea>
v-bind指令
v-bind:动态的绑定一个或多个attribute(让标签的属性名或者属性值变成动态数据)
<img v-bind:src="imgUrl" alt="" width="100px" height="100px">
//简化写法
<img :src="imgUrl" alt="" width="100px" height="100px">
代码演示(图片轮播):
<body>
<div id="app">
<!--
v-bind 给属性动态绑定数据
简写 :属性名
-->
<img :src="imgArr[index]" alt="" width="100px" height="100px" @mouseover.prevent="">
<p v-bind:username="username" v-bind:age="age"></p>
</div>
<script src="./js/vue3.js"></script>
<script>
//创建Vue实例
const app=Vue.createApp({
data () {
return {
username:"张三",
age:18,
//imgUrl:"./imgs/qq.png",
imgArr:["./imgs/qq.png","./imgs/wangpanpng.png","./imgs/weixin.png"]
,
index:0
}
},
methods: {
changImg(){
//箭头函数获取的是当前Vue对象
setInterval(() => {
console.log(this);
this.imgUrl=this.imgArr[this.index];
this.index++;
if(this.index>=this.imgArr.length){
this.index=0;
}
}, 1000);
},
/* changImg(){
setInterval(function (){
//匿名函数获取的对象是Window对象
console.log();
this.imgUrl=this.imgArr[this.index];
this.index++;
if(this.index>=this.imgArr.length){
this.index=0;
}
}, 1000);
}, */
},
//钩子函数 生命周期函数
mounted () {
this.changImg();
}
})
//将Vue与页面绑定
app.mount('#app')
</script>
</body>
vue配置项介绍
这里直接用代码演示Vue2和Vue3创建实例的区别
Vue2创建实例:
<body>
<!-- 使用vue开发前端页面,必须在页面给出vue所控制(管理)的区域 -->
<div id="app">
<p>{{name}}</p>
</div>
<!-- <script src="./js/vue3.js"></script> -->
<script src="./js/vue2.js"></script>
<script>
let app = new Vue({
// 配置项
el: "#app",
data: {
name: "zhangsan"}
});
// app.$mount("#app");
</script>
vue3创建实例:
let app = Vue.createApp({
// 定义vue中的所有的数据(变量):基本类型、数组、对象
data(){
return{
变量名:值,
数组名:[],
对象名:{}
}
}.
// 定义函数
methods:{
方法名:function(参数1,参数2,....){
},
// 在ES6中,可以简化对象中的方法书写
方法名(参数1,参数2,....){
}
}
});
计算属性(computed)
基本使用:
在vue实例中通过computed配置项定义相关的计算属性,格式基本上和methods中函数一致。
计算属性必须有返回值,将来在页面上,或者vue的其他配置项中去使用计算属性的结果。
计算属性有缓存, 当计算属性被的调用之后,会将返回的结果缓存起来,下载调用只要结果一致,不会执行函数体,直接返回。
完成一些数据业务逻辑处理,针对data中定义的变量数据,它们一般只能表示值,无法对值进行复杂的处理。
<body>
<div id="app">
<!-- age是vue配置项data中的一个变量 -->
<p>age:{{age}}</p>
<hr>
<!-- vue 的计算属性中一个函数 -->
<p>sum:{{sum}}</p>
<p>sum:{{sum}}</p>
<p>sum:{{sum}}</p>
<hr>
<!-- vue的methods中的一个函数 -->
<p>demo:{{ demo() }}</p>
<p>demo:{{ demo() }}</p>
<p>demo:{{ demo() }}</p>
<hr>
<p>totalPrace:{{totalPrace}}</p>
</div>
<script src="./js/vue3.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
age: 20,
a: 1,
b: 2
}
},
// 方法
methods: {
demo() {
console.log("demo....");
return this.a + this.b;
}
},
// 计算属性也是vue中的一个配置项
computed: {
// 计算属性中定义的内容与methods中书写函数格式一致
//
sum() {
console.log("==sum==");
// 书写一些逻辑
return this.a + this.b;
},
totalPrace() {
// 计算商品的总价
return 0;
}
}
});
app.mount("#app");
</script>
</body>
实现前后数据动态匹配一致:(完整写法)
<body>
<div id="app">
<p>
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
全名:{{ fullName }}
<input type="text" v-model.lazy="fullName">
</p>
</div>
<script src="./js/vue3.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
firstName: 'xiao',
lastName: 'li'
}
},
// 计算属性也是vue中的一个配置项
computed: {
fullName: {
//当计算属性被使用时,就会执行该方法
get:function(){
return this.firstName+this.lastName;
},
set:function(value){
console.log(this.value);
//把第一个字给到firstname其余的复制给lastname
this.firstName=value.substring(0,1);
this.lastName=value.substring(1)
}
}
}
});
app.mount("#app");
</script>
</body>