Vue3从入门到精通

一、Vue3简介

1.Vue是什么

Vue是一套用于构建用户界面的渐进式的JavaScript框架。所谓渐进式就是可以自底向上逐层的应用。

2.Vue的特点

1.采用组件化 模式,提高代码复用率 、且让代码更好维护

2.声明式 编码,让编码人员无需直接操作DOM,提高开发效率。

3.使用虚拟DOM+优秀的Diff 算法,尽量复用DOM节点,。

3.Vue的API风格

Vue的组件可以按两种不同的风格书写:选项式API( 可以理解成Vue2版本)和组合式API (可以理解成Vue3版本)

大部分的核心概念在这两种风格之间都是通用的。熟悉了一种风格以后,你也能够很快地理解另一种风格。

选项式API(Options API)

使用选项式API,我们可以用包含多个选项的对象来描述组件的逻辑,例如datamethodsmounted 。选项所定义的属性都会暴露在函数内部的this上,它会指向当前的组件实例。

javascript 复制代码
<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

组合式API(CompositionAPl)

通过组合式API,我们可以使用导入的API函数来描述组件逻辑。

javascript 复制代码
<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}

onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

4.Vue开发前的准备

构建工具 让我们能使用Vue单文件组件(SFC)。Vue官方的构建流程是基于Vite的,一个现代、轻量、极速的构建工具

创建Vue项目

bash 复制代码
npm init vue@latest

这一指令将会安装并执行create-vue,它是Vue官方的项目脚手架工具。你将会看到一些诸如TypeScript和测试支持之类的可选功能提示。

注意项目名字不要存在字母大写!

之后我们cd 到项目目录,执行

bash 复制代码
#安装依赖
npm install

#运行项目
npm run dev

当看到下面的信息,证明项目运行成功了

我们复制链接到浏览器打开,网页内容如下

5.Vue项目目录结构

二、Vue语法

1.模版语法

Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析。

文本插值

最基本的数据绑定形式是文本插值,它使用的是"Mustache"语法(即双大括号):

javascript 复制代码
<template>
    <p>{{msg}}</p>
</template>
<script>
export default{
    data(){
        return{
            msg:"神奇的魔法"
        }
    }
}
</script>

使用JavaScript表达式

每个绑定仅支持单一表达式 ,也就是一段能够被求值的JavaScript代码。一个简单的判断方法是是否可以合法地写在returm后面

javascript 复制代码
<template>
    <h3>模版语法</h3>
    <p>{{msg}}</p>
    <p>{{number+1}}</p>
    <p>{{ok ? 'yes':'no'}}</p>
    <p>{{message.split('').reverse().join('')}}</p>
</template>
<script>
export default{
    data(){
        return{
            msg:"神奇的魔法",
            number:10,
            ok:true,
            message:"神奇的魔法"
        }
    }
}
</script>

无效

html 复制代码
<!-- 这是一个语句,而非表达式 -->
{{var a = 1}}



<!-- 条件控制也不支持,请使用三元表达式 -->
{{if (ok) { retrun message }}}

原始HTML

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

javascript 复制代码
<template>
    <h3>模版语法</h3>
    <p>{{msg}}</p>
    <p>{{number+1}}</p>
    <p>{{ok ? 'yes':'no'}}</p>
    <p>{{message.split('').reverse().join('')}}</p>
    <p v-html="rawHtml"></p>
</template>
<script>
export default{
    data(){
        return{
            msg:"神奇的魔法",
            number:10,
            ok:true,
            message:"神奇的魔法",
            rawHtml:'<a href="https://www.baidu.com">神奇的链接</a>'
        }
    }
}
</script>

2.属性绑定

双大括号不能在HTMLattributes中使用。想要响应式地绑定一个attribute,应该使用v-bind指令

javascript 复制代码
<template>
  <div v-bind:id="id" v-bind:class="msg">测试</div>
</template>
<script>

export default {
  data() {
    return {
      msg: 'active',
      id:"customid"
    }
  }
}

</script>

v-bind 指令指示Vue将元素的id attribute与组件的dynamicld属性保持一致。如果绑定的值是null 或者undefined ,那么该attribute将会从渲染的元素上移除

javascript 复制代码
<template>
  <div v-bind:id="id" v-bind:class="msg" v-bind:title="title">测试</div>
</template>
<script>

