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 vuevue-begin01表示你的项目名称,同时要注意安装的路径。回车后我们会发现文件当中多了一个vue-begin01文件夹

2、cd .\vue-begin01\进入vue-begin01项目中,npm install进行安装

3、运行npm run dev,点击链接

4、效果

3.1.3 观察app应用

1、在index.html中有一个js引用
image

2、打开main.js引用可以看到里面调用了app的应用
image

3、App.vue里面有网页的设计
image

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中添加类似如图红框当中的代码
image

2、运行效果图
image

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按钮,会改变数字的值
image
image

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标签并没有注释,但是并没有结果
image

使网页中的代码正常显示

1、双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:

<p>{{name}}</p>
<p>{{num}}</p>
<p>{{msg}}</p>
<p v-html="msg"></p>

2、代码运行的效果
image

模板语法二:

方法一:动态更改标签id名(点击按钮更改id名改变标签颜色)和img的url值

1、p标签的原id名为pid;imgsrc值为urlbutton标签点击执行的函数是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名为p1url值为图片网页链接。

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,红色文本会改变成蓝色。
image

<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>

image

使文本倒置

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+1p1

<script>
// 声明式渲染,可以提高开发效率
export default{
  data(){
    return{
      name:'公众号:小知识酷',
      qq:'2602629646',
      id:'p',
    }
  },
}
</script>
<template>
  <p v-bind:id="id+1">v-bide绑定</p>
</template>

image

指令

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>

image

点击按钮更改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>

image

点击前

image

点击后

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>

image

8.2 动态属性:点击按钮将id更改为class

1、attributeName原本的值是idpid=p1<p v-bind:[attributeName]="pid">动态参数</p>变为<p v-bind:[id]="p1">动态参数</p>,因此原本的颜色是红色
2、点击按钮后attributeName的值会变成classclass=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',
    }
  },
}

image

点击前

image

点击后

8.3 动态事件

8.3.1 点击按钮将id更改为class

1、mouseEvent=clickattributeName=classpid=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”,图片上方的红色字体会变成绿色
image

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”按钮时,颜色就会改变成绿色。
image

缩写

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的区别

  1. 计算属性computedtemplate中的调用<p>{{reverseMsg}}</p>,计算属性依赖于data中的值(name)变化,当data中的值(name)没有发生变化时,就不会重新计算;当data中的值(name)发生变化时,就会执行computed中的函数。计算属性将基于他们的响应依赖关系缓存
  2. 方法methodstemplate中的调用<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、使用计算属性,当我们第一次调用,就会把结果进行缓存,当我们再需要时只需要调用缓存里面的数据就行,这样就可以节省时间。
image

2、点击按钮更改后的内容:name原本的内容是公众号:小知识酷,当我们点击button时,name变成mrflysandreverseMsgreverseMessage()就会执行函数,使字符串倒置。
image

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
image

效果图

添加this.name = newValue;到set中

set:function(newValue){
   console.log(newValue);
   `this.name = newValue;`到set中
},

点击“reverseMsg”按钮,控制台会输出hello网页中的文本也会改变
image

效果图

  • 完整代码
<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时,nameqq的值就会发生改变,控制台就会输出。

<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>

image

点击前

image

点击按钮后的效果图

数据name发生变化时,qq的数值也相应改变

1、在data中原本的数据是name:'公众号:小知识酷',qq:"flysand",
2、当我们第1次点击button时,nameqq发生改变,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>

image

未点击按钮的效果图

image

点击1次按钮后的效果图

image

点击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里面的值是“公众号:小知识酷”
image

2、当我们改变里面的数值时,网页中的数值也会发生改变
image

3、改变第2次时的网页
image

判断字符串

只有当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>

image

image

点击“改变名字”后

  • deep表示是否深度监听,他有一个参数truefalse

  • 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的值
image

效果图

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>

image

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>

image

效果图isActive:false

image

效果图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>

image

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 = trueerror的值是true
2、上面的2个内容都是true,true = true && true
3、active:true所以class会正常显示
4、qq:this.errorqq:false=qq:null,因此网页中没有class:qq这个属性
image

修改属性值

error:null修改为error:10

data(){
  return{
    name:'公众号:小知识酷',
    isActive:true,
    error:10,
    classObj:{
      active:true,
      qq:true,
      qqNum:true,
    }
  }
},

image

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>

image

效果图

17 条件渲染-v-show以及和v-if的区别

因为 v-if 是一个指令,他必须依附于某个元素。但如果我们想要切换不止一个元素呢?

在这种情况下我们可以在一个 <template> 元素上使用 v-if,这只是一个不可见的包装器元素,最后渲染的结果并不会包含这个 <template> 元素。

templatediv元素上使用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>

image

效果图

<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>

image

效果图

点击按钮切换数值

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>

image
image

18 列表渲染v-for

<li v-for="item in person" :key="item">{{item}}</li>相当于itemperson里面的值

