Vue3入门指南:零基础小白也能轻松理解的学习笔记

文章目录

  • 创建项目
  • 开发环境
  • 项目目录
  • 模板语法
  • 属性绑定
  • 条件渲染
  • 列表渲染
  • 事件处理
    • 内联事件处理器
    • 方法事件处理器(常用)
  • 事件参数
    • 获取 event 事件
    • 事件传参
  • 事件修饰符
    • 阻止默认事件
    • 阻止事件冒泡
  • 数组变化侦测
    • 变更方法
    • 替换一个数组
  • 计算属性
  • class 绑定
  • 单对象绑定
  • 多对象绑定
    • 绑定数组
  • Style 绑定
  • 侦听器
  • 表单输入绑定
    • 单选框
    • 复选框
    • 修饰符
  • 模板引用(操作 DOM)
  • 组件组成
    • 组成结构
    • 案例
  • 组件嵌套关系
    • Header.vue
    • Main.vue
    • Aside.vue
    • Article.vue
    • Item
  • 组件注册方式
    • 全局注册
    • 局部注册
  • 组件传递数据
    • 静态传递数据
    • 动态传递数据
  • 组件传递多种数据类型
  • 组件传递数据 Props 校验
  • 组件事件
    • 组件事件配合 V-model
    • 组件数据传递
    • 透传 Attributes
  • 插槽
    • 插槽 Slots
      • 插槽 Slots
      • 具名插槽传递数据
  • 组件的声明周期
    • 声明周期的应用
  • 动态组件
  • 组件保持存活
  • 异步组件
  • 依赖注入
  • Vue应用
  • 路由

创建项目

  • 配置 node.js > 15.0
  • 命令行创建命令 npm init vue@latest
  • cd 项目名
  • npm install
  • npm run dev
  • cnpm下载方法,更快
  • 设置 VSCode 自动保存
  • 官方教程

开发环境

  • VSCode + Volar
  • 格式化代码:Shift + Alt + F

项目目录

  • .vscode:VSCode工具的配置文件
  • node_modules:Vue项目运行的依赖文件
  • public:资源文件夹(浏览器图标)
  • src:源码文件夹
  • .gitignore:git忽略文件
  • index. html:入口HTML文件
  • package. json:信息描述文件
  • README. md:注释文件
  • vite.config.js:Vue配置文件

模板语法

<template><h3>模板语法</h3><p>{{ msg }}</p>
</template><script>
export default{data(){return {msg:"神奇的魔法"}}
}
</script>
  • 绑定仅支持单一表达式:简单算数,三目运算法,链式调用,能写在 return 后面
  • 想插 HTML,需要使用 v-html

属性绑定

<template><div v-bind:id="dynamicId" v-bind:class="dynamicClass">属性绑定</div>
</template><script>
export default{data(){return{dynamicClass:"appClass",dynamicId:"appId"}}
}
</script><style>
.appClass{color:red;font-size: 30px;
}
</style>
  • v-bind 可以简写为:
  • 动态绑定多个值
<template><div v-bind="objectOfAttrs">属性绑定</div>
</template><script>
export default{data(){return{objectOfAttrs:{class:"appclass",id:"appid"}}}
}
</script><style>
.appclass{color:red;font-size: 30px;
}
</style>

条件渲染

<template><h3>条件渲染</h3><div v-if="flag">你能看见我吗?</div><div v-else>那你还是看看我吧</div>
</template><script>
export default{data(){return{flag:false}}
}
</script>
<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-if 一样但不能配合 v-else
  • v-show 有较高初始开销,v-if 有较高切换开销

列表渲染

<template><h3>列表渲染</h3><p v-for="item in names">{{ item }}</p>
</template><script>export default{data(){return{names:["百战程序员","尚学堂","IT"]}}
}
</script>
<template><h3>列表渲染</h3><div v-for="item in result"><p>{{item.title}}</p><img v-bind:src="item.avatar" alt=""></div>
</template><script>export default {data() {return {result: [{"id": 2261677,"title": "鄂尔多斯|感受一座城市的璀璨夜景感受一座城市,除了白日里的车水马龙,喧嚣繁华","avatar": "https://pic.qyer.com/avatar/002/25/77/30/200?v=1560226451"},{"id": 2261566,"title": "成都这家洞穴暗黑风咖啡厅酷毙了!早C晚A走起\n成都天气这么热\n咖啡\n人必","avatar": "https://pic.qyer.com/avatar/011/07/08/69/200?v=1572185180"},{"id": 2261662,"title": "【川西新龙-措卡湖】措卡湖,意为“乱石丛中的黑色海水”,神秘小众原汁原味。深","avatar": "https://pic.qyer.com/avatar/009/88/48/58/200?v=1507386782"}]}}
}
</script>
  • items 可以提取出更多内容 (value,key,index)
  • in 可以用 of 来替换
  • 通过 :key=“item.id” 管理状态,保证数组变化时,不进行重新渲染

