正在连接海拉鲁...

Vue

概述

  1. Vue.js是一个专注于构建Web用户界面的JavaScript库
  2. 作者:尤雨溪,中国人,早前就职于Google公司
  3. 思想:MVVM(Model-View-ViewModel)
    • M:Model,模型(数据和业务逻辑)
    • View:视图
    • ViewModel:视图模型,是一个纽带,它连接模型和视图
  4. 一个渐进式的框架

使用

  1. 安装

    //使用CDN
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    
    //先安装node.js,在当前终端中:npm install vue
    <script src="./node_modules/vue/dist/vue.global.js"></script>
    
  2. 创建第一个案例

    <div id="app">
          {{msg}}
    </div>
    //app表示一个Vue的应用实例
         const app = Vue.createApp({
           data(){
             return{
                 msg:'Hello!!'
             }
           }
         });
         //root表示Vue应用的根组件
         const root = app.mount("#app");
    • Vue:是一个包含各种工具和方法的对象,用来创建并配置一个新的Vue应用实例
    • Vue.createApp(Vue组件配置对象):创建了一个新的Vue应用实例
    • mount(“#app”):把Vue实例挂载到id为app的div上
    • root:表示一个根组件实例,可以通过这个实例来访问组件的属性,方法和数据
    • 组件的data()方法返回的对象中的数据属性可以直接在组件的模板中访问,也可以通过组件的实例来访问。但注意。data()方法必须返回一个对象
    • ():插值表达式,指的是使用双大括号{{}}在模板中嵌入动态的值

语法

插值表达式

  1. 在插值表达式中可以写简单的js表达式
  2. 不是语句,不能写控制语句

指令

Vue提供了一系列的内置指令,用于在模板中执行一些常见的任务,如条件渲染,列表渲染,事件监听等,这些指定都是以v-前缀开头的

  1. v-text:用于更新元素的textContent,不会对数据中的html进行解析

  2. v-html:用于更新元素的innerHTML,会对数据中的html标签进行解析,显示解析后的结果

  3. v-bind:用于绑定属性到表达式,简写形式::

  4. v-model:绑定表单数据,双向绑定

    <input v-model="title">
    
    data(){
    	return{
    		title:'tom'
    	}
    }
  5. v-on:绑定事件处理程序,简写:@

    <div id="app">
        <input v-on:click="test" type="button" value="测试">
        <input :value="abc">
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                        abc:'',
                }
            },
            methods:{
                test(){
                    this.abc="tom"//this:当前vue组件
                }
            }
        }).mount("#app");
    </script>
  6. v-show:是否显示元素,元素的显示和隐藏是通过css的display属性来控制的

    <p v-show="b">abc</p>
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    b:false
                }
            },methods:{
                ifshow(){
                    this.b=!this.b
                }
            }
        }).mount("#app");
    </script>
  7. v-if,v-else-if,v-else:用于条件渲染

    <div id="app">
        <input v-model="score">
        <p v-if="score>=90">优秀</p>
        <p v-else-if="score>=80">良好</p>
        <p v-else-if="score>=70">中等</p>
        <p v-else-if="score>=60">及格</p>
        <p v-else>不及格</p>
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    score:90
                }
            }
        }).mount("#app");
    </script>

    v-if和v-show的区别

    • v-if:如果为false,会删除DOM元素,为true,会创建DOM元素
    • v-show:通过样式显示和隐藏元素,隐藏时并不会删除DOM元素
  8. v-for:用于渲染列表

    <table border="1">
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>年龄</th>
            </tr>
            <tr v-for="(stu,index) in stus":key="stu.index">
                <td>{{index+1}}</td>
                <td>{{stu.name}}</td>
                <td>{{stu.age}}岁</td>
            </tr>
        </table>
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    stus:[
                        {name:'tom',age:20},
                        {name:'marry',age:18},
                        {name:'scott',age:25}
                    ]
                }
            }
        }).mount("#app");
    </script>

    vue使用”就地复用”的思想复用已经生成的DOM,使用绑定key属性来确定DOM属性是否已经创建,要求key的值是唯一的

  9. 表单样例

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./node_modules/vue/dist/vue.global.js"></script>
    </head>
    <body>
    <div id="app">
        <table border="1">
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th colspan="2">操作</th>
            </tr>
            <tr v-for="(stu,index) in stus":key="stu.index">
                <td>{{index+1}}</td>
                <template v-if="stu.edit" >
                    <td><input type="text" size="5" v-model="stu.name"></td>
                    <td><input type="text" size="5" v-model="stu.age"></td>
                </template>
                <template v-else>
                    <td>{{stu.name}}</td>
                    <td>{{stu.age}}岁</td>
                </template>
                <td><input @click="edit(stu)" :value="statement" type="button"></td>
                <td><input type="button" @click="deleteItem(index)" value="删除"></td>
            </tr>
        </table>
        姓名:<input type="text" v-model="stu.name">
        年龄:<input type="text" v-model="stu.age">
        <input type="button" value="添加" @click="add(stu.name,stu.age)">
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    stus:[
                        {name:'tom',age:20},
                        {name:'marry',age:18},
                        {name:'scott',age:25}
                    ],
                    statement:"编辑",
                    stu:{
                        name:'',
                        age:''
                    }
                }
            },methods:{
                edit(stu){
                    if(this.statement === "编辑"){
                        stu.edit = true;
                        this.statement = "保存";
                    }else {
                        stu.edit = false;
                        this.statement = "编辑";
                    }
    
                },
                deleteItem(index){
                    if (confirm("是否删除")){
                        this.stus.splice(index,1);
                    }
                },
                add(){
                    this.stus.push(this.stu);
                    this.stu={
                        name:"",
                        age:""
                    }
                }
            }
        }).mount("#app");
    </script>
    </body>
    </html>

