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组件中的不会改变。


浙公网安备 33010602011771号