事件处理

内联事件处理器

<template><h3>内联事件处理器</h3><!-- <button v-on:click="count++">Add</button> --><button @click="count++">Add</button><p>{{count }}</p>
</template><script>
export default{data(){return{count:0}}
}
</script>

方法事件处理器(常用)

<template><h3>方法事件处理器</h3><button @click="addCount">Add</button><p>{{count }}</p>
</template><script>
export default{data(){return{count:0}},//所有的方法函数都放在这里methods:{addCount(){this.count++;console.log("点击了")}}
}
</script>

事件参数

获取 event 事件

<template><h3>Vue 中的 event 对象就是原生的 event</h3><button @click="addCount">Add</button><p>{{count }}</p>
</template><script>
export default{data(){return{count:0}},//所有的方法函数都放在这里methods:{addCount(event){this.count++;event.target.innerHTML="Add"+this.count;}}
}
</script>

事件传参

<template><h3>事件传参</h3><p @click="getNameHandle(item, $event)" v-for="(item, index) of names" :key="index">{{ item }}</p>
</template><script>
export default {data() {return {names: ["iwen", "ime", "frank"]}},//所有的方法函数都放在这里methods: {getNameHandle(name, e) {console.log(name, e);}}
}
</script>

事件修饰符

阻止默认事件