绑定复选框

<template v-for="hobby in hobbies">
<input type="checkbox" v-model="selectedItem" :value="hobby">{{hobby}}
</template>
  • 单个复选框:使用v-model绑定一个布尔值

    <input type="checkbox" v-model="isAll">
    <script>
    Vue.createApp({
        data(){
            return{
                isAll:false//复选框被选中,isAll为true
            }
        }
    })
    </script>
  • 复选框组:使用v-model绑定到一个数组,如果复选框被选中,当前复选框的值会被放到数组中,取消选择,则从数组中移除

    <input type="checkbox" v-model="selectedItem" :value="hobby">{{hobby}}
    
     const root = Vue.createApp({
            data() {
                return {
                    hobbies:[
                        "学java",
                        "玩游戏",
                        "踢足球",
                        "打篮球"
                    ],
                    selectedItem:[
    
                    ],
                    selectTime:false,
                    isAll:false
                }
            },methods:{
                checkAll(){
                    // this.selectTime = !this.selectTime;
                    if (this.isAll){
                        this.selectedItem =[...this.hobbies];
                    }else{
                        this.selectedItem.length = 0;
                    }
                },
                reverseAll(){
                    this.selectedItem =  this.hobbies.filter(h=>{
                        //includes:查找参数元素是否存在,如果存在返回true,否则返回false
                        return !this.selectedItem.includes(h);
    
                        /*if (this.selectedItem.indexOf(h) >= 0){
                            return false;
                        }else {
                            return true;
                        }*/
                    })
                }
            }
        }).mount("#app");
    </script>

绑定单选按钮

<div id="app">
    <template v-for="hobby in hobbies">
        <input type="radio" v-model="selectItem" :value="hobby">{{hobby}}
    </template>
</div>

<script>
    const root = Vue.createApp({
        data() {
            return {
                hobbies:["阅读","旅游","音乐","运动"],
                selectItem:''//如果值为"阅读",则"阅读"被默认选中
            }
        }
    }).mount("#app");

注意:没有给单选按钮的value赋值,默认值是on

绑定下拉列表框

<select v-model="selectProvince" @change="cityChange">
<option v-for="province in provinces" >{{province}}</option>
 </select>