export default {
  data() {
    return {
      msg: 'active',
      id:"customid",
      title:null
    }
  }
}

</script>

简写

因为v-bind非常常用,我们提供了特定的简写语法:

html 复制代码
  <div :id="id" :class="msg" :title="title">测试</div>

布尔型Attribute

布尔型attribute依据true/false值来决定attribute是否应该存在于该元素上,disabled就是最常见的例子之一。

javascript 复制代码
<template>
  <button :disabled="isButtonDisenabled">按钮</button>
</template>
<script>

export default {
  data() {
    return {
      isButtonDisenabled: true
    }
  }
}

</script>

我们可以看到此时按钮是不可点击的

动态绑定多个值

如果你有像这样的一个包含多个attribute的JavaScript对象

javascript 复制代码
<template>
  <div v-bind="obiectOfAttrs">测试</div>
</template>
<script>

export default {
  data() {
    return {
      customid: 'customid',
      customclass: 'customclass',
      obiectOfAttrs: {
        id: "customid",
        class: "customclass"
      }
    }
  }
}

3.条件渲染

在Vue中,提供了条件渲染,这类似于JavaScript 中的条件语句

  • v-if
  • v-else
  • v-esle-if
  • v-show

v-if

v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染

javascript 复制代码
<template>
  <h3>条件渲染</h3>
  <div v-if="flag">你能看见我么</div>
</template>
<script>
export default {
  data(){
    return {
      flag: true
    }
  }
}
</script>

v-else

你也可以使用v-else为v-if添加一个"else区块"

javascript 复制代码
<template>
  <h3>条件渲染</h3>
  <div v-if="flag">你能看见我么</div>
   <div v-else>那你还是看我吧</div>
</template>
<script>
export default {
  data(){
    return {
      flag: false
    }
  }
}
</script>

v-else-if

顾名思义,v-else-if提供的是相应于vif的"else if区块"。它可以连续多次重复使用

javascript 复制代码
<template>
  <h3>条件渲染</h3>
  <div v-if="type === 'A'">
    A
  </div>
  <div v-else-if="type === 'B'">
    B
  </div>
  <div v-else-if="type === 'C'">
    C
  </div>
  <div v-else>
    NOT A/B/C
  </div>

</template>
<script>
export default {
  data(){
    return {
      type:"D"
    }
  }
}
</script>

v-show

另一个可以用来按条件显示一个元素的指令是**v-show。**用法基本一样

javascript 复制代码
<template>
  <h3>条件渲染</h3>
  <div v-show="flag">你能看见我么</div>
</template>
<script>
export default {
  data(){
    return {
      flag: true
    }
  }
}
</script>

v-if Vs v-show

v-if是"真实的"按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。

v-if也是惰性的:如果在初次渲染时条件值为false,则不会做任何事。条件区块只有当条件首次变为true时才被渲染。

相比之下,v-show简单许多,元素无论初始条件如何,始终会被渲染,只有CSS display属性会被切换。

总的来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要频繁切换,则使用v-show较好;如果在运行时绑定条件很少改变,则v-if会更合适

4.列表渲染

我们可以使用v-for 指令基于一个数组来染一个列表。v-for 指令的值需要使用item in items 形式的特殊语法,其中items是是源数据的数组,而item是迭代项的别名

javascript 复制代码
<template>
  <div>
    <p v-for="item in names">{{ item }}</p>
  </div>
</template>
<script> 
export default {
  data() {
    return {
      names: ["Mike", "Jane", "Tom"],
    };
  },
};
</script>

复杂数据

大多数情况,我们渲染的数据源来源于网络请求,也就是JSON格式

v-for 也支持使用可选的第二个参数表示当前项的位置索引

javascript 复制代码
<template>
  <div v-for="item in result">
    <p >{{ item.id }}</p>
    <img :src="item.avator" alt="">
  </div>
  <p v-for="(item,index) in names">{{index}}:{{item}}</p>
</template>
<script>
export default {
  data() {
    return {
      names: ['张三', '李四', '王五'],
      result: [
        {
          "id": "ITEM001",
          "name": "产品A",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
        },
        {
          "id": "ITEM002",
          "name": "产品B",
          "avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
        },
        {
          "id": "ITEM003",
          "name": "产品C",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
        }
      ]
    };
  },
};
</script>

你也可以使用作of 为分隔符来替代 in 这更接近JavaScript的迭代器语法