<template><h3>事件修饰符</h3><a @click.prevent="clickHandle" href="https://itbaizhan.com">百战程序员</a>
</template><script>
export default{data(){return{}},methods:{clickHandle(e){//阻止默认事件// e.preventDefault();console.log("点击了");}}
}</script>

阻止事件冒泡

<template><h3>事件修饰符</h3><div @click="clickDiv"><p @click.stop="clickP">测试冒泡</p></div>
</template><script>
export default{data(){return{}},methods:{clickDiv(){console.log("div");},clickP(){console.log("P");}}
}
</script>

数组变化侦测

变更方法

  • push
  • pop
  • shift
  • unshift
  • splice
  • sort
  • reverse

替换一个数组

  • filter
  • concat
  • slice
<template><h3>数组变化侦听</h3><button @click="addListHandle"></button> <ul><li v-for="(item,index) of names" :key="index">{{  item }}</li></ul><button @click="concatHandle">合并数组</button><h3>数组1</h3><p v-for="(item,index) of nums1" :key="index">{{ item }}</p><h3>数组 2</h3><p v-for="(item,index) of nums2" :key="index">{{ item }}</p>
</template><script>
export default{data(){return{names:["iwen","ime","frank"],nums1:[1,2,3,4,5],nums2:[6,7,8,9,10]} },methods:{addListHandle(){//会引起 UI 自动更新// this.names.push("sarra")//不会引起 UI 自动更新//this.names.concat(["sarra"])this.names = this.names.concat(["sarra"])},concatHandle(){this.nums1 = this.nums1.concat(this.nums2)}}
}
</script>

计算属性

  • 没引入计算属性,不推荐
<template><h3>{{  itbaizhan.name }}</h3><p>{{ itbaizhan.content.length>0?'Yes':'No' }}</p>
</template><script>
export default{data(){return{itbaizhan:{name:"百战程序员",content:["前端","Java","Python"]}}}
}
</script>
  • 引入计算属性
<template><h3>{{  itbaizhan.name }}</h3><p>{{ itbaizhanContent }}</p>
</template><script>
export default{data(){return{itbaizhan:{name:"百战程序员",content:["前端","Java","Python"]}}},computed:{itbaizhanContent(){return this.itbaizhan.content.length>0?'Yes':'No'}}
}
</script>
  • 计算属性会基于响应式依赖被缓存,一个计算属性仅会在响应式依赖更新时才会被重新计算
  • 方法:会在重新渲染发生时再次执行函数

class 绑定

单对象绑定

<template><p :class="{ 'active':isActive,'text-danger':hasError}">Class 样式绑定</p>
</template><script>
export default{data(){return{isActive:false}},}
</script><style>
.active{color: red;font-size: 30px;
}
</style>
<template><p :class="{ 'active':isActive,'text-danger':hasError}">Class 样式绑定</p>
</template><script>
export default{data(){return{isActive:true,hasError:true}},}
</script><style>
.active{font-size: 30px;
}.text-danger{color: red;
}
</style>

多对象绑定

<template><p :class="classObject">Class 样式绑定</p>
</template><script>
export default{data(){return{classObject:{'active':true,'text-danger':false}}},}
</script><style>
.active{font-size: 30px;
}.text-danger{color: red;
}
</style>

绑定数组

<template><p :class="[arrActive,arrHasError]">Class 样式绑定</p>
</template><script>
export default{data(){return{arrActive:"active",arrHasError:"text-danger"}},}
</script><style>
.active{font-size: 30px;
}.text-danger{color: red;
}
</style>
  • 数组可以用三目运算符
  • 数组和对象可以嵌套

Style 绑定

<template><div :style="{color:activeColor,fontSize:fontSize+'px'}">Style绑定</div>
</template><script>
export default{data(){return{activeColor:'red',fontSize:30}}
}
</script>
<template><div :style="styleObject">Style绑定</div>
</template><script>
export default{data(){return{styleObject:{color:'red',fontSize:'30px'}}}
}
</script>
  • 绑定数组(多余)

侦听器

<template><h3>侦听器</h3><p>{{ message }}</p><button @click="updateHandle">修改数据</button>
</template><script>
export default{data(){return{message:"Hello"}},methods:{updateHandle(){this.message = "World"}},watch:{message(newValue,oldValue){console.log(newValue,oldValue)}}}
</script>

表单输入绑定

单选框

<template><input type="text" v-model="message"><p>{{ message }}</p>
</template><script>
export default{data(){return{message:""}}
}
</script>

复选框

<template><input type="checkbox" id="checkbox" v-model="checked"/><label for="checkbox">{{  checked }}</label>
</template><script>
export default{data(){return{message:"",checked:false}}
}
</script>

修饰符

  • .lazy
  • .number
  • .trim
  • 失去焦点后显示:
<template><input type="text" v-model.lazy="message"><p>{{ message }}</p>
</template><script>
export default{data(){return{message:""}}
}
</script>

模板引用(操作 DOM)

  • 内容改变:{{ 模板语法 }}
  • 属性改变:v-bind:指令
  • 事件:v-on:click
  • 如果没有特别的需求不要操纵 DOM
<template><div ref="container" class="container">{{ content }}</div><button @click="getElementHandle">获取元素</button><input type="text" ref="username">
</template><script>
export default{data(){return{content:"内容"}},methods:{getElementHandle(){this.$refs.container.innerHTML = "hahaha";console.log(this.$refs.username.value)}}
}
</script>

组件组成

  • Vue 会单独定义在.Vue 中,叫单文件组件(SFL)

组成结构

  • scoped让当前样式只在当前文件中生效,局部样式
<template><div>承载标签</div>
</template><script>
export default{}
</script><style scoped>
</style>

案例

  • MyComponent.vue
<template><div class="container">{{ message }}</div>
</template><script>
export default{data(){return{message:"组件基础组成"}}
}
</script><style>
.container{font-size:'30px';color:red;
}
</style>
  • App.vue
<template><!--3 标注组件 --><MyComponent/>
</template><script>
//1 引入组件
import MyComponent from "./components/MyComponent.vue"export default{//2 注入组件components:{MyComponent}
}
</script><style></style>

组件嵌套关系

在这里插入图片描述

Header.vue

<template><h3>Header</h3>
</template><style scoped>
h3{width:100%;height: 100px;border: 5px solid #999;text-align: center;line-height: 100px;box-sizing: border-box;
}
</style>

Main.vue

<template><div class="main"><h3>Main</h3></div>
</template><script>
import Article from './Article.vue';
export default{components:{Article}
}
</script><style scoped>
.main{float: left;width: 70%;height: 400px;border: 5px solid #999;box-sizing: border-box;border-top: 0px;
}
</style>

Aside.vue

<template><div class="aside"><h3>Aside</h3><Item/><Item/><Item/></div>
</template>
<script>
import Item from './Item.vue'
export default{components:{Item}
}
</script><style scoped>
.aside{float: right;width:30%;height: 600px;border: 5px solid #999;box-sizing: border-box;border-left: 10;border-top: 10;
}
</style>

Article.vue

<template><h3>Article</h3>
</template><style scoped>
h3{width: 80%;margin:0 auto;text-align: center;line-height: 100px;box-sizing: border-box;margin-top: 50px;background: #999;
}
</style>

Item

<template><h3>Item</h3>
</template><style scoped>
h3{width:80%;margin:0 auto;text-align: center;line-height: 100px;box-sizing: border-box;margin-top: 10px;background: #999;
}
</style>

组件注册方式

全局注册

最外层注册全局都能用 Main.js 中

import { createApp } from 'vue'
import App from './App.vue'
import Header from './pages/Header.vue'const app = createApp(App)app.component("Header",Header)app.mount("#app")=

局部注册

如上节

  • 如果没用该组件,打包会带上
  • 大型项目中可维护性低

组件传递数据

  • 解决方案:props

静态传递数据

  • App.vue
<template><Parent/>
</template><script>
import Parent from './components/parent.vue'
export default{components:{Parent}
}
</script><style></style>
  • Parent.vue
<template><h3>Parent</h3><Child title="parent 数据" demo="测试"/>
</template><script>
import Child from './child.vue'
export default{data(){return{}},components:{Child}
}
</script>
  • Child.vue
<template><h3>Child</h3><p>{{ title }}</p><p>{{ demo }}</p>
</template><script>
export default{data(){return{}},props:["title","demo"]
}
</script>

动态传递数据

  • parent.vue
<template><h3>Parent</h3><Child :title="message"/>
</template><script>
import Child from './child.vue'
export default{data(){return{message:"Parent 数据!"}},components:{Child}
}
</script>
  • child.vue
<template><h3>Child</h3><p>{{ title }}</p>
</template><script>
export default{data(){return{}},props:["title"]
}
</script>
  • props 传递数据只能父级传递给子级,不能相反

组件传递多种数据类型

  • 任何类型
  • parent.vue
<template><h3>Parent</h3><Child :title="message" :age="age" :names="names" :userInfo="userInfo"/>
</template><script>
import Child from './child.vue'
export default{data(){return{message:"Parent 数据!",age:10,names:["iwen","jixiyu"],userInfo:{name:"iwen",age:20}}},components:{Child}
}
</script>
  • child.vue
<template><h3>Child</h3><p>{{ title }}</p><p>{{  age }}</p><ul><li v-for="(item,index) of names" :key="index">{{ item }}</li></ul><p>{{ userInfo.name }}</p><p>{{ userInfo.age }}</p>
</template><script>
export default{data(){return{}},props:["title","age","names","userInfo"]
}
</script>

组件传递数据 Props 校验

  • 默认值,类型校验,必选项
  • Props 传递来的数据是只读的
<template><h3>ComponentA</h3><ComponentB :title="title" :names="names"/>
</template><script>
import ComponentB from "./ComponentB.vue"
export default{data(){return{title:"title",names:["awin","jiangxiyu"]}},components:{ComponentB}
}
</script>

组件事件

  • 子元素数据传递给父级数据 this.$emit
  • 父级数据传递给子数据 props
  • Child.vue
<template><h3>Child</h3><button @click="clickEventHandle">传递数据</button>
</template><script>
export default{data(){return{msg:"Child 数据!"}},methods:{clickEventHandle(){this.$emit("someEvent",this.msg)}}
}
</script>
  • ComponentEvent.vue
<template><h3>组件事件</h3><Child @someEvent="getHandle"></Child><p>父元素:{{ message }}</p>
</template>
<script>
import Child from './child.vue'
export default{data(){return {message:""} },components:{Child},methods:{getHandle(data){this.message = data;}}
}
</script>

组件事件配合 V-model

  • 子组件不断发送数据给父组件,并且实时展示
  • SearComponent.vue
<template>搜索:<input type="text" v-model="search">
</template><script>
export default{data(){return{search:""}},watch:{search(newValue,oldValue){this.$emit("searchEvent",newValue)}}
}
</script>
  • Main.vue
<template><h3>Main</h3><p>搜索内容为:{{ search }}</p><SearchCompoent @searchEvent="getSearch"/>
</template><script>
import SearchCompoent from './SearchCompoent.vue';
export default{components:{SearchCompoent},data(){return{search:""}},  methods:{getSearch(data){this.search = data;}}
}
</script>

组件数据传递

  • props 额外操作方式子传父,函数回调
  • ComponentA.vue
<template><h3>ComponentA</h3><p>父元素:{{ message }}</p><ComponentB title="标题" :onEvent="dataFn"/>
</template><script>
import ComponentB from './ComponentB.vue'
export default{data(){return {message:""}},components:{ComponentB,},methods:{dataFn(data){this.message = data}}
}
</script>
  • ComponentB.vue
<template><h3>ComponentB</h3><p>{{ title }}</p><p>{{  onEvent('传递数据') }}</p>
</template><script>
export default{data(){return {}},props:{title:String,onEvent:Function}
}
</script>

透传 Attributes

  • 使用率低,了解
  • “透传attribute"指的是传递给一个组件却没有被该组件声为props或emits的attribute或者 v-on事件
    监听器。最常见的例子就是class、style和id
  • 当一个组件以单个元素为根作渲染时,透传的attribute会自动被添加到根元素上
  • 父组件
<template><AttrComponents class="attr-containder"/>
</template><script>
import AttrComponents from './components/AttrComponents.vue'export default{components:{AttrComponents}
}
</script><style></style>
  • 子组件
<template><!-- 透传属性必须唯一根元素 --><h3>透传属性</h3>
</template><script>
export default{inheritAttrs:false
}
</script><style>
.attr-containder{color:red
}
</style>

插槽

  • 传递模板,子组件渲染
  • slot 插槽出口
  • App.vue
    在这里插入图片描述
<template><SlotsBase><div><h3>插槽标题</h3><p>插槽内容</p></div></SlotsBase>
</template><script>
import SlotsBase from './components/SlotsBase.vue'
export default{components:{SlotsBase}
}
</script><style></style>
  • SlotsBase.vue
<template><slot></slot><h3>插槽基础知识</h3>
</template>

插槽 Slots

  • 插槽中的数据应该在父元素内容
  • 插槽默认值,在 slot 中直接写
  • 具名插槽
    • v-slot间写为#
  • App.vue
<template><SlotsTow><template v-slot:header><h3>{{ message }}</h3></template><template v-slot:main><p>内容</p></template></SlotsTow>
</template><script>
import SlotsTow from './components/SlotsTow.vue'
export default{components:{SlotsTow},data(){return{message:"插槽内容续集"}}
}
</script><style></style>
  • SlotsTow.vue
<template><h3>Slots插槽续集</h3><slot name="header">插槽默认值</slot><hr><slot name="main">插槽默认值</slot>
</template>

插槽 Slots

  • 子元素数据传给父插槽

在这里插入图片描述

<template><SlotsAttr v-slot="slotProps"><h3>{{  currentTest }} - {{  slotProps.msg }}</h3></SlotsAttr>
</template><script>
import SlotsAttr from './components/SlotsAttr.vue'
export default{data(){return{currentTest:"测试内容"}},components:{SlotsAttr}
}
</script><style></style>
<template><h3>Slots 再续集</h3><slot :msg="childMessage"></slot>
</template><script>
export default{data(){return{childMessage:"子组件数据"}}
}
</script>

具名插槽传递数据

在这里插入图片描述

<template><SlotsAttr><template #header="slotProps"><h3>{{ currentTest }}-{{ slotProps.msg }}</h3></template><template #main="slotProps"><p>{{ slotProps.job }}</p></template></SlotsAttr>
</template><script>
import SlotsAttr from './components/SlotsAttr.vue'
export default{data(){return{currentTest:"测试内容"}},components:{SlotsAttr}
}
</script><style></style>
<template><h3>Slots 再续集</h3><slot name="header" :msg="childMessage"></slot><slot name="main" :job="jobMessage"></slot>
</template><script>
export default{data(){return{childMessage:"子组件数据",jobMessage:"itbaizhan"}}
}
</script>

组件的声明周期

在这里插入图片描述

  • 创建:创建后系统才开始初始化数据
  • 渲染:显示
  • 更新:用户操作导致改变,渲染和显示
  • 销毁
<template><h3>组件的声明周期</h3><p>{{ message }}</p><button @click="updateHandle"></button>
</template><script>
export default{methods:{updateHandle(){this.message = "更新之后"}},data(){return{message:"更新之前"}},beforeCreate(){console.log("组件创建之前")},created(){console.log("组件创建之后")},beforeMount(){console.log("组件渲染之前")},mounted(){console.log("组件渲染之后")},beforeUpdate(){console.log("组件更新之前")},updated(){console.log("组件更新之后")},beforeUnmount(){console.log("组件销毁之前")},unmounted(){console.log("组件销毁之后")}
}
</script>
<style></style>

声明周期的应用

  • 模拟网络请求渲染数据
  • 通过 ref 获取 dom 结构
<template><UserComponent/>
</template><script>
import UserComponent from './components/UserComponent.vue'
export default{components:{UserComponent}
}
</script>
<style></style>
<template><h3>组件声明周期函数应用</h3><p ref="name">百战程序员</p></template><script>export default{beforeMount(){console.log(this.$refs.name);},mounted(){console.log(this.$refs.name)}}</script><style></style>
  • 读取 HTML 的过程放到页面渲染之后
  • 并且在渲染页面后再渲染数据
<template><h3>组件声明周期函数应用</h3><p ref="name">百战程序员</p><ul><li v-for="(item, index) of banner" :key ="index"><h3>{{ item.title }}</h3><p>{{ item.content }}</p></li></ul>
</template><script>
export default {data() {return {banner: []}},mounted() {//网络请求this.banner = [{"title": "我在爱尔兰","content": "爱尔兰(爱尔兰语: Poblacht na hEireann;英语: Republic of Ireland),是一个..."},{"title": "一个人的东京","content": "东京(Tokyo)是日本国的首都,是亚洲第一大城市,世界第二大城市。全球最的经济中心..."},{"title": "普罗旺斯的梦","content": "普罗旺斯(Provence)位于法国东南部,毗邻地中海和意大利,从地中海沿岸延伸到内陆..."}]},
}
</script>
<style></style>

动态组件

<template><ComponentA/><ComponentB/><component :is="tabComponent"></component><button @click="changeHandle">切换组件</button>
</template><script>
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'
export default{data(){return{tabComponent: "ComponentA"}},components:{ComponentA,ComponentB},methods:{changeHandle(){this.tabComponent = this.tabComponent == "ComponentA"?"ComponentB":"ComponentA"}}
}
</script>
<style></style>

组件保持存活

  • 切换时会卸载组件
<template><KeepAlive><component :is="tabComponent"></component></KeepAlive><button @click="changeHandle">切换组件</button>
</template><script>
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'
export default{data(){return{tabComponent: "ComponentA"}},components:{ComponentA,ComponentB},methods:{changeHandle(){this.tabComponent = this.tabComponent == "ComponentA"?"ComponentB":"ComponentA"}}
}
</script>
<style></style>
<template><h3>ComponentA</h3><p>{{ message }}</p><button @click="updateHandle">更新数据</button>
</template><script>
export default{beforeUnmount(){console.log("组件卸载前")},unmounted(){console.log("组件卸载后")},data(){return{message:"老数据"}},methods:{updateHandle(){this.message = "新数据"}}
}
</script>
<template><h3>ComponentB</h3>
</template>

异步组件

  • 在第一次进入网页时,没显示出来的网页先不加载,等显示出来后再加载
<template><KeepAlive><component :is="tabComponent"></component></KeepAlive><button @click="changeHandle">切换组件</button>
</template><script>
import { defineAsyncComponent } from 'vue'
import ComponentA from './components/ComponentA.vue'
// import ComponentB from './components/ComponentB.vue'
const ComponentB = defineAsyncComponent(()=>import("./components/ComponentB.vue")
)
export default{data(){return{tabComponent: "ComponentA"}},components:{ComponentA,ComponentB},methods:{changeHandle(){this.tabComponent = this.tabComponent == "ComponentA"?"ComponentB":"ComponentA"}}
}
</script>
<style></style>

依赖注入

  • 父组件作为依赖提供者,无论孩子有多深,都能用依赖获取数据。
  • provide 和 inject
  • 只能由上到下,不能反向
  • 可以在整个应用提供
    在这里插入图片描述
  • 爷爷
<template><h3>祖宗</h3><Father />
</template><script>
import Father from './components/Father.vue'
export default{// provide:{//   message:"爷爷的财产"// },data(){return{message:"爷爷的财产"}},provide(){return{message:this.message}},components:{Father}
}
</script>
<style></style>
  • 父亲
<template><h3>父亲</h3><Son /></template><script>import Son from './Son.vue'export default{props:{title:{type:String}},components:{Son}}</script>
  • 孙子
<template><h3>孩子</h3><p>{{ fullMessage }}</p></template><script>export default{props:{title:{type:String}},inject:["message"],data(){return{fullMessage:this.message}}}</script>
  • 全局数据
import { createApp } from 'vue'
import App from './App.vue'const app = createApp(App)
app.provide("golabData","我是全局数据")
app.mount("#app")

Vue应用

  • src/assets:资源文件夹
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><link rel="icon" href="/favicon.ico"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vite App</title></head><body><div id="app"></div><script type="module" src="/src/main.js"></script></body>
</html>
import { createApp } from 'vue'
import App from './App.vue'const app = createApp(App)app.mount("#app")

路由

  • cnpm install --save vue-router@4
  • App.vue
<template><router-link to="/home">首页</router-link><router-link to="/blog">博客</router-link><router-view></router-view>
</template><script>
export default{name:'App'
}
</script>
<style></style>
  • router.js
import {createRouter,createWebHashHistory} from "vue-router"
import Home from "./components/Home.vue"
import Blog from "./components/Blog.vue"
const router = createRouter({history:  createWebHashHistory(),routes:[{path:"/home",component:Home},{path:"/blog",component:Blog}]
})export default router;
  • main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router.js'const app = createApp(App)
app.use(router);
app.mount("#app")
  • Home.vue,Blog.vue 略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/129033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

野火霸天虎 STM32F407 学习笔记_1 stm32介绍;调试方法介绍

STM32入门——基于野火 F407 霸天虎课程学习 前言 博主开始探索嵌入式以来&#xff0c;其实很早就开始玩 stm32 了。但是学了一段时间之后总是感觉还是很没有头绪&#xff0c;不知道在学什么。前前后后分别尝试了江协科技、正点原子、野火霸天虎三次 stm32 的课程学习。江协科…

多模态 多引擎 超融合 新生态!2023亚信科技AntDB数据库8.0产品发布

9月20日&#xff0c;以“多模态 多引擎 超融合 新生态”为主题的亚信科技AntDB数据库8.0产品发布会成功举办&#xff0c;从技术和生态两个角度全方位展示了AntDB数据库第8次大型能力升级和生态建设成果。浙江移动、用友、麒麟软件、华录高诚、金云智联等行业伙伴及业界专家共同…

如何做好网页配色,分享一些配色方案和方法

很多网页设计师在选择网页配色方案时&#xff0c;会纠结于用什么网页UI配色方案来吸引客户的注意力&#xff0c;传达信息。选择正确的颜色是网页设计不可或缺的一部分。本指南将从色彩理论和色彩心理学入手&#xff0c;分享三个网页UI配色的简单步骤。 网页UI配色方法有很多&a…

关于msvcp120.dll丢失的解决方法详解,快速解决dll丢失问题

在计算机使用过程中&#xff0c;经常会遇到“msvcp120.dll丢失”的错误提示。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;造成相关应用程序可能无法正常启动或运行。那么&#xff0c;究竟是什么原因导致了msvcp120.dll文件的丢失呢&#xff1f;本文将详细解析msvc…

在 Linux 中更改 echo 的输出颜色

文章目录 前言一、快速入门二、基本使用2.1 对于常规的输出2.2 对于字体加粗的输出2.3 对于字体斜体的输出2.4 对于带下划线的输出2.5 对于闪烁效果的输出 三、小结 前言 在计算机编程世界中&#xff0c;颜色不仅仅是一种视觉效果&#xff0c;它也是一种信息传递的工具。特别是…

Doris:StreamLoad导入数据

目录 1.基本原理 2.支持数据格式 3.StreamLoad语法 3.1.请求参数 3.2.返回参数 4.StreamLoad实践 4.1.使用 curl命令 4.2.使用Java代码 Stream load 是一个同步的导入方式&#xff0c;用户通过发送 HTTP 协议发送请求将本地文件或数据流导入到 Doris 中。Stream load 主…

免费记课时小程序-全优学堂

1. 教师使用小程序记上课 使用步骤 创建了员工账号&#xff0c;员工需设置为教师为班级进行排课使用系统账号绑定小程序&#xff0c;记上课 #1.1 创建员工账号 通过系统菜单’机构设置->员工管理‘&#xff0c;添加本机构教师及其他员工。 添加过程中&#xff0c;可设置…

ffmpeg mp3截取命令,视频与mp3合成带音频视频命令

从00:00:03.500开始截取往后长度到结尾的mp3音频&#xff08;这个更有用&#xff0c;测试好用&#xff09; ffmpeg -i d:/c.mp3 -ss 00:00:03.500 d:/output.mp3 将两个音频合并成一个音频&#xff08;测试好用&#xff09; ffmpeg -i "concat:d:/c.mp3|d:/output.mp3&…

CSS3设计动画样式

CSS3动画包括过渡动画和关键帧动画&#xff0c;它们主要通过改变CSS属性值来模拟实现。我将详细介绍Transform、Transitions和Animations 3大功能模块&#xff0c;其中Transform实现对网页对象的变形操作&#xff0c;Transitions实现CSS属性过渡变化&#xff0c;Animations实现…

Git复制代码

目录 一、常用下载代码 1.登录Git克隆SSH​编辑 2.新建文件然后右键点击Git Bash Here 3.git clone Paste 二. 本地下载 1.从本地进入页面 2.生成代码——>导入——>生成代码后下载 3.解压道相应位置 一、常用下载代码 1.登录Git克隆SSH 2.新建文件然后右键点击…

C# list<T>去重

文章目录 C# list<T>去重值类型去重List<object>object is intobject is decimalobject is charobject is boolobject is string List<int>List<string> 引用类型去重 C# list去重 值类型去重 List object is int //object is intList<object&g…

图像二值化阈值调整——cv2.threshold方法

二值化阈值调整&#xff1a;调整是指在进行图像二值化处理时&#xff0c;调整阈值的过程。阈值决定了将图像中的像素分为黑色和白色的界限&#xff0c;大于阈值的像素被设置为白色&#xff0c;小于等于阈值的像素被设置为黑色。 首先画出灰度直方图&#xff1a;横坐标是灰度值…

制造行业数字化运维破局之道

项目背景 某大型汽车制造集团&#xff0c;致力于通过数字化、智能化运营手段为用户提升提供高品质的汽车产品和服务。IT部门不仅为内外部持续提供服务&#xff0c;同时为业务运营与核心系统运行提供重要支撑。数字化运维作为数字化转型的核心基础&#xff0c;不但要保障数据安…

3D网页游戏外包开发引擎

3D网页开发引擎是用于创建具有三维图形、虚拟现实和交互性的网页应用程序的工具。以下是一些常用的3D网页开发引擎以及它们的主要特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Three.js&…

使用 Curl 和 DomCrawler 下载抖音视频链接并存储到指定文件夹

项目需求 假设我们需要从抖音平台上下载一些特定的视频&#xff0c;以便进行分析、编辑或其他用途。为了实现这个目标&#xff0c;我们需要编写一个爬虫程序来获取抖音视频的链接&#xff0c;并将其保存到本地文件夹中。 目标分析 在开始编写爬虫之前&#xff0c;我们需要了…

Redis Twemproxy 集群,水平扩展 ,扩容方案

文章目录 一、概述二、Twemproxy 分布模式三、测试规划四、Redis 服务实例准备4.1 配置Redis实例4.2 创建关资源4.3 启动Redis服务实例 五、Twemproxy 安装准备六、Twemproxy 安装及集群配置6.1 安装 Twemproxy6.2 配置 Twemproxy6.3 启动 twemproxy6.4 测试 twemproxy 集群 如…

如何使用 NFTScan NFT API 在 Polygon 网络上开发 Web3 应用

Polygon 以前被称为 Matic Network&#xff0c;是一种扩展的解决方案&#xff0c;它提供多种工具来加快并降低区块链网络上交易的成本和复杂性。然而&#xff0c;其区块链上的大量活动使以太坊因增长的传输成本和拥挤的流量几乎瘫痪。Polygon 诞生的主要目的是帮助以太坊解决链…

Docker学习——①

文章目录 1、什么是虚拟化、容器化&#xff1f;2、为什么要虚拟化、容器化&#xff1f;3、虚拟化实现方式3.1 应用程序执行环境分层3.2 虚拟化常见类别3.3 常见虚拟化实现3.3.1 主机虚拟化(虚拟机)实现3.3.2 容器虚拟化实现3.3.3 空间隔离实战--基础知识3.3.4 PID 隔离3.3.5 Mo…

springboot+vue基于Hadoop短视频流量数据分析与可视化系统的设计与实现【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

HarmonyOS(二)—— 初识ArkTS开发语言(中)之ArkTS的由来和演进

前言 在上一篇文章HarmonyOS&#xff08;二&#xff09;—— 初识ArkTS开发语言&#xff08;上&#xff09;之TypeScript入门&#xff0c;我初识了TypeScript相关知识点&#xff0c;也知道ArkTS是华为基于TypeScript发展演化而来。 从最初的基础的逻辑交互能力&#xff0c;到…