省市级联综合案例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    省份<select v-model="selectProvince" @change="cityChange">
        <option v-for="province in provinces" >{{province}}</option>
    </select>
    城市<select>
        <option v-for="city in selectCities">{{city}}</option>
    </select>
</div>

<script>
    const root = Vue.createApp({
        data() {
            return {
                provinces:["辽宁",'吉林','黑龙江'],
                selectProvince:'--请选择--',
                cities:new Map([
                        ['辽宁',['沈阳','大连','盘锦']],
                        ['吉林',['长春','吉林']],
                        ['黑龙江',['哈尔滨','齐齐哈尔']]
                    ]),
                selectCities:[]

            }
        },methods:{
            cityChange(){
                this.selectCities=this.cities.get(this.selectProvince)
            }
        }
    }).mount("#app");
</script>
</body>
</html>

Map集合

  1. 创建map集合

    let map = new Map();
  2. 创建并初始化map集合

    let map = new Map([[key.value],[key.value],[key.value],[key.value],[key.value]...]);
  3. 添加键值对

    map.set(key,value)
  4. 根据键取值

    map.get(key)
  5. 移除键值对

    map.delete(key)
  6. 得到键的迭代器对象

    let keys = map.keys()
    
    let keys = this.map.keys();
    for (let i = 0; i < this.map.size; i++) {
    this.items.push(keys.next().value)
                    }
  7. 得到值的迭代器对象

    let values = map.values()
    
    let items = this.map.values()
    for (let i = 0; i < this.map.size; i++) {
    this.items.push(items.next().value)
                    }
  8. 得到键值对的个数

    map.size

样式绑定

  1. 通过v-bind指令,绑定内联样式(行内样式)和类样式

  2. 绑定内联样式

    • 绑定单个样式
    <div id="app">
        <p :style="{color:colorValue,fontSize:fontSizeValue}">tom</p>
        <input type="button" value="修改" @click="changeStyle">
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    colorValue:'red',
                    fontSizeValue:'15px'
                }
            },methods:{
                changeStyle(){
                    this.colorValue = 'blue'
                    this.fontSizeValue = "50px"
                }
            }
        }).mount("#app");
    </script>
    • 绑定样式对象

      <div id="app">
          <p :style="styleObj">tom</p>
          <input type="button" value="修改" @click="changeStyle">
      </div>
      
      <script>
          const root = Vue.createApp({
              data() {
                  return {
                      styleObj:{
                          color:'red',
                          fontSize:'15px'
                      }
                  }
              },methods:{
                  changeStyle(){
      
                  }
              }
          }).mount("#app");
      </script>
  3. 类样式绑定

    • 绑定单个类名

      <style>
             .class1{
                 color: red;
             }
      </style>
         <p :class="{class1:isShow}">普通文本</p>
              
        data() {
                 return {
                     isShow:true
                 }
             }
    • 绑定类对象

          <style>
              .class1{
                  color: red;
              }
              .class2{
                  font-size: 20px;
              }
          </style>
      <div id="app">
          <p :class="classObj">普通文本</p>
      </div>
      data() {
                  return {
                     classObj:{
                         class1:true,
                         class2:true
                     }
                  }
              }
    • 绑定类数组

      <style>
              .class1{
                  color: red;
              }
              .class2{
                  font-size: 50px;
              }
      </style>
      <div id="app">
          <p :class="[classObj1,classObj2]">普通文本</p>
      </div>
      data() {
                  return {
                     classObj1:{
                         class1:true
                     },
                      classObj2:{
                          class2:true
                      }
                  }
              }

计算属性

  1. 定义:计算属性是基于组件的响应式依赖进行缓存的属性,只有当它的依赖发生变化时,才会重新求值

  2. 使用原因:

    • 性能优化
    • 逻辑清晰
  3. 基本使用

    <div id="app">
        商品价格:<input type="text" v-model="price">
        商品数量:<input type="number" v-model="sum"><br>
        商品总价:{{total}}<br>
        姓名:{{showName}}
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    price:10,
                    sum:0,
                    name:"tom"
                }
            },computed:{//计算属性
                total(){
                    return this.price*this.sum
                },
                showName(){
                    return this.name.toUpperCase();
                }
            }
        }).mount("#app");
    </script>
  4. 计算属性和方法

    • 计算属性依赖缓存,只有当依赖发生变化的时候才会重新求值