javascript 复制代码
  <div v-for="item of result">

v-for与对象

你也可以使用v-for来遍历一个对象的所有属性

javascript 复制代码
<template>
  <div v-for="item of result">
    <p >{{ item.id }}</p>
    <img :src="item.avator" alt="">
  </div>
  <p v-for="(item,index) in names">{{index}}:{{item}}</p>
  <div v-for="item of userInfo">{{ item }}</div>
</template>
<script>
export default {
  data() {
    return {
      names: ['张三', '李四', '王五'],
      result: [
        {
          "id": "ITEM001",
          "name": "产品A",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
        },
        {
          "id": "ITEM002",
          "name": "产品B",
          "avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
        },
        {
          "id": "ITEM003",
          "name": "产品C",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
        }
      ],
      userInfo: {
        name: '张三',
        age: 18,
        sex: '男'
      }
    };
  },
};
</script>

5.通过key管理状态

Vue默认按照"就地更新"的策略来更新通过v-for渲染的元素列表。当数据项的顺序改变时,Vue不会随之移动DOM元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。

为了给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的key attribute:

javascript 复制代码
<template>
  <h3>key属性添加到v-for</h3>
  <p v-for="(item,index) in names" :key="index">{{item}}</p>
</template>
<script>
export default {
  data(){
    return{
      names:["张三","李四","王五"]
    }
  }
};
</script>

温馨提示
key 在这里是一个通过v-bind 绑定的特殊attribute

推荐在任何可行的时候为v-for 提供一个keyattribute

key 绑定的值期望是一个基础类型的值,例如字符串或number类型

key的来源

请不要使用index作为key的值,我们要确保每一条数据的唯一索引|不会发生变化

javascript 复制代码
<template>
  <div v-for="item of result" :key="item.id">
    <p >{{ item.id }}</p>
    <img :src="item.avator" alt="">
  </div>
  <p v-for="(item,index) in names" :key="item">{{index}}:{{item}}</p>
  <div v-for="item of userInfo">{{ item }}</div>
</template>
<script>
export default {
  data() {
    return {
      names: ['张三', '李四', '王五'],
      result: [
        {
          "id": "ITEM001",
          "name": "产品A",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/432eddcf18fc472b9429556ea80f64cf"
        },
        {
          "id": "ITEM002",
          "name": "产品B",
          "avator": "https://p3-search.byteimg.com/img/labis/7d19a60bce9c75c0ddd71bd92d7e007b~480x480.JPEG"
        },
        {
          "id": "ITEM003",
          "name": "产品C",
          "avator": "https://p3-search.byteimg.com/obj/pgc-image/153355020857866fdf59e72"
        }
      ],
      userInfo: {
        name: '张三',
        age: 18,
        sex: '男'
      }
    };
  },
};
</script>

6.事件处理

我们可以使用v-on 指令(简写为**@** )来监听DOM事件,并在事件触发时执行对应的JavaScript。用法:v-on:click="methodName" 或**@click="handler"**

事件处理器的值可以是:

  1. 内联事件处理器:事件被触发时执行的内联JavaScript语句(与onclick类似)
  2. 方法事件处理器:一个指向组件上定义的方法的属性名或是路径

内联事件处理器

内联事件处理器通常用于简单场景

javascript 复制代码
<template>
  <h3>内联事件处理器</h3>
  <button @click="count++">点我</button>
  <p>{{count}}</P>
</template>
<script> 
export default {
  data(){
    return {
      count:0  
    }
  }
}
</script>

方法事件处理器

javascript 复制代码
<template>
  <h3>方法事件处理器</h3>
  <button @click="addCount">点我</button>
  <p>{{count}}</P>
</template>
<script> 
export default {
  data(){
    return {
      count:0  
    }
  },
  //所有的方法和函数都放在这里
  methods:{
    addCount(){
      this.count++
    }
  }
}
</script>

7.事件参数

事件参数可以获取event对象和通过事件传递数据

获取event对象

javascript 复制代码
<template>
  <h3>事件传参</h3>
  <p @click="getNameHandler(item)" v-for="(item,index) in names" :key="index">{{ item }}</p>
</template>
<script> 
export default {
  data(){
    return {
      names:['张三','王五','小王']
    }
  },
  methods:{
    getNameHandler(item){
      console.log(item)
    }
  }
}
</script>