vue教程,超详细~
02vue的安装
程序说明
1、在body中有2个counter
,一个是id,一个是class。
2、创建应用,分别用id和class将配置对象传入
- 语法:
Vue.createApp(方法名).mount("标签");
- id:counter前面是
#
,Vue.createApp(Counter).mount("#counter");
- class:counter前面是
.
,Vue.createApp(Counter).mount(".counter");
3、vue通过2个{}获取变量
<!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>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<!-- vue语法,告诉vue,这里放了一个变量,2个{}表示变量 -->
<div id="counter">
<p>{{id}}</p>
<p>{{name}}</p>
</div>
<div class="counter">
<p>QQ</p>
<P>{{num}}</P>
</div>
<script>
const Counter = { //配置方法
data: function() {
return {
id: "公众号",
name: "小知识酷",
num: 2602629626,
}
}
}
Vue.createApp(Counter).mount("#counter"); //创建应用,将配置对象传入
Vue.createApp(Counter).mount(".counter");
</script>
</body>
</html>
代码输出
公众号
小知识酷
QQ
2602629626
03 使用vite安装项目
- 教程说明:为了文章更加简洁,教程中的所有代码进行了部分缩减,文章中的代码都是
body
中的内容。
<!-- vue语法,告诉vue,这里放了一个变量,2个{}表示变量 -->
<div id="counter">
<p>{{id}}</p>
<p>{{name}}</p>
</div>
<script>
const Counter = { //配置方法
data: function() {
return {
id: "公众号",
name: "小知识酷",
num: 2602629626,
}
}
}
app = Vue.createApp(Counter).mount("#counter"); //创建应用,将配置对象传入
console.log(app)
</script>
按F12会出现代理对象Proxy,如果你的值是省略号可以点击省略号查看具体的值
数据的双向绑定
在控制台输入app.name = "关注我,了解更多教程"
会改变网页中的值,app是应用,name是值
3.1 vite安装项目
3.1.1 查看版本号
1、按Win+R
输入cmd
2、输入npm -v
查看版本号
3.1.2 安装
1、在当前代码文件夹下的终端输入npm init vite@latest vue-begin01 -- --template vue
,vue-begin01
表示你的项目名称,同时要注意安装的路径。回车后我们会发现文件当中多了一个vue-begin01文件夹
2、cd .\vue-begin01\
进入vue-begin01项目中,npm install
进行安装
3、运行npm run dev
,点击链接
4、效果
3.1.3 观察app应用
1、在index.html
中有一个js引用
2、打开main.js
引用可以看到里面调用了app的应用
3、App.vue
里面有网页的设计
3.1.4 修改APP应用
1、index.htlm
会调用app.vue
程序,当我们在打开刚才点击的链接时会显示里面的内容
2、在app.vue
程序中我们添加自己想要的内容
3、效果图
3.2 VS Code 修改前端vue代码页面不更新问题,热更新失败(不会自动刷新)
热更新:在动态下发代码,当用户打开app时,通过网络下载升级包来直接更新,不需要发布新版本到应用市场。
问题原因:引入的路径错误
例如,正确的是import mrflysand from "./components/Mrflysand.vue";
错误引入import mrflysand from "./components/mrflysand.vue";
npm run dev
更新就没事了
注意:引用时要注意大小写
04 申明式渲染
1、在app.vue
中添加类似如图红框当中的代码
2、运行效果图
06 模板语法一
6.1 修改html网页中的值
1、在html中添加名为changeUname
的方法
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
num:18,
}
},
methods:{
// 给vue定义方法,方法名为changeUname
changeUname:function(){
//this指向vue实例
this.num = 2602629646;
},
},
}
</script>
2、在template
标签中添加button
按钮,点击效果 @click
执行的函数名为changeUname
<template>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<HelloWorld msg="Vite + Vue" />
<p>{{name}}</p>
<p>{{num}}</p>
<button @click="changeUname">点击更改数字</button>
</template>
3、点击button
按钮,会改变数字的值
6.2 添加html代码在网页中
1、添加msg:"<h1>标签1</h1>"
到msg中,并注释num
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
// num:18,
msg:"<h1>标签1</h1>"
}
},
methods:{
// 给vue定义方法
changeUname:function(){
//this指向vue实例
this.num = 2602629646;
},
},
}
</script>
2、添加 <p>{{msg}}</p>
标签
<template>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<HelloWorld msg="Vite + Vue" />
<p>{{name}}</p>
<p>{{num}}</p>
<p>{{msg}}</p>
<button @click="changeUname">点击更改数字</button>
</template>
3、运行代码,h1
标签没有正确显示,它还是一个字符串。num
网页中的p
标签并没有注释,但是并没有结果
使网页中的代码正常显示
1、双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:
<p>{{name}}</p>
<p>{{num}}</p>
<p>{{msg}}</p>
<p v-html="msg"></p>
2、代码运行的效果
模板语法二:
方法一:动态更改标签id名(点击按钮更改id名改变标签颜色)和img的url值
1、p
标签的原id名为pid;img
的src
值为url
;button
标签点击执行的函数是changeColor
。
<template>
<!-- v-bind绑定属性的内容 -->
<p v-bind:id="pid">v-dind绑定</p><!-- 动态设置id名为p1 -->
<img v-bind:src="url" alt="">
<button @click="changeColor">改变颜色</button>
</template>
2、更改后的p
标签的id名为p1
;url
值为图片网页链接。
changeColor
函数更改pid的id名为p2。
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
pid:"p1",//id名为p1
url:"https://tse2-mm.cn.bing.net/th/id/OIP-C.ayAY9cZTL2wpgG7wb_sVjQHaEM?pid=ImgDet&rs=1",
}
},
methods:{
changeColor:function(){
this.pid = "p2";
}
},
}
</script>
3、给两个id名设置不同的属性
<style scoped>
#p1{
font-size: 2em;
color: #ff0000;
background-color: aliceblue;
}
#p2{
color: blue;
}
</style>
方法二:使用javascrip表达式改变id的值
点击改变颜色2
,红色文本会改变成蓝色。
<template>
<!-- v-bind绑定属性的内容 -->
<p v-bind:id="pid">v-dind绑定</p><!-- 设置id名为p1 -->
<img v-bind:src="url" alt="">
<button @click="changeColor">改变颜色</button>
<!-- 使用javascrip表达式改变id的值 -->
<button @click="pid='p2'">改变颜色2</button>
<p>{{num}}+2</p>
<p>{{num+2}}</p>
</template>
使用js表达式使元素递增
{{num}}
中的num
是一个变量,它的初始值是1,{{num+2}}
之后,{{1+2}}
显示的值是3;{{num}}+2
表示1+2
,并且是字符串。
<template>
<p>{{num}}+2</p>
<p>{{num+2}}</p>
</template>
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
num:1,
}
},
}
</script>
使文本倒置
1、p
标签中有2个数值name、qq
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:'2602629646',
}
},
}
</script>
2、name
通过函数会倒置,qq
会正常显示
<template>
<p>{{name.split('').reverse().join('')}}<br>{{qq}}</p>
</template>
id+1
改变id名
id+1
表示p+1
为p1
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:'2602629646',
id:'p',
}
},
}
</script>
<template>
<p v-bind:id="id+1">v-bide绑定</p>
</template>
指令
v-bind
可以省略不写
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:'2602629646',
id:'p',
}
},
}
</script>
<template>
<!-- v-bind可以省略不写 -->
<p v-bind:id="id+1">v-bide绑定,p1</p>
<p :id="id+2">v-bide绑定,p2</p>
</template>
点击按钮更改id名
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:'2602629646',
pid:'p1',
}
},
methods:{
changeColor:function(){
this.pid = "p2";
}
},
}
</script>
<template>
<p :id="pid">v-bide绑定,p2</p>
<button v-on:click="changeColor">更改id名</button>
</template>
点击前
点击后
08 动态参数
8.1 动态参数
1、设置动态参数的值
export default{
data(){
return{
attributeName:'class',
pid:'p1',
}
},
}
2、设置attributeName为动态参数,[attributeName]="pid"
表示class=p1
。
<template>
<!-- attributeName表示动态参数 -->
<p v-bind:[attributeName]="pid">动态参数</p>
</template>
3、设置样式
<style scoped>
.p1{
font-size: 2em;
color: green;
}
</style>
8.2 动态属性:点击按钮将id更改为class
1、attributeName
原本的值是id
,pid=p1
。<p v-bind:[attributeName]="pid">动态参数</p>
变为<p v-bind:[id]="p1">动态参数</p>
,因此原本的颜色是红色
2、点击按钮后attributeName
的值会变成class
,class=p1
,因此点击按钮变成绿色。
<template>
<!-- attributeName表示动态参数 -->
<p v-bind:[attributeName]="pid">动态参数</p>
<!-- 点击按钮后attributeName的值会变成class -->
<button @click="attributeName='class'">更改id为class</button>
</template>
<style scoped>
#p1{
font-size: 2em;
color: #ff0000;
background-color: aliceblue;
}
.p1{
font-size: 2em;
color: green;
}
</style>
export default{
data(){
return{
name:'公众号:小知识酷',
qq:'2602629646',
attributeName:'id',
pid:'p1',
}
},
}
点击前
点击后
8.3 动态事件
8.3.1 点击按钮将id更改为class
1、mouseEvent=click
,attributeName=class
,pid=p1
<template>
<!-- attributeName表示动态参数 -->
<p v-bind:[attributeName]="pid">动态参数</p>
<button @[mouseEvent]="attributeName='class'">更改id为class</button>
</template>
export default{
data(){
return{
attributeName:'id',
pid:'p1',
mouseEvent:'click',
}
},
}
8.3.2 点击按钮改变事件
点击“更改id为class”,图片上方的红色字体会变成绿色
1、原来的mouseEvent值是click(点击事件)
export default{
data(){
return{
attributeName:'id',
pid:'p1',
mouseEvent:'click',
}
},
}
2、更改事件click为mouseover
<template>
<p :id="pid">v-bide绑定,p2</p>
<button v-on:click="changeColor">更改id名</button>
<!-- attributeName表示动态参数 -->
<p v-bind:[attributeName]="pid">动态参数</p>
<button @[mouseEvent]="attributeName='class'">更改id为class</button>
<!-- mouseover当鼠标指针位于元素上方时,改变属性 -->
<button @click="mouseEvent='mouseover'">改变事件</button>
</template>
3、点击“改变事件”,标签“更改id为class”的mouseEvent值是mouseover。当我们把鼠标接触到(不用点击)“更改id为class”按钮时,颜色就会改变成绿色。
缩写
v-bind
缩写
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!-- 动态参数的缩写 -->
<a :[key]="url"></a>
v-on
缩写
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
<!-- 动态参数的缩写 -->
<a @[event]="doSomething"></a>
09 计算属性computed
的使用以及和methods
的区别
- 计算属性
computed
在template
中的调用<p>{{reverseMsg}}</p>
,计算属性依赖于data
中的值(name)变化,当data中的值(name)没有发生变化时,就不会重新计算;当data中的值(name)发生变化时,就会执行computed中的函数。计算属性将基于他们的响应依赖关系缓存 - 方法
methods
在template
中的调用<p>{{reverseMsg()}}</p>
多了括号
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
}
},
computed:{//计算属性,只要依赖值(name)不变,那么不会重新计算,计算属性将基于他们的响应依赖关系缓存
reverseMsg:function(){
console.log("reverseMsg");
return this.name.split('').reverse().join('');
}
},
methods:{//方法属性
reverseMessage:function(){
console.log("reverseMessage");
return this.name.split('').reverse().join('');
}
}
}
</script>
<template>
<p>{{name}}</p><br>
<!-- 第一种,js表达式 -->
<p>{{name.split('').reverse().join('')}}</p>
<p>{{name.split('').reverse().join('')}}</p><br>
<!-- 第二种,使用计算属性,当我们第一次调用,就会把结果进行缓存,当我们再需要时只需要调用缓存里面的数据就行,这样就可以节省时间-->
<p>{{reverseMsg}}</p>
<p>{{reverseMsg}}</p><br>
<!-- 第三种,使用methods中的方法 -->
<p>{{reverseMessage()}}</p>
<p>{{reverseMessage()}}</p>
<button @click="name='mrflysand'">改变name</button>
</template>
1、使用计算属性,当我们第一次调用,就会把结果进行缓存,当我们再需要时只需要调用缓存里面的数据就行,这样就可以节省时间。
2、点击按钮更改后的内容:name
原本的内容是公众号:小知识酷
,当我们点击button时,name变成mrflysand
,reverseMsg
和reverseMessage()
就会执行函数,使字符串倒置。
10 计算属性的getter和setter
- 安全警告
- 在网站上动态渲染任意 HTML 是非常危险的,因为这非常容易造成 XSS 漏洞。请仅在内容安全可信时再使用 v-html,并且永远不要使用用户提供的 HTML 内容。
一个完整的计算属性的写法
- 每一个计算属性都有一个getter和setter,在设置或更改计算属性的时候调用,计算属性一般没有set方法,计算属性只是只读属性。
//每一个计算属性都有一个getter和setter
reverseMsg:{//一个完整的计算属性的写法
//在设置或者更改计算属性的时候调用,它可以有自己的一个参数,例如newValue。计算属性一般没有set方法,计算属性只是只读属性,计算属性默认只有getter,不过在需要时也可以提供一个setter
set:function(newValue){
// console.log("reverseMsg()-set")
console.log(newValue);
},
// 当我们调用reverseMsg属性的时候,就会自动执行get方法。
get:function(){
console.log("reverseMsg()-get");
return this.name.split('').reverse().join('');
}
}
简写
- 完整的计算属性的写法和简写最终的效果都是一样的
reverseMsg:function(){//简写
console.log("reverseMsg");
return this.name.split('').reverse().join('');
}
setter方法
<template>
<p>{{reverseMsg}}</p>
<button @click="reverseMsg='hello'">reverseMsg</button>
</template>
reverseMsg:{//一个完整的计算属性的写法
//在设置或者更改计算属性的时候调用,它可以有自己的一个参数,例如newValue。计算属性一般没有set方法,计算属性只是只读属性,计算属性默认只有getter,不过在需要时也可以提供一个setter
set:function(newValue){
// console.log("reverseMsg()-set")
console.log(newValue);
},
//当我们调用reverseMsg属性的时候,就会自动执行get方法。
get:function(){
console.log("reverseMsg()-get");
return this.name.split('').reverse().join('');
}
}
点击“reverseMsg”按钮,会调用reverseMsg
方法,并将hello
的值给set属性中的newValue,因此会输出hello
效果图
添加this.name = newValue;
到set中
set:function(newValue){
console.log(newValue);
`this.name = newValue;`到set中
},
点击“reverseMsg”按钮,控制台会输出hello
网页中的文本也会改变
效果图
- 完整代码
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
}
},
computed:{//计算属性,只要依赖值(name)不变,那么不会重新计算,计算属性将基于他们的响应依赖关系缓存
reverseMsg:function(){//简写
console.log("reverseMsg");
return this.name.split('').reverse().join('');
},
//每一个计算属性都有一个getter和setter
reverseMsg:{//一个完整的计算属性的写法
//在设置或者更改计算属性的时候调用,它可以有自己的一个参数,例如newValue。计算属性一般没有set方法,计算属性只是只读属性,计算属性默认只有getter,不过在需要时也可以提供一个setter
set:function(newValue){
// console.log("reverseMsg()-set")
console.log(newValue);
this.name = newValue;
},
//当我们调用reverseMsg属性的时候,就会自动执行get方法。
get:function(){
console.log("reverseMsg()-get");
return this.name.split('').reverse().join('');
}
}
},
methods:{//方法属性
reverseMessage:function(){
console.log("reverseMessage");
return this.name.split('').reverse().join('');
}
}
}
</script>
<template>
<p>{{name}}</p><br>
<!-- 第一种,js表达式 -->
<p>{{name.split('').reverse().join('')}}</p>
<p>{{name.split('').reverse().join('')}}</p><br>
<!-- 第二种,使用计算属性,当我们第一次调用,就会把结果进行缓存,当我们再需要时只需要调用缓存里面的数据就行,这样就可以节省时间-->
<p>{{reverseMsg}}</p>
<p>{{reverseMsg}}</p><br>
<!-- 第三种,使用methods中的方法 -->
<p>{{reverseMessage()}}</p>
<p>{{reverseMessage()}}</p>
<button @click="name='mrflysand'">改变name</button>
<button @click="reverseMsg='hello'">reverseMsg</button>
<button @click="reverseMessage='hello1'">reverseMessage</button>
</template>
<style scoped>
#p1{
font-size: 2em;
color: #ff0000;
background-color: aliceblue;
}
#p2{
color: blue;
}
.p1{
font-size: 2em;
color: green;
}
.p2{
font-size: 2em;
color: #ff0000;
}
</style>
11 watch侦听器的使用
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么vue通过watch
选项提供了一个更通用的方法来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch
是一个选项,watch
选项里面有一些对象或是侦听的属性,用于侦听数据的变化,当我们点击button时,name
和qq
的值就会发生改变,控制台就会输出。
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:"flysand",
}
},
methods:{
},
watch:{//侦听数据的变化
name:function(){
console.log("name");
},
qq:function(){
console.log("qq");
}
},
}
</script>
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<button @click="name='mrflysand',qq='2602629646'">改变name的值</button>
</template>
点击前
点击按钮后的效果图
数据name
发生变化时,qq
的数值也相应改变
1、在data
中原本的数据是name:'公众号:小知识酷',qq:"flysand",
2、当我们第1次点击button时,name
和qq
发生改变,watch
发现name发生改变,所以控制台输出,qq
后面会添加新的内容
3、第2次点击button时,name
并没有改变,还是“mrflysand”,qq
发生改变,watch
并发现name发生改变,所以没有执行方法。
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:"flysand",
}
},
methods:{
},
watch:{//侦听数据的变化,每当name发生变化时,就会调用这个函数
name:function(oldValue,newValue){
console.log(oldValue+","+newValue);
// 执行异步操作,或者复杂的逻辑代码,例如一个数据变化会让多个数据变化
this.qq = this.qq+",加我"
}
},
}
</script>
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<button @click="name='mrflysand',qq='2602629646'">改变name的值</button>
</template>
未点击按钮的效果图
点击1次按钮后的效果图
点击2次按钮后的效果图
12 watch对对象进行深度监听
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<button @click="name='mrflysand',qq='2602629646'">改变name的值</button>
<!-- v-model:数据的双向绑定 -->
<input type="text" v-model="name">
</template>
1、此时input
里面的值是“公众号:小知识酷”
2、当我们改变里面的数值时,网页中的数值也会发生改变
3、改变第2次时的网页
判断字符串
只有当input
输入框里面的内容是11位,才会输出“这个一个11位的字符串”
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:"flysand",
}
},
methods:{
},
watch:{//侦听数据的变化,每当name发生变化时,就会调用这个函数
name:function(oldValue,newValue){
// 执行异步操作,或者复杂的逻辑代码,例如一个数据变化会让多个数据变化
if(this.name.length == 11){
console.log("这个一个11位的字符串");
}
}
},
}
</script>
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<button @click="name='mrflysand',qq='2602629646'">改变name的值</button>
<!-- v-model:数据的双向绑定 -->
<input type="text" v-model="name">
</template>
深度监听
watch
可以侦听数据的变化,但是监听不到对象(QQ
)里面的属性变化,因此我们要使用深度监听。
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:{//qq是一个对象
QID:"FlySand",
number:"2602629646",
}
}
},
watch:{//watch侦听数据的变化,监听不到对象里面的属性变化,控制台并没有输出值
qq:function(newValue){
console.log(newValue);
}
},
}
</script>
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<p>{{qq.QID}}</p>
<button @click="qq.QID='QQ搜索FlySand'">改变名字</button>
</template>
点击“改变名字”后
-
deep
表示是否深度监听,他有一个参数true
或false
。 -
watch
侦听数据的变化,监听不到对象里面的属性变化,因此我们要使用深度监听deep
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
qq:{//qq是一个对象
QID:"FlySand",
number:"2602629646",
}
}
},
watch:{//watch侦听数据的变化,监听不到对象里面的属性变化,因此我们要使用深度监听deep,
"qq.QID":{//使用字符串的形式进行优化,只会单独监听对象中对应的属性
handler:function(newValue){
console.log(newValue);
},
deep:true,//表示是否深度监听,监听器会一层层的向下遍历,给对象每个属性都加上侦听器
}
},
}
</script>
<template>
<div>
<p>{{name}}</p>
<p>{{qq}}</p>
</div>
<p>{{qq.QID}}</p>
<button @click="qq.QID='QQ搜索FlySand'">改变名字</button>
</template>
代码说明: 点击按钮“改变名字”,qq.QID='QQ搜索FlySand'
发生改变,watch
监听到数值的变化,所以控制台就会输出qq
的值
效果图
13 class类名的对象使用方式
放置对象 :class="{类名:boolean类型}"
。
如下代码,当boolean
的值是true
时class才会正常显示;当boolean
的值是false
时class不会正常显示。
<template>
<div>
<!-- 第一种:普通模式,放置字符串 -->
<div class="active">公众号:小知识酷</div>
<!-- 第二种:放置对象 :class="{类名:boolean类型}" -->
<p :class="{active:true}">qq:2602629646</p>
<p :class="{active:false}">baidu:mrflysand</p>
</div>
</template>
<style scoped>
.active{
color: red;
}
</style>
13.1 设置变量
设置变量:class="{active:isActive}"
、isActive:false
,及:class="{active:false}"
<script>
// 声明式渲染,可以提高开发效率
export default{
data(){
return{
name:'公众号:小知识酷',
isActive:false,
}
},
}
</script>
<template>
<!-- 第二种:放置对象 :class="{类名:boolean类型}" -->
<p :class="{active:isActive}">qq:2602629646</p>
</div>
</template>
效果图isActive:false
效果图isActive:true
13.2 点击按钮将true
改变成false
- 代码说明:
isActive
的初始值是true
,当我们点击button时,isActive
会变成false
export default{
data(){
return{
name:'公众号:小知识酷',
isActive:true,
}
},
}
<template>
<div>
<p :class="{active:isActive}">qq:2602629646</p>
<button @click="isActive=false">改变isActive为false</button>
</div>
</template>
13.3 点击按钮切换颜色
当isActive=true
时,!true
的值变为false
,因此isActive=false
<button @click="isActive=!isActive">切换颜色</button>
13.4 class
设置多个类名
格式:class="{类名1:布尔值,类名2:布尔值}"
,例如:class="{active:isActive,qq:isActive}"
<template>
<div>
<p :class="{active:isActive,qq:isActive}">qq:2602629646</p>
<button @click="isActive=!isActive">切换</button>
</div>
</template>
<style scoped>
.active{
color: blue;
}
.qq{
background-color: #ff000035;
}
</style>
13.5 设置2个class
设置2个class
,在网页中同样有效,和普通的类同时存在,不会冲突
<p :class="{active:isActive,qq:isActive}" class="qqNum">qq:2602629646</p>
<style scoped>
.active{
color: blue;
}
.qq{
background-color: #ff000035;
}
.qqNum{
font-size: 2em;
}
</style>
13.6 设置多个class类名
1、<p :class=classObj>qq:2602629646</p>
定义class为classObj
2、 classObj:{active:true,qq:true,qqNum:true}
定义的对象
<script>
export default{
data(){
return{
name:'公众号:小知识酷',
isActive:true,
classObj:{
active:true,
qq:true,
qqNum:true,
}
}
},
}
</script>
<template>
<div>
<p :class=classObj>qq:2602629646</p>
</div>
</template>
13.7 使用computed
<script>
export default{
data(){
return{
name:'公众号:小知识酷',
isActive:true,
error:null,
classObj:{
active:true,
qq:true,
qqNum:true,
}
}
},
computed:{
classObj:function(){
console.log(this.isActive+","+!this.error);
return{
active:this.isActive && !this.error,
qq:this.error,
}
}
}
}
</script>
<template>
<div>
<!-- 使用computed -->
<p :class=classObj>公众号:小知识酷</p>
</div>
</template>
<style scoped>
.active{
color: blue;
}
.qq{
background-color: #ff000035;
}
</style>
1、this.isActive=true
、!this.error = !null = true
(error
的值是true
)
2、上面的2个内容都是true,true = true && true
3、active:true
所以class会正常显示
4、qq:this.error
为qq:false=qq:null
,因此网页中没有class:qq
这个属性
修改属性值
将error:null
修改为error:10
data(){
return{
name:'公众号:小知识酷',
isActive:true,
error:10,
classObj:{
active:true,
qq:true,
qqNum:true,
}
}
},
15 style样式的多种操作方式
绑定内联样式
代码格式::style="{属性名1:属性值,属性名2:属性值,属性名3:属性值}"
注意:在书写css样式时font-size
要写成fontSize
,中间的横杠要去掉,首字母换成大写(驼峰命名法)。
<script>
export default{
data(){
return{
activeColor:'blue',
fontSize:36,
}
},
}
</script>
<template>
<div>
<!-- 第一种:放置字符串 -->
<p style="color:red;">公众号:小知识酷</p>
<!-- 第二种:放置对象 -->
<p :style="{color:activeColor,fontSize:fontSize+'px'}">qq:2444099018</p>
</div>
</template>
效果图
直接绑定到一个对象通常会更好,这会让模板更清楚:
<script>
export default{
data(){
return{
styleObject:{
color:'blue',
fontSize:'2em',
},
}
},
}
</script>
<template>
<div>
<!-- 第一种:放置字符串 -->
<p style="color:red;">公众号:小知识酷</p>
<!-- 第二种:放置对象 -->
<p :style="styleObject">qq:2444099018</p>
</div>
</template>
数组语法
:style="[样式对象,{属性名1:'属性值',属性名2:'属性值',}
,:style="[styleObject,{border:'5px solid blue',background:'#00ff00'
<script>
export default{
data(){
return{
styleObject:{
color:'red',
fontSize:'2em',
},
}
},
}
</script>
<template>
<div>
<!-- 第三种:数组模式 -->
<p :style="[styleObject,{border:'5px solid blue',background:'#00ff00'}]">公众号:小知识酷</p>
</div>
</template>
效果图
16 条件渲染
v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true
(真)值时才被渲染。
<template>
<div>
<p v-if="true">微信公众号:小知识酷</p>
<p v-if="false">QQ:2444099018</p>
</div>
</template>
效果图
判断年龄
<script>
export default{
data(){
return{
age:17,
}
},
}
</script>
<template>
<div>
<p v-if="age>=18">我是成年人了</p>
<p v-if="age<18">这是未成年人</p>
</div>
</template>
效果图
v-else
当v-if
条件不满足时就会执行v-else
<script>
export default{
data(){
return{
age:17,
}
},
}
</script>
<template>
<div>
<p v-if="age>=18">我是成年人了</p>
<p v-else>这是未成年人</p>
</div>
</template>
效果图
v-else-if
<script>
export default{
data(){
return{
age:17,
}
},
}
</script>
<template>
<div>
<p v-if="age>18">我是成年人了</p>
<p v-else-if="ege==18">我刚好18岁</p>
<p v-else>他还是未成年人</p>
</div>
</template>
效果图
17 条件渲染-v-show
以及和v-if的区别
因为 v-if
是一个指令,他必须依附于某个元素。但如果我们想要切换不止一个元素呢?
在这种情况下我们可以在一个 <template>
元素上使用 v-if
,这只是一个不可见的包装器元素,最后渲染的结果并不会包含这个 <template>
元素。
在template
或div
元素上使用v-if条件渲染分组
<template>
<div>
<p v-if="age>18">我是成年人了</p>
<p v-else-if="ege==18">我刚好18岁</p>
<p v-else>他还是未成年人</p>
</div>
<template v-if="age<18">
<p>微信公众号:小知识酷</p>
<p>微信公众号:小知识酷</p>
<p>微信公众号:小知识酷</p>
</template>
</template>
效果图
<script>
export default{
data(){
return{
age:17,
sex:"man",
isShow:true,
}
},
}
</script>
<template>
<p v-if="isShow">微信公众号1:小知识酷</p>
<p v-show="!isShow">微信公众号2:小知识酷</p>
</template>
效果图
点击按钮切换数值
v-if
只要后面为false,对应的元素以及子元素都不会被渲染出来,控制DOM元素的创建和销毁,运行时条件很少改变,或者说是一次性的渲染。
v-show
只是简单地切换元素的display
属性,带有v-show
的元素始终会被渲染并保留在DOM中,频繁切换状态。
<template>
<p v-if="isShow">微信公众号1:小知识酷</p>
<p v-show="!isShow">微信公众号2:小知识酷</p>
<button @click="isShow=!isShow">改变 isShow</button>
</template>
18 列表渲染v-for
<li v-for="item in person" :key="item">{{item}}</li>
相当于item
是person
里面的值
<script>
export default{
data(){
return{
person:["飞沙","mrflysand","公众号:小知识酷"],
}
},
}
</script>
<template>
<div>
<ul>
<li v-for="item in person" :key="item">{{item}}</li>
</ul>
</div>
</template>
效果图
v-for
第二个参数index
索引
v-for
还支持一个可选项的第二个参数,即当前项的index
索引。
v-for
使用数组,item
代表数组中每一个元素,index
表示数组元素的下标
<script>
export default{
data(){
return{
person:["飞沙","mrflysand","公众号:小知识酷"],
styleObj:{
textAlign:"left",
color:"red",
},
}
},
}
</script>
<template>
<div>
<ul>
<li v-for="(item,index) in person" :key="index" :style="styleObj">{{index+1}}-{{item}} </li>
</ul>
</div>
</template>
我们也可以使用of
替代in
作为分隔符,因为它更接近JavaScript迭代器的语法:
<li v-for="(item,index) of person" :key="index" :style="styleObj">{{index+1}}-{{item}} </li>
在v-for
里使用对象
<script>
export default{
data(){
return{
person:["飞沙","mrflysand","公众号:小知识酷"],
personObj:{
publicAccount:"小知识酷",
qq:"2444099018",
qid:"flysand",
},
styleObj:{
textAlign:"left",
color:"red",
},
}
},
}
</script>
<template>
<div>
<ul>
<li v-for="(item,key) of personObj" :style="styleObj">{{key}}:{{item}} </li>
</ul>
</div>
</template>
效果图
v-for
对象中的第三个参数index
索引
代码格式:v-for="(键,值,索引) of 对象"
,v-for="(item,key,index) of personObj"
<li v-for="(item,key,index) of personObj" :style="styleObj">{{index+1}}-{{key}}:{{item}} </li>
效果图
调换顺序
无论代码单词如何,for对象里面的参数都会按照顺序进行赋值
<li v-for="(item,index,key) of personObj" :style="styleObj">{{key+1}}-{{index}}:{{item}} </li>
效果图
19 v-for
为什么要加key
为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素
key
是唯一的标识
unshift
会在数组元素的前面添加一个数值
<script>
export default{
data(){
return{
person:["飞沙","flysand","公众号:小知识酷"],
personObj:{
publicAccount:"小知识酷",
qq:"2444099018",
qid:"flysand",
},
styleObj:{
textAlign:"left",
color:"red",
},
}
},
methods:{
addPerson:function(){
// unshift会在数组元素的前面添加一个数值
this.person.unshift("mrflysand");
console.log(this.person);
}
},
}
</script>
<template>
<div>
<ul>
<li v-for="(item,index) of person" :style="styleObj"><input type="checkbox">{{index}}{{item}}</li>
</ul>
<button @click="addPerson">增加</button>
</div>
</template>
效果图
点击“添加”后的效果图
20 数组更新检测
- 数组发生改变,视图里面的内容也会发生更新
<script>
export default{
data(){
return{
list:[1,5,3,8,6],
}
},
methods:{
changeList:function(){
console.log(this.list.length)
this.list[this.list.length]=10; //将数字10添加到数组中
console.log(this.list.length)
}
},
}
</script>
<template>
<div>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
<button @click="changeList">改变数组</button>
</div>
</template>
效果图
点击按钮后的效果图
使用方法改变数组
push(value1,value2,value99)
给数组末尾添加元素,里面的内容可以是一个或多个。
pop ()
删除数组最末尾的最后一个元素,里面没有参数
shift()
对数组的第一位进行删除
unshift()
给数组的首位添加元素,可以有多个数值,如unshift(99,100,101)
splice()
删除元素、插入元素、替换元素
sort()
给数组从小到大排序
reverse()
使数组中的内容反向,无参数
push(value1,value2,value99)
给数组末尾添加元素,里面的内容可以是一个或多个。
<script>
export default{
data(){
return{
list:[1,5,3,8,6],
}
},
methods:{
changeList:function(){
this.list.push(10,12,11);
}
},
}
</script>
点击按钮后的效果图
unshift()
给数组的首位添加元素,可以有多个数值
this.list.unshift(100,120,110);
添加多个数组元素
点击按钮后的效果图
splice()
删除元素、插入元素、替换元素
删除元素
1、参数1(必填):表示开始插入或开始删除的元素的位置下标
2、参数2(可选):要删除几个元素,如果没有传入就删除后面所有的元素
- 举例:
splice(2)
删除从下标2开始以后的参数
插入元素
1、参数1:位置下标
2、参数2:传入0,表示没有元素要删除
3、参数3:要插入的元素,可以多个参数
this.list.splice(1,0,100,111,222)
效果图
替换元素
1、参数1:位置下标
2、参数2:要替换的元素个数
3、参数3:被替换后的参数
this.list.splice(1,3,100,111,222)
效果图
22 事件处理
<script>
export default{
data(){
return{
num:0,
};
},
methods:{
addCounter(number){
this.num+=number;
}
},
};
</script>
<template>
<div>
<!-- 绑定事件,直接通过js代码处理 -->
<h2 @click=num++>{{num}}</h2>
<!-- 绑定事件,使用函数 -->
<h2 @click=addCounter>{{num}}</h2>
<!-- 绑定事件,传递参数 -->
<h2 @click=addCounter(5)>{{num}}</h2>
</div>
</template>
效果图:当我们点击按钮时就会使3个数字(响应式)自动+1;当我们点击第三个数字时会使数字自动加5。
函数参数
<script>
export default{
data(){
return{
num:0,
};
},
methods:{
addCounter(number){
this.num++;
console.log(number)
}
},
};
</script>
<template>
<div>
<!-- 绑定事件,直接通过js代码处理 -->
<h2 @click=num++>{{num}}</h2>
<!-- 绑定事件,使用函数 -->
<h2 @click=addCounter>{{num}}</h2>
<!-- 绑定事件,传递参数 -->
<h2 @click=addCounter(5)>{{num}}</h2>
</div>
</template>
效果图:分别点击3个数字时的输出内容
绑定参数,既传递参数,也要有事件对象
<h2 @click="addCounter(5,$event)">{{num}}</h2>
methods:{
addCounter(number,event){
this.num++;
console.log(number,event)
}
},
效果图:当我们点击最后一个数字时,会输出数字5和对象。
绑定多个事件,事件之间用逗号分开
<h2 @click="addCounter(5,$event),addAge()">num:{{num}}<br>age:{{age}}</h2>
<script>
export default{
data(){
return{
num:0,
age:18,
};
},
methods:{
addCounter(num){
this.num+=num;
},
addAge(){
this.age++;
},
},
};
</script>
点击1次最后一个区域的效果图
23 事件修饰符
<script>
export default{
methods:{
changeList:function(){
// list1 = [100,111,222];
this.list.sort()
},
divClick:function(){
console.log("父元素的展示");
},
btnClick:function(){
console.log("子元素的展示");
}
},
}
</script>
<template>
<div>
<!-- .stop 阻止事件冒泡 -->
<div @click="divClick">
<button @click="btnClick">按钮</button>
</div>
</div>
</template>
当我们点击按钮时,首先会输出子元素,然后再输出父元素,目标元素执行完毕后就会执行父元素,如果父元素有事件就会执行函数。
点击按钮后的效果图
.stop
阻止事件冒泡
当我们给click
添加stop
时,父元素就不会执行,<button @click.stop="btnClick">按钮</button>
.once
只触发一次回调
当我们点击button
时只会进行一次回调,<button @click.once="btnClick">按钮</button>
点击2次后的效果图
<template>
<div>
<!-- .stop 阻止事件冒泡 -->
<div @click="divClick">
<button @click.once="btnClick">按钮</button>
</div>
<button @click.once="onceClick">只触发一次once</button>
</div>
</template>
当我们点击第2个按钮时,只有第一次是有效的,后面是无效的。
按键修饰符
.{keyCode(键盘编码) | keyAilas(键盘的简写)}
监听键盘的某个键帽
.{keyCode(键盘编码)}
.{keyAilas(键盘的简写)}
@keyup
当我们一起按着键盘时,控制台不会输出;当我们松开键盘时,控制台就会输出文本
<script>
export default{
methods:{
keyup:function(){
console.log("键盘被按松开")
},
},
}
</script>
<template>
<div>
<!-- .{keyCode(键盘编码) | keyAilas(键盘的简写)} 监听键盘的某个键帽 -->
<input type="text" @keyup="keyup">
</div>
</template>
松开enter
执行函数
keyup:function(){
console.log("你松开了enter,数据被提交")
},
<input type="text" @keyup.enter="keyup">
按键别名
.enter
.tab
.delete (捕获“Delete”和“Backspace”两个按键)
.esc
.space
.up
.down
.left
.right
系统按键修饰符#
你可以使用以下系统按键修饰符来触发鼠标或键盘事件监听器,只有当按键被按下时才会触发。
.ctrl
.alt
.shift
.meta
24 表单输入绑定v-model
的原理
v-model
的原理,本质是2个操作:
1、v-bind绑定一个value属性
2、v-on给当前元素添加一个input事件
当我们在输入框内输入内容时p
标签里面的内容也会随时更新
<script>
export default{
data(){
return{
text:"10",
};
},
}
</script>
<template>
<div>
<input type="text" v-model="text">
<p>text:{{text}}</p>
</div>
</template>
25 v-model
表单控件的基本使用
1、复选框
1.1 复选框-单个勾选
语法:v-model
布尔值true
或false
代码说明:
1、checked的默认值是null
2、当我们勾选时checked:true
3、取消勾选checked:false
<input type="checkbox" v-model="checked">
<h2>{{checked}}</h2>
data(){
return{
text:"10",
checked:"",
};
},
效果图
勾选
取消勾选
1.2 复选框-多个勾选
语法:v-model
值为数组
当我们勾选input时,就会给fruits添加内容
<input type="checkbox" v-model="fruits" value="苹果">苹果
<input type="checkbox" v-model="fruits" value="梨子">梨子
<input type="checkbox" v-model="fruits" value="荔枝">荔枝
<h2>喜欢的水果:{{fruits}}</h2>
data(){
return{
text:"10",
checked:"",
fruits:[],
};
},
效果图
当我们勾选时,就会给fruits添加内容
2、选项框
2.1 选项框-单选
city
的默认值是武汉,当我们点击其他地址是city
就会发生改变
data(){
return{
text:"10",
checked:"",
fruits:[],
sex:"男",
city:"武汉",
citys:[],
};
},
<select name="" id="" v-model="city">
<option value="武汉">武汉</option>
<option value="重庆">重庆</option>
<option value="上海">上海</option>
</select>
<div>地址:{{city}}</div>
2.2 选项框-多选
multiple
表示是多选框,同是数值citys是数组类型
data(){
return{
text:"10",
checked:"",
fruits:[],
sex:"男",
city:"武汉",
citys:[],
};
},
<select name="" id="" v-model="citys" multiple>
<option value="长沙">长沙</option>
<option value="武汉">武汉</option>
<option value="重庆">重庆</option>
<option value="上海">上海</option>
</select>
<div>地址2:{{citys}}</div>
按住ctrl
同时点击地址就会多选
26 v-model
修饰符的使用
组件: 组件是带有名称可复用的实例
26.1 .lazy
.lazy
当输入框失去焦点,再去同步输入框里面的数据,当我们在文本框输入时数据不会发生改变.number
将输入框的内容自动转为数字类型,当我们在文本框输入时数据会及时更新.trim
自动过滤用户输入的首尾空白字符
data(){
return{
counter:0,
msg:"mrflysand",
};
},
<input type="text" v-model.lazy="msg">
<h2>{{msg}}</h2>
<input type="text" v-model.number="counter">
<h2>{{typeof counter}},{{counter}}</h2>
<input type="text" v-model.trim="msg" @keydown="downmsg">
<h2>{{msg}}</h2>
当我们在第三个输入框输入内容时,下面的内容不会改变
27 vue组件化开发
当我们打开一个见面时,我们能看到很多内容,里面由大盒子套小盒子组成。如果在一个文件中写出所有的元素,网页在加载的时候就会出现卡顿。
28 vue组件的基本使用
App.vue
是根组件,components
是组件文件夹
嵌套多个组件,MrFlySand.vue
会在Content.vue
中显示,Content.vue
会在APP.vue
中显示。
28.1 导入其它组件
1、在components
组件文件夹中创建Content.vue
<template>
<div>
<h2>微信公众号【小知识酷】,关注获取更多</h2>
<h2>我是组件content组件内容</h2>
</div>
</template>
2、在App.vue
引入Content.vue
- 2.1
import 组件名 from './组件文件夹名称/组件名'
,如import Content from './components/content.vue'
- 2.2
components:{Content}
- 2.3
<div><Content></Content></div>
<script setup>
import { buildDirectiveArgs } from '@vue/compiler-core';
import HelloWorld from './components/HelloWorld.vue'
import Content from './components/content.vue'
</script>
<script>
export default{
data(){
return{
};
},
components:{
Content
}
}
</script>
<template>
<div>
<Content></Content>
</div>
</template>
效果图
28.2 在App.vue
中导入多个组件
1、创建一个MrFlySand.vue
文件
<template>
<div>
<h2>QID:flysand</h2>
</div>
</template>
2、在App.vue
中导入MrFlySand.vue
3、效果图
28.3 在content.vue
中导入组件
1、创建MrFlySand.vue
文件
2、在Content
文件中导入MrFlySand.vue
文件
<script>
import MrFlySand from './mrflysand.vue'
export default{
data(){
return{
};
},
components:{
MrFlySand
}
}
</script>
<template>
<div>
<MrFlySand></MrFlySand>
<h2>微信公众号【小知识酷】,关注获取更多</h2>
<h2>我是组件content组件内容</h2>
<MrFlySand></MrFlySand>
</div>
</template>
3、在终端输入npm run dev
重新运行
注意:当我们在网页中修改后,再按F5刷新不会更新网页
29 父组件和子组件
通过prop向子组件传递数据
组件是带有名称的可复用的实例,单独功能的模式的封装。
30 组件数据的存放
在调用子组件时,Content
组件是互不干扰,相互独立的。
当我们点击button
按钮时,按钮上方的h2
会发生改变,另一个Contnet
组件中的不会改变。