<script>
export default{
  data(){
    return{
      person:["飞沙","mrflysand","公众号:小知识酷"],
    }
  },
}
</script>
<template>
  <div>
    <ul>
      <li v-for="item in person" :key="item">{{item}}</li>
    </ul>
  </div>
</template>

image

效果图

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>

image

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>

image

效果图

调换顺序

无论代码单词如何,for对象里面的参数都会按照顺序进行赋值

<li v-for="(item,index,key) of personObj" :style="styleObj">{{key+1}}-{{index}}:{{item}} </li>

image

效果图

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>

image

效果图

image

点击“添加”后的效果图

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);添加多个数组元素
image

点击按钮后的效果图

点击按钮后的效果图

splice()删除元素、插入元素、替换元素
删除元素

1、参数1(必填):表示开始插入或开始删除的元素的位置下标
2、参数2(可选):要删除几个元素,如果没有传入就删除后面所有的元素

  • 举例:splice(2)删除从下标2开始以后的参数
插入元素

1、参数1:位置下标
2、参数2:传入0,表示没有元素要删除
3、参数3:要插入的元素,可以多个参数

  • this.list.splice(1,0,100,111,222)效果图
    image
替换元素

1、参数1:位置下标
2、参数2:要替换的元素个数
3、参数3:被替换后的参数

  • this.list.splice(1,3,100,111,222)效果图
    image

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。
image

函数参数
<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个数字时的输出内容
image

绑定参数,既传递参数,也要有事件对象

<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>

image

image

点击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>

当我们点击按钮时,首先会输出子元素,然后再输出父元素,目标元素执行完毕后就会执行父元素,如果父元素有事件就会执行函数。
image

点击按钮后的效果图

.stop阻止事件冒泡

当我们给click添加stop时,父元素就不会执行,<button @click.stop="btnClick">按钮</button>
image

.once只触发一次回调

当我们点击button时只会进行一次回调,<button @click.once="btnClick">按钮</button>
image

点击2次后的效果图

<template>
  <div>
    <!-- .stop 阻止事件冒泡 -->
    <div @click="divClick">
      <button @click.once="btnClick">按钮</button>
    </div>
    <button @click.once="onceClick">只触发一次once</button>
  </div>
</template>

当我们点击第2个按钮时,只有第一次是有效的,后面是无效的。
image

按键修饰符

.{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>

image

松开enter执行函数

keyup:function(){
	console.log("你松开了enter,数据被提交")
},
<input type="text" @keyup.enter="keyup">

image

按键别名
.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>

image

25 v-model表单控件的基本使用

1、复选框

1.1 复选框-单个勾选

语法v-model布尔值truefalse
代码说明
1、checked的默认值是null
2、当我们勾选时checked:true
3、取消勾选checked:false

<input type="checkbox" v-model="checked">
<h2>{{checked}}</h2>
data(){
  return{
    text:"10",
    checked:"",
  };
},

image

效果图

image

勾选

image

取消勾选

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:[],
  };
},

image

效果图

image

当我们勾选时,就会给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>

image

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同时点击地址就会多选
image

26 v-model修饰符的使用

组件: 组件是带有名称可复用的实例

26.1 .lazy

  1. .lazy当输入框失去焦点,再去同步输入框里面的数据,当我们在文本框输入时数据不会发生改变
  2. .number将输入框的内容自动转为数字类型,当我们在文本框输入时数据会及时更新
  3. .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>

image

当我们在第三个输入框输入内容时,下面的内容不会改变
image

27 vue组件化开发

当我们打开一个见面时,我们能看到很多内容,里面由大盒子套小盒子组成。如果在一个文件中写出所有的元素,网页在加载的时候就会出现卡顿。
image

28 vue组件的基本使用

App.vue是根组件,components是组件文件夹
image

嵌套多个组件,MrFlySand.vue会在Content.vue中显示,Content.vue会在APP.vue中显示。
image

28.1 导入其它组件

1、在components组件文件夹中创建Content.vue

<template>
  <div>
    <h2>微信公众号【小知识酷】,关注获取更多</h2>
    <h2>我是组件content组件内容</h2>
  </div>
</template>

image

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>

image

2、在App.vue中导入MrFlySand.vue
image

3、效果图
image

28.3 在content.vue中导入组件

1、创建MrFlySand.vue文件
image

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刷新不会更新网页
image

29 父组件和子组件

通过prop向子组件传递数据

组件是带有名称的可复用的实例,单独功能的模式的封装。

30 组件数据的存放

在调用子组件时,Content组件是互不干扰,相互独立的。
image

当我们点击button按钮时,按钮上方的h2会发生改变,另一个Contnet组件中的不会改变。
image

31 父传子通过prop传值

posted @ 2022-11-24 10:20  MrFlySand-飞沙  阅读(860)  评论(0编辑  收藏  举报