监听属性

  1. 定义:监听属性允许你响应某些特定的数据变化,执行自定义的逻辑,与计算属性相似,但专为侦听数据的变化而设计

  2. 基本使用

    <div id="app">
        <input type="text" v-model="km">千米<br>
        <input type="text" v-model="m"><br>
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    km:0,
                    m:0
                }
            },methods:{
    
            },computed:{
    
            },watch:{
                km(newValue,oldValue){
                    this.m = newValue*1000;
                },
                m(newValue,oldValue){
                    this.km = newValue/1000;
                }
            }
        }).mount("#app");
  3. 为什么使用监听属性

    • 执行异步操作或昂贵操作(计算属性无法执行异步操作,它是同步的)
    • 可以对多个数据源进行侦听
  4. 深度监听和立即执行

    <div id="app">
        商品价格:<input type="text" v-model="good.price"><br>
        商品数量:<input type="text" v-model="good.num"><br>
        {{total}}
    </div>
    
    <script>
        const root = Vue.createApp({
            data() {
                return {
                    good:{
                        price:1,
                        num:1
                    },
                    total:''
                }
            },watch:{
                good:{
                    handler(newValue){
                        this.total = this.good.num * this.good.price
                    },
                    deep:true//深度监听,监听对象的属性
                    ,immediate:true//立即执行
                }
            }
        }).mount("#app");
    </script>

组件

