Vue3学习

刚入门写的有的乱,请见谅。

默认有html,css,js基础。

文章目录

    • [1. 准备](#1. 准备)
    • [2. 基础](#2. 基础)
      • [1. 响应式基础](#1. 响应式基础)
      • [2. 指令](#2. 指令)
        • [1. 属性绑定与条件渲染](#1. 属性绑定与条件渲染)
        • [2. 列表渲染 v-for](#2. 列表渲染 v-for)
        • [3. 事件处理 v-on](#3. 事件处理 v-on)
        • [4. 事件参数](#4. 事件参数)
        • [5. 事件修饰符](#5. 事件修饰符)
        • [6. 数组变化侦测](#6. 数组变化侦测)
      • [3. 计算属性 computed](#3. 计算属性 computed)
      • [4. 类与样式绑定](#4. 类与样式绑定)
      • [5. 侦听器 watch](#5. 侦听器 watch)
      • [6. 表单输入绑定 v-model](#6. 表单输入绑定 v-model)
      • [7. 模板引用 ref](#7. 模板引用 ref)
      • [8. 组件基础](#8. 组件基础)
    • [3. 深入组件](#3. 深入组件)
      • [1. 组件注册(全局和局部)](#1. 组件注册(全局和局部))
        • [1. 全局注册](#1. 全局注册)
        • [2. 局部注册](#2. 局部注册)
      • [3. 父传子 props](#3. 父传子 props)
      • [4. 组件事件](#4. 组件事件)
      • [5. 透传attributes](#5. 透传attributes)
      • [6. 插槽 slot](#6. 插槽 slot)
        • [1. 简介](#1. 简介)
        • [2. 渲染作用域](#2. 渲染作用域)
        • [3. 插槽默认值](#3. 插槽默认值)
        • [4. 具名插槽](#4. 具名插槽)
        • [5. 作用域插槽](#5. 作用域插槽)
      • [7. 组件生命周期](#7. 组件生命周期)
      • [8. 动态组件](#8. 动态组件)
      • [9. 组件保持存活](#9. 组件保持存活)
      • [10. 异步组件](#10. 异步组件)
      • [11. 依赖注入](#11. 依赖注入)
    • 参考

1. 准备

vscode下完配好c和python环境。

npm换淘宝源,下载vue

vscode上下载volar插件

npm init vue@latest 创建vue项目

python 复制代码
#项目目录解释
public 资源文件(浏览器图标)
src 源码文件夹
src/assets 存放公共资源,比如图片
.gitignore git忽略文件
package.json 信息描述文件
vite.config.js vue配置文件

在index.html中写入以下代码,将vue应用HelloVueApp挂载到对应id的div标签中。

{``{}}用于输出对象的属性和函数返回值。

在一个vue项目中,有且只有一个vue的实例对象。

vue 复制代码
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="hello-vue" class="demo">
  {{ message }}
</div>
<script>
const HelloVueApp = {
  data() {
    return {
      message: 'Hello Vue!!'
    }
  }
}
Vue.createApp(HelloVueApp).mount('#hello-vue')
//使用createApp()创建新的应用实例
//传入createApp()的对象实际是一个根组件
//应用挂载(mount)到id为hello-vue的html标签上
</script>
</body>

2. 基础

1. 响应式基础

略。

2. 指令

指令 简写 说明
v-bind : 属性绑定
v-if...v-else...v-else-if 条件渲染,有较高的切换渲染开销
v-show 条件性地显示或隐藏元素,有较高的初始渲染开销
v-for 列表渲染
v-on @ 事件监听
v-model 双向绑定
1. 属性绑定与条件渲染

修改index.html对应部分

vue 复制代码
<div id="hello-vue" >
    <p v-bind:class="msg">p标签class属性与msg的值绑定</p>
    <p v-bind="obj">绑定多个值</p>
    <p v-if="flag">false隐藏</p>
    <p v-if="type === 'A'">A</p>
    <p v-else-if="type === 'B'">B</p>
    <p v-else="type === 'C'">C</p>
    <p v-show="flag">使用css的display</p>
</div>

const HelloVueApp = {
  data() {
    return {
      msg: 'jkloli',
		obj:{class:"123",id:"456"},
		flag:false,
		type:"B"
    }}}
2. 列表渲染 v-for

v-for遍历列表有两个参数,第二个参数表示下标。

v-for遍历对象有三个参数,三个参数依次为value,key,index。

v-for可以设置key来管理状态,减少重复渲染的次数。

in也可以写成of

vue 复制代码
  <div id="hello-vue" >
    <div v-for="i in result">
      <p>{{i.id}}</p>
      <p>{{i.name}}</p>
    </div>
    <p v-for="(j,index) in list">内容{{j}},下标{{index}}</p>
    <p v-for="(v,k,i) in obj" :key="i">{{v}},{{k}},{{i}}</p>
  </div>

const HelloVueApp = {
  data() {
    return {
      result:[{"id":"1","name":"雪"},{"id":"2","name":"梅"}],
      list:['a','b','c'],
      obj:{"name":"zs","age":99}
    }}}
3. 事件处理 v-on

事件处理分为内联事件处理和方法事件处理。

在index.html里

vue 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Vue 测试实例</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

在App.vue里,导入Demo1,因为使用了

vue 复制代码
<script setup>//单文件
import Demo1 from "./components/Demo1.vue"
</script>
<template>
    <Demo1/>
</template>

在main.js里

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

在Demo1.vue里

vue 复制代码
<template>
<h3>内联事件处理器</h3>
<button v-on:click="count++">Add</button><br>
<h3>方法事件处理器</h3>
<button @click="mimusCount">minus</button><br>
<p>{{ count }}</p>
</template>

<script>
export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        mimusCount(){
            this.count-=1
        }
    }
}
</script>
4. 事件参数

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

在Demo1.vue里

vue 复制代码
<template>
    <p @click="getN(n,$event)" v-for="(n,i) in l" :key="i">{{ n }}</p>
    </template>
    
    <script>
    export default{
        data(){
            return{
                l:["zs","ls","ww"]
            }
        },
        methods:{
            getN(name,e){
                console.log(name);
                console.log(e);
            }
        }
    }
    </script>

点击左侧的zs即可在控制台打印event对象

5. 事件修饰符

事件捕获:事件从文档根节点(Document 对象)流向目标节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达事件的目标节点;

事件冒泡:与事件捕获相反,事件会从目标节点流向文档根节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达文档的根节点。整个过程就像水中的气泡一样,从水底向上运动。

v-on提供事件修饰符。

事件修饰符 说明
.stop 阻止事件冒泡
.prevent 阻止默认事件
.self 只有自己触发自己才执行,忽略内部冒泡传递的触发信号
.capture 从最外层向里捕获
.once 最多触发一次
.passive 不阻止默认事件
按键修饰符 按键修饰符
.enter .tab
.delete 捕获Delete和Backspace .esc
.space .up
.down .left
.right .middle
.ctrl
.alt .shift

.exact修饰符,语序控制触发一个事件所需的确定组合的系统按键修饰符。

vue 复制代码
<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发-->
<button @click.ctrl="onClick">A</button>
<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
vue 复制代码
<template>
    <a @click.prevent="HK" href="https://www.baidu.com">百度</a>
    <div @click="c1">
        <p @click.stop="c2">若冒泡,先打印c2,再打印c1。这里加了.stop不冒泡</p>
    </div>
    <div @click.self="c1">点我只触发c1
        <p @click="c2">会冒泡,点我只触发c2,因为外部.self忽略了内部冒泡信号</p>
    </div>
    </template>
    
    <script>
    export default{
        data(){
            return{
                l:["zs","ls","ww"]
            }
        },
        methods:{
            HK(){
                console.log("HK");
            },
            c1(){
                console.log("c1");
            },
            c2(){
                console.log("c2");
            }
        }
    }
    </script>

​ 以下代码点击c4,依次打印c2,c3,c4,c1(先由外向内捕获,再由内向外冒泡)。

vue 复制代码
<template>
    <div @click="c1">c1
        <div @click.capture="c2">c2
            <div @click.capture="c3">c3
                <div @click="c4">c4
                </div>
            </div>
        </div>
    </div>
    </template>
    
    <script>
    export default{
        data(){
            return{
            }
        },
        methods:{
            c1(){
                console.log("c1");
            },
            c2(){
                console.log("c2");
            },
            c3(){
                console.log("c3");
            },
            c4(){
                console.log("c4");
            }
        }
    }
    </script>
6. 数组变化侦测

变更方法:变更方法会改变原数组。

不可变方法:不改变原数组,返回新数组。

变更方法 说明
push() 向数组末尾添加元素,并返回新的长度。
pop() 删除并返回数组的最后一个元素
shift() 删除并返回第一个元素
unshift() 向数组的开头添加元素,并返回新的长度
splice(index,len,[list]) 从index向后删除len个元素,在index前插入[list]
this.list.sort((a,b)=>a.id-b.id) 升序排序数组
reverse() 数组翻转
不可变方法 说明
filter() 返回符合条件的数组
concat() 连接数组
slice() 从已有数组返回选定元素
vue 复制代码
<template>
    <p @click="c1">修改原数组</p>
    <p @click="c2">替换数组</p>
    <li v-for="i in numbers" :key="i">{{ i }}</li>
    </template>
    
    <script>
    export default{
        
        data(){
            return{
                numbers:[1,2,3,4,5,6]
            }
        },
        methods:{
            c1(){
                this.numbers.push(10);
            },
            c2(){
                this.numbers= this.numbers.concat([7,8,9]);
            }
        }
    }
    </script>

3. 计算属性 computed

​ 一个计算属性仅会在其响应式依赖更新时才重新计算。也就是说只要this.list的值不变,调用多次even也只会计算一次。

vue 复制代码
<template>
    <li v-for="i in list" :key="i">{{ i }}</li>
    <p>偶数: {{even}}</p>
    </template>
    
    <script>
    export default{   
        data(){
            return{
                list:[1,2,3,4,5,6]
            }
        },
        computed:{
            even(){
                return this.list.filter((i)=>i%2==0)
            }
        }
    }
    </script>

4. 类与样式绑定

classstylev-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象,数组或数组嵌套对象

vue 复制代码
<template>
    <p :class="{'a':isA,'b':isB}">class="a b"</p>
    <p :class="[jk,gg]">class="jkloli giegie"</p>
<p :style="obj">Red Taylor Swift</p>
    </template>
    
    <script>
    export default{
        data(){
            return{
                isA:true,
                isB:true,
                jk:"jkloli",
                gg:"giegie",
                obj:{color:"red",
                fontSize:30+'px'}
            }
        }
    }
    </script>

5. 侦听器 watch

​ 在组合式 API 中,我们可以使用watch函数在每次响应式状态发生变化时触发回调函数。

vue 复制代码
<template>
<p>{{msg}}</p>
<button @click="uD">修改</button>
    </template>
    
    <script>
    export default{
        data(){
            return{
                msg:"hello"
            }
        },
        methods:{
            uD(){
                this.msg="world";
            }
        },
        watch:{//watch选项
            //newValue改变之后新数据
            //oldValue改变之前旧数据
            msg(newValue,oldValue){
                //函数名必须与侦听对象同名
                console.log(newValue,oldValue);
            }
        }
    }
    </script>

6. 表单输入绑定 v-model

双向绑定,改变输入框的值会改变msg的值

vue 复制代码
<template>
    <input type="text" v-model.lazy="msg">
    <p>{{msg}}</p>
    <input type="checkbox" id="checkbox" v-model="checked"/>
    <label for="checkbox">{{checked}}</label>
        </template>
        
        <script>
        export default{
            data(){
                return{
                    msg:"hello",
                    checked:false
                }
            }
        }
        </script>
v-model修饰符 说明
.lazy 在每次change事件后更新数据(失去焦点更新)
.number 转为数字类型
.trim 过滤首尾空白

7. 模板引用 ref

我们可以使用ref属性访问底层DOM元素。

挂载结束后引用都会暴露在this.$refs上。

vue 复制代码
<template>
    <input type="text" ref="abc">
    <button @click="getValue">获取属性值</button>
        </template>
        
        <script>
        export default{
            data(){
                return{
                }
            },
            methods:{
                getValue(){
                    console.log(this.$refs.abc.value);
                }
            }
        }
        </script>

8. 组件基础

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构。

当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,这被叫做单文件组件(简称 SFC)。此外,我们还可以在Demo1.vue里引入其它组件形成组件嵌套。

3. 深入组件

1. 组件注册(全局和局部)

​ 一个vue组件在使用前需要先被"注册",vue在渲染模板时才能找到对应的实现。组件注册有全局注册和局部注册两种。

​ 全局注册没法移除未使用的组件。

1. 全局注册

全局注册我们可以使用 Vue 应用实例的 .component() 方法,让组件在vue当前 Vue 应用中全局可用。

./components/Demo1.vue里

vue 复制代码
<template>
<p class="Redc">{{msg}}</p>
</template>

<script>
        export default{
            data(){
                return{
                    msg:18
                }
            }
        }
</script>
<!--scoped让当前样式只在当前组件中生效-->
<style scoped>
    .Redc{
        color:red;
    }
</style>

main.js

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import Demo1 from './components/Demo1.vue'//引入

const app = createApp(App)
//下面写组件注册
app.component("Demo1",Demo1)
app.mount("#app")

App.vue

vue 复制代码
<template>
    <Demo1 /><!--在这显示-->
    </template>
    <script>
    </script>
    <!--scoped让当前样式只在当前组件中生效-->
    <style scoped>
    </style>
2. 局部注册

局部注册可以使用components显式注册。

在使用<script setup>的单文件组件中,导入的组件可以直接在模板中使用,无需注册。

main.js

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount("#app")

App.vue里

vue 复制代码
<template>
<!-- 3.显示组件-->
<Demo1/>
</template>

<script>
//1.引入组件
import Demo1 from "./components/Demo1.vue"

//2.注入组件(局部注册)
export default{
    components:{
        Demo1
    }
}
</script>
<style>
</style>
vue 复制代码
<script setup>
import Demo1 from "./components/Demo1.vue"
</script>

3. 父传子 props

我们可以用props在组件间传递数据,并且只能由父组件传到子组件,且不能直接在子组件修改父组件传来的数据。但是我们可以传递函数,让函数在子组件调用时修改父组件数据。

在传递过程中我们还可以设置props校验,判断传入数据类型,设置数据默认值,设置必选项(必须传入该数据)。

如果是数组和对象,必须通过工厂函数返回默认值。

App.vue

vue 复制代码
<template>
<!-- 3.显示组件-->
<Father />
</template>

<script setup>
import Father from "./components/Father.vue"
</script>

Father.vue 父组件

vue 复制代码
<template>
    <h3>Father</h3>
    <input style="text" v-model:="msg" />
    <Child :jkloli="cD" :title="msg" />
</template>

<script>
import Child from './Child.vue'
export default {
    data(){
        return{
            msg:"Father data"
        }
    },
    methods:{
        cD(data,e){
            this.msg=data;
        }
    },
    components:{
        Child //局部注册
    }
}
</script>

Child.vue 子组件

vue 复制代码
<template>
    <h3>Child</h3>
    <p>{{title}}</p>
    <li v-for="(j,i) in arr" :key="i">{{j}}</li>
    <input type="text" v-model="vv">
    <button @click="jkloli(vv,$event)">间接修改父组件msg</button>
  </template>
  <script>
  export default {
      data(){
          return{
                vv:""
          }
      },
      //props:["jkloli","title"]
      props:{
          jkloli:{
              type:Function,
              //数据需要满足的类型,不满足报警告
              required:true //必选项
          },
          title:{
              type:[String,Number,Array],
              default:"Child" //默认值
          },
          arr:{
              type:Array,
              default(){
                  return [1,2,3,4];
              }
          }
          
      }
  }
  </script>

4. 组件事件

在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件,实现子传父。

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
子组件传递的数据: <p>{{msg}}</p>
    <Child @someEvent="getHandle"/>
</template>

<script>
import Child from './Child.vue'
export default {
    data(){
        return{
            msg:""
        }
    },
    methods:{
        getHandle(data){//事件处理
            console.log("自定义事件someEvent触发了");
            this.msg=data;
        }
    },
    components:{
        Child //局部注册
    }
    
}
</script>

Child.vue

vue 复制代码
<template>
    <h3>Child</h3>
    <input type="text" v-model="msg">
    <button @click="adr">传递数据</button>
  </template>
  <script>
  export default {
      data(){
          return{
              msg:""
          }
      },
      methods:{//或者用侦听器实时更新数据
          adr(){
              //触发自定义事件someEvent
              this.$emit("someEvent",this.msg);
          }
      }
  }
  </script>

5. 透传attributes

"透传 attribute"指的是传递给一个组件,却没有被该组件声明为 props 或 emits的 attribute 或者 v-on 事件监听器。最常见的例子就是 classstyleid

当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。

App.vue

vue 复制代码
<template>
    <!-- 传递class给子组件Demo1-->
    <Demo1 class="a-c" />
    </template>   
    <script setup>
    import Demo1 from "./components/Demo1.vue"
    </script>

Demo1.vue

vue 复制代码
<template>
    <!--1. 必须是唯一根元素,比如有且只有一个h3-->
    <h3>透传属性</h3>
    </template>
    <script>
            export default{
                //inheritAttrs:false //禁用 Attributes 继承 
            }
    </script>
    <!--scoped让当前样式只在当前组件中生效-->
    <style scoped>
    .a-c{
        color:red;
    }
    </style>

6. 插槽 slot

1. 简介

我们可以使用插槽在子组件中渲染父组件传递的模板片段。

<slot> 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
    <Child>
        <h3>插槽内容</h3>
    </Child>
</template>

<script setup>
import Child from './Child.vue'
</script>

Child.vue

vue 复制代码
<template>
    <h3>Child</h3>
    <slot></slot>
  </template>
  <script>
  </script>
2. 渲染作用域

插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的。

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
    <Child>
        <h3>{{msg}}</h3>
    </Child>
</template>

<script>
import Child from './Child.vue'
export default{
    data(){
        return{
            msg:"666"
        }
    },
    components:{
        Child
    }
}
</script>
3. 插槽默认值
vue 复制代码
<slot>在slot里写插槽默认值</slot>
4. 具名插槽

<slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容。

v-slot,简写#,意思是将这部分的模板片段传入子组件的header插槽中。

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
    <Child>
        <template v-slot:A>
            <p>hello world</p>
		</template>
		<template #B>
            <p>xss</p>
		</template>
    </Child>
</template>

<script setup>
import Child from './Child.vue'
</script>

Child.vue

vue 复制代码
<template>
    <h3>Child</h3>
    <slot name="A">插槽A</slot>
    <hr>
    <slot name="B">插槽B</slot>
  </template>
  <script>
  </script>
5. 作用域插槽

可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes。

子组件count传给父组件,父组件将count又传给子组件显示。

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
    <Child v-slot="slotProps">
        {{slotProps.count}}
    </Child>
</template>

<script setup>
import Child from './Child.vue'
</script>

Child.vue

vue 复制代码
<template>
    <h3>Child</h3>
    <slot :count="65">插槽A</slot>
  </template>

如果是具名插槽,Father.vue可以这样写

vue 复制代码
<template>
    <h3>Father</h3>
    <Child>
        <template #A="slotProps">
			{{slotProps.count}}
		</template>   
    </Child>
</template>
<script setup>
import Child from './Child.vue'
</script>

7. 组件生命周期

每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。

通过ref获取DOM元素

APP.vue

vue 复制代码
<template>
<h3>App</h3>
<p ref="name">you get it!</p>
    </template>
    
    <script>
export default{
    beforeMount(){
        console.log(this.$refs.name);//undefined
    },
    mounted(){
        console.log(this.$refs.name);//<p>you get it!</p>
    }
}
    </script>

8. 动态组件

通过 Vue 的 <component> 元素和特殊的 is attribute 实现在两个组件间来回切换。

Demo1.vue和Demo2.vue随便写点内容。

App.vue

vue 复制代码
<template>
<h3>App</h3>
<component :is="CT"></component>
<button @click="changeHandle">切换组件</button>
</template>
    
<script>
import Demo1 from './components/Demo1.vue'
import Demo2 from './components/Demo2.vue'
export default{
    data(){
        return{
            CT:"Demo1"
        }
    },
    components:{
        Demo1,
        Demo2
    },
    methods:{
        changeHandle(){
            this.CT=this.CT=="Demo1"?"Demo2":"Demo1";
        }
    }
}
</script>

9. 组件保持存活

当使用<component :is="...">在多个组件间来回切换时,被切换掉的组件会被卸载,我们可以用<keep-alive>来使被切换掉的组件保持存活状态。比如下面的Demo1更新成新数据后,切Demo2再切回来依旧是新数据。

App.vue

vue 复制代码
<template>
<h3>App</h3>
    <keep-alive>
        <component :is="CT"></component>
    </keep-alive>
<button @click="changeHandle">切换组件</button>
</template>
    
<script>
import Demo1 from './components/Demo1.vue'
import Demo2 from './components/Demo2.vue'
export default{
    data(){
        return{
            CT:"Demo1"
        }
    },
    components:{
        Demo1,
        Demo2
    },
    methods:{
        changeHandle(){            
            this.CT=this.CT=="Demo1"?"Demo2":"Demo1";
        }
    }
}
</script>

Demo1.vue

vue 复制代码
<template>
    <h3>Demo1</h3>
    <p>msg: {{msg}}</p>
    <button @click="changeHandle">更新数据</button>
    </template>      
    <script>
    export default{
        data(){
            return{
                msg:"旧数据"
            }
        },
        methods:{
            changeHandle(){            
                this.msg="新数据";
            }
        }
    }
    </script>

10. 异步组件

​ 在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。Vue 提供了 defineAsyncComponent方法来实现此功能。

App.vue

vue 复制代码
<template>
    <h3>App</h3>
        <keep-alive>
            <component :is="CT"></component>
        </keep-alive>
    <button @click="changeHandle">切换组件</button>
    </template>
        
    <script>
    import {defineAsyncComponent} from 'vue'
    import Demo1 from './components/Demo1.vue'
    //异步加载组件
    const Demo2=defineAsyncComponent(()=>import('./components/Demo2.vue'))
    export default{
        data(){
            return{
                CT:"Demo1"
            }
        },
        components:{
            Demo1,
            Demo2
        },
        methods:{
            changeHandle(){            
                this.CT=this.CT=="Demo1"?"Demo2":"Demo1";
            }
        }
    }
    </script>

11. 依赖注入

​ 有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。此时使用props会非常麻烦(prop逐级透传),因此我们可以使用provideinject解决这一问题。

​ inject注入会在组件自身的状态之前 被解析,因此你可以在 data() 中访问到注入的属性。

App.vue

vue 复制代码
<template>
    <Father />
    </template>
    <script>
    import Father from "./components/Father.vue"
    export default{
        components:{
            Father
        },
        provide:{
            msg:"App的数据"
        }
    }
    </script>

App.vue中provide也可以读取data选项中的数据

vue 复制代码
<template>
    <Father />
    </template>
    <script>
    import Father from "./components/Father.vue"
    export default{
        data(){
            return{
                msg:"App的数据"
            }
        },
        components:{
            Father
        },
        provide(){
            return{
                msg:this.msg
            }
        }
    }
    </script>

Father.vue

vue 复制代码
<template>
    <h3>Father</h3>
    <Child />
</template>
<script setup>
import Child from './Child.vue'
</script>

Child.vue

vue 复制代码
<template>
    <h3>Child</h3>
	<p>{{msg}}</p>
</template>
<script>
export default{
      inject:["msg"]
}
</script>

此外,我们还可以在整个应用层面提供依赖

main.js

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.provide("msg","hello world")
//msg为注入名,hello world为值
app.mount("#app")

参考

Vue3从入门到精通 蔡蔡小趴菜
vue.js 文档
走进Vue【二】Vue3语法糖 忆凡_

相关推荐
长路 ㅤ   3 小时前
cherry-markdown开源markdown组件详细使用教程
vue·markdown组件
Mudrock__9 小时前
前后端传输文件(图片)
vue·.net
王小二(海阔天空)1 天前
个人文章合集 - 前端相关
前端·css·vue·jquery
osnet1 天前
showdoc二次开发
node.js·vue
前端张三3 天前
view deign 和 vue2 合并单元格的方法
vue
-心铭-3 天前
有关若依菜单管理的改造
学习·vue
Snailmi3 天前
Spring Boot+VUE《班级综合测评管理系统》
java·spring boot·后端·vue·毕业设计
潜心专研的小张同学3 天前
pnpm依赖安装失败解决|pnpm项目从一个文件夹复制到另一个文件夹运行失败问题解决-以vbenAdmin项目为例
前端·javascript·vscode·npm·vue·pnpm
夏与冰3 天前
vue3项目el-table表格行内编辑加输入框校验
vue
垂钓的小鱼14 天前
尚硅谷vue3+TypeScript笔记大全
javascript·typescript·vue