概述

  1. 定义:组件是Vue最强大的功能之一,组件可以扩展html元素,封装可重用的代码

  2. 目的:

    • 代码重用
    • 模块化
    • 简洁性:清晰地定义界面的每个部分
  3. 基础使用:

    • 定义组件

      const myComponent = {
              template:`<div >{{msg}}--{{count}}--<input @click="add" type="button" value="+"></div>`,
              data(){
                  return{
                      msg:'Hello!',
                      count:1
                  }
              },methods:{
                  add(){
                      this.count++
                  }
              }
          }
    • 注册组件

      • 局部注册

        const root = Vue.createApp({
                data() {
                    return {
        
                    }
                },
                components:{//注册组件 组件名:组件对象
                    "my-component":myComponent
                }
            }).mount("#app");
      • 全局注册

        const app = Vue.createApp({
            data() {
                return {
               
                }
            },
            //在Vue应用对象中注册,称为全局注册
                app.component("my-component",myComponent)
               
    • 在父组件的模板中使用

      <div id="app">
          <my-component></my-component>
      </div>
    • 组件名称注意事项:

      • 驼峰命名:在JavaScript中使用驼峰命名法,例如:myComponent
      • 短横线命名:在html的模板中,组件名应使用短横线命名,例如:my-component
      • 避免使用Vue保留的前缀,如:v-

Vue3父子组件通信

  1. 基本概念:

    • 在vue中,父子组件的关系可以总结为prop down,events up(属性下传,事件上抛)
    • 父组件通过props将数据传递给子组件
    • 子组件通过事件向父组件发送信息
  2. props

    • 定义:是props是父组件用来传递数据给子组件的自定义属性

    • 使用:在子组件中声明props属性来接收数据

      //子组件
      {
          name:'子组件的名字',
          props:["num"]
      }

      注意:子组件内部不应该修改prop的值

  3. 自定义事件

    • 子组件

      //ChildCom.vue
      this.$emit('事件名',向父组件传递的数据)
    • 父组件

      //ParentCom.vue
      <template>
      	<ChildCom @事件名="父组件中的方法"></ChildCom>
      	<ChildCom @事件名="num=$"></ChildCom>
      </template>
      methods:{
          //value表示子组件传递出来的值
          父组件中的方法(value){
              
          }
      },data(){
          return{
              num:0
          }
      }

      $event:表示子组件传递出来的值

provide和inject

  1. 概述:主要用于避免为深层次的组件通过 props 逐层传递数据。

  2. 工作原理:

    • provide:通过该属性暴露一些属性或方法,使其在子组件中可用
    • inject:任何子组件或更深层的组件可以通过 inject 选项来获取其祖先组件暴露出来的属性或方法
  3. 基本使用

    • 父组件

      provide:{
          themeColor:'blue'
      }
    • 子组件

      inject:['themeColor']

插槽

  1. 实现了一种内容分发的机制。可以使得父组件插入内容到子组件的视图结构中。

  2. 基础插槽

    • 默认插槽:允许父组件为子组件插入内容

      • 如果子组件没有预留出插槽,父组件的内容被忽略
      • 子组件内容使用<slot></slot>来指定内容的分发位置
    • 子组件

      //ChildSlot
      <template>
      	<div><slot></slot></div>
      </template>
    • 父组件

      <ChildSlot>
      	<h1>父组件插入的内容</h1>
      </ChildSlot>
  3. 具名插槽

    • 允许多个插槽的存在,需要使用name属性区分

    • 子组件

      //ChildSlot
      <template>
      	<div><slot name="header"></slot></div>
      	<div><slot></slot></div>
      </template>
    • 父组件

      <ChildSlot>
      	<template #header>
      		插入到名称为header的子组件插槽
      	</template>
      	<h1>父组件插入的内容</h1>
      </ChildSlot>
  4. 作用域插槽

    • 允许子组件为插槽传递数据

    • 子组件

      //ChildSlotScope
      data(){
      	return {
      		num:100,
      		name:'tom'
      	}
      }
      
      <template>
      	<slot :n="num" :username="name"></slot>
      	<slot name="header" :n="num"></slot>
      </template>
    • 父组件

      <ChildSlotScope>
      	<template #default="slotScope">
      		数量:{{slotScope.n}},用户名:{{slotScope.username}}
      	</template>
      	<template #header="slotScope">
      		数量:{{slotScope.n}}
      	</template>
      </ChildSlotScope>

Vite

概述

  1. Vite是什么?

    • Vite(法语中的”快”),是一个由Vue.js的创建者尤雨溪开发的Web开发构建工具,旨在提供更快的冷启动时间
    • 它不同于传统的工具如Webpack,Vite利用了ES6的原生模块系统(ESM)进行快速的源码到源码的转换
  2. 基础使用

    npm create vite@latest
    
    npm create vite@latest 项目名 -- --template vue
  3. Vite中vue项目目录结构

    • index.html:这是应用的主html文件,它是Vite开发服务器的入口点,并且也是构建后的应用的入口点
    • package.json:这个文件包含了项目的元数据,例如:项目的名称,版本,依赖
    • package-lock.json:是自动生成的,用于描述项目的依赖树结构的文件,当在项目中安装或更新依赖时,这个文件会自动更新
    • src/:这个目录包含了应用的所有源文件,包括Vue组件、JavaScript文件和其他资源
      • assets:这个目录是用于存放静态资源,如图片,字体等
      • components:这里通常存放vue组件文件
      • App.vue:主Vue组件文件,通常会包括应用的布局和样式
    • vite.config.js:自定义的vite配置放到这里

路由

概述

  1. 介绍

    • Vue Router是Vue.js官方的路由管理器,它与Vue.js的核心深度集成,简化单页面应用的开发
  2. 安装

    npm install vue-router@4
  3. 基本使用

    • 创建路由对象

      //src/router/index.js
      
      import {createRouter,createWebHistory} from "vue-router";
      
      //路由表
      const routes=[
          {
              path:"/login",
              name:"login",
              component:()=> import("../views/Login.vue")
          },{
              path:"/main",
              name:"main",
              component:()=>import("../views/main.vue")
          }
      ]
      //创建一个路由器对象
      const router=createRouter({
          history:createWebHistory(import.meta.env.BASE_URL),
          routes
      })
      
      export default router;
    • 在主应用中使用

      //main.js
      
      import { createApp } from 'vue'
      // import './style.css'
      import router from "./router/index.js";//导入路由器对象
      import App from './App.vue'
      
      createApp(App).use(router).mount('#app')//在vue应用中注册路由插件
    • 在App.vue组建中添加<router-view></router-view>

路由传参

  1. 使用路由路径参数

    {
        path:'editDept/:deptno'
    }
    //使用params传参,不能使用path属性
    <router-link :to="{name:'editdept',params:{deptno:dept.deptno}}"></router-link>
    
    
    //得到数据
    {{$route.params.deptno}}
    
    //地址栏
    http://localhost:5173/main/editdept/10
  2. 实用查询参数

    • 不需要在路由配置中预先定义查询参数

      {
          path:'editdept'
      }
      
      <router-link :to="{name:'editdept',query:{deptno:dept.deptno}}"></router-link>
      
      //地址栏
      http://localhost:5173/main/deptModify?deptno=10&dname=人力资源部

编程式路由

  1. 导航的两种方式

    • 声明式导航:通过<router-link>标签
    • 编程式导航:通过Vue-router提供的api来实现
  2. router.push()

    会向路由的历史记录中添加一个新的记录

    $router.push("/main")
    
    $router.push({name:'dept',query:{deptno:Deptno}})
  3. router.replace()

    跟push()类似,但它不会向历史记录中添加新纪录,而是替换掉当前记录

  4. router.go(n)

    在历史记录中来回跳转

    this.$router.go(-1)后退一页
    this.$router.go(1)前进一页

路由守卫

主要用于监视路由的变化,可以执行某些操作,例如:权限检查,页面跳转

router.beforeEach((to,from,next)=>{
    if (to.path != '/' && to.path != '/login'){
        const user = sessionStorage.getItem("user");
        if (!user){
            next("/login")//跳转回登录页
        }else {
            next();
        }
    }

    next();//放行
})
  • beforeEach():允许在路由变化之前设置一个钩子函数
  • {to,from,next}=>{}
    • to:路由对象,表示即将导航到的目的路由对象
    • from:表示从哪个路由导航而来
    • next:是一个函数
    • next(‘/login’):拦截,跳转到指定路径
    • next(false):将中断导航

路由监听

使用watch选项来监听某个路由的变化

//APP.vue
 watch:{
        $route(to,from){
            if (to.name === "deptModify" && from.name === "dept"){
                alert("即将跳转")
            }
        }
    }

组件的生命周期

描述了组件从被创建到被销毁的整个过程,我们可以使用”钩子”在关键时刻插入自定义的代码

  1. beforeCreate和created
    • beforeCreate:组件实例创建之前执行的方法
    • created:组件实例创建完毕
  2. beforeMount和mounted
    • beforeMount:当组件挂载之前执行
    • mount:组件被挂载到DOM上
  3. beforeUpdate和updated
    • beforeUpdate:当响应式数据发生变化,组件需要更新之前
    • update:组件模板已经更新,数据变化后
  4. beforeDestory和destroyed
    • beforeDestory:组件销毁前执行
    • destroyed:组件被销毁后执行

Vuex

  1. 介绍

    • 是vue.js的状态管理库
  2. 安装

    npm install vuex@next --save
  3. 配置

    //src/store/index.js
    
    import {createStore} from "vuex";
    
    const store = createStore({
        state(){
            return{
                count:0
            }
        }
    })
    
    export default store
  4. 在Vue应用对象中注册插件

    //main.js
    import store from "./store/index.js";
    createApp(App).use(router).use(store).mount('#app')
    
  5. 在vue组件中

    {{$store.state.count}}
    
    this.$store.state.count
  6. 改变状态

    • 不能直接改变store中的状态,修改store中的状态的唯一途径就是显示的提交(commit) mutation

      const store = createStore({
          state(){
              return{
                  count:0
              }
          },
          mutations:{
              increment(state){
                  state.count++
              }
          }
      })
      
      
      //代码
      this.$store.commit('increment')
  7. getters

    • 从store中的state派生出一些状态

      import {createStore} from "vuex";
      
      const store = createStore({
          state(){
              return{
                  count:0
              }
          },
          mutations:{
              increment(state,num){
                  state.count += num
              }
          },
          getters:{
              count2: state => state.count+"个"
          }
      })
      
      //模板中
      {{$store.getters.count2}}
  8. Actions

    • Action可以包含任意异步操作

    • Action提交时是mutation而不是直接修改状态

      import {createStore} from "vuex";
      
      const store = createStore({
          state(){
              return{
                  count:0
              }
          },
          mutations:{
              increment(state,num){
                  state.count += num
              }
          },
          getters:{
              count2: state => state.count+"个"
          },
          actions:{
              add(context){
                  setTimeout(function (){
                      context.commit('increment',2)
      
                  },3000)
              }
          }
      })
      
      export default store
      
      

组合式API

概述

是Vue3新引入的一种编写组件逻辑的方式,与Vue2的选项式API相比,提供了更加灵活的代码组织方式

set()函数

<script>
    import {ref} from "vue";

    export default {
        setup(){
            let num = ref(10);
            let name = ref("tom")
            function test(){
                num.value++;
                name.value = "marry"
            }
            return {
                num,
                test,
                name
            }
        }
    }
</script>

<template>
    {{num}}
    {{name}}
    <input type="button" @click="test" value="test">
</template>

<style scoped>

</style>

<script setup>

<script setup>
    import {ref} from "vue";

    let num = ref(10);
    let name = ref("tom")
    function test(){
        num.value++
        name.value = "marry"
    }
</script>

<template>
    {{num}}
    {{name}}
    <input type="button" @click="test" value="test">
</template>

<style scoped>

</style>

ref和reactive

  1. ref:用于将原始数据类型(如:string、number)转化为响应式对象

    • 返回的对象有一个value属性,通过这个属性可以获取或设置其值
  2. reactive:用于创建一个响应式对象

    • 对于对象和数组,可以直接使用它们,无需.value
    • 不能直接包装原始数据类型
       
    import {reactive, ref} from "vue";
       
    const obj = reactive(
        {
            age:10,
            arr:[1,2,3],
            scores:[
                {name:'数学',score:100},
                {name:'语文',score:90},
                {name:'英语',score:80},
            ]
        }
    )
       
    const arr=reactive([
        {name:'数学',score:100},
        {name:'语文',score:90},
        {name:'英语',score:80},
    ])
    const arr2 =ref(
        {
            count:10,
            name:'tom'
        }
    )
       
    function change(){
        // obj.age++;
        // obj.arr[0]++;
        // obj.scores[0].score--;
        // arr[0].score--
        arr2.value.count++
    }

计算属性

let total = computed(()=>price.value*num.value)

props

//子组件

let props = defineProps(['name','num'])

{{props.name}}--{{props.num}}

//父组件
<ChildTest name='tom' num='18'></ChildTest>

defineEmits

//子组件
    let emits = defineEmits([
        'event1','event2'
    ])
        function toParent(){
        emits('event1',100)
        emits("event2",200)
    }
//父组件
<script setup>
    import ChildTest from "./ChildTest.vue"
    import {ref} from "vue";

    let num = ref(0)
</script>

<template>
    <ChildTest name="tom" num="18" @event2="num = $event"></ChildTest>
    {{num}}
</template>

<style scoped>

</style>

生命周期钩子函数

  • 没有对应的created函数,原来在created事件发生事后执行的代码直接写到script标签中

    function showHi(){
        alter("Hi")
    }
    
    showHi();
  • onMounted

    onMounted(() =>{
        alter("Hi")
    })
  • 大多数生命周期的钩子函数都是在原来函数前加on,特殊的如:destroyed和beforeDestroyed用onUnmountedonBeforeUnmount替代

监听器

let km = ref(0)
let m = ref(0)
watch(km,(newValue,oldValue)=>{
    m.value = km.value * 1000
})
watch(m,()=>{
    km.value = m.value / 1000
})

补充

在Vite中动态使用图片

import imgSrc from '../assets/vue.svg'

<img :src="imgSrc">

1.