“关于“拓源纯净主题”引发的Undefined array key "pro" 的修复” 的相关文章
VUE3快速入门(2)——自定义组件
本文介绍了VUE组件的基本使用,包括定义组件、导出组件、引入组件、使用组件的基本过程,尤其是特别提示了组合式API与选项式API交互的问题。 1. 准备工作 用VSCode打开上节课“VUE3快速入门(1)——搭建开发环境”的文件夹。在VSCode选择“终端”、“新建终端”,准备用命令行执行npm相关指令。打开/src/app.vue文件,删除掉顶部代码 import TheWelcome from ‘./components/TheWelcome.vue’ 同时删除约17行的<TheWelcome />的标签,该步骤是为了删除对TheWelcome组件的引用,稍后将替换成自己编写的组件。 2. 新建一个组件2.1 新建文件在/src/components目录下新建一个文件:MyComp.vue 2.2 添加组件模板代码模板代码用于描述模板架构,由H5标签组成。模板代码写在<template>标签内,Vue2版本要求必须被<div>标签包裹,Vue3则无此要求。 <template> <h1>门禁管理系统</h1> <h2>作者:{{ author }},联系邮箱:{{ mail }},电话:{{ tel }}</h2> </template> 2.2 添加组件控制代码控制代码用于描述控制逻辑,实现相关功能。整体结构是一个被导出的类。在Vue3中,内部数据、方法、计算属性、传入属性等均写在setup方法内,目前先使用内部数据。 <script lang="ts"> export default { //组件名称 name: "MyComp", //组合式API setup() { let author = "Jesse"; let mail = "3898xxxx@qq.com"; let tel = "136****615"; //返回外部需要的数据 return {author, mail, tel}; //上述代码返回的是一个键值对,当key=value时,可省略其中一个。否则需要写成key: value的形式,则外部需要通过key获取值:{{key}} } } </script> 2.3 添加组件样式代码控制代码用于描述组件外观,如字号、字体等,由css代码组成。样式代码写在<style>标签内。 <style scoped> font-size: 16px; </style> style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,通过该属性,可以使得组件之间的样式不互相污染。 3. 调用该组件3.1 引入组件在App.vue中的<script>标签内,增加语句: import MyComp from './components/MyComp.vue'; 3.2 使用组件在App.vue的<template>标签内,像使用H5标签那样,直接在期望展示的位置或者直接在刚才删掉<TheWelcome>处写上 <MyComp></MyComp> 即可。或简写为 <MyComp/> 4. 执行npm能热更新。当编译、构建完成无误后,页面将出现“作者:Jesse,联系邮箱:3898xxxx@qq.com,电话:136****615”的字样 5. 总结 组件分为<template>、<script>、<style>三个部分。<template>定义组件的骨架,<script>定义组件的业务逻辑,<style>定义样式。Vue2下<template>内的所有标签必须被<div>标签包裹,Vue3无此要求。export default用于导出该组件以便复用,其本质上是导出了一个类。如果做过C#、MFC的传统桌面端的开发,可以将组件理解为控件。Vue3下,外部需要的数据(包括内部数据、计算属性、方法等)均写在setup内,且通过return返回。使用组件需要先import引入,最后像使用H5标签一样调用该组件。建议所有组件样式都加上scoped属性,避免污染其他组件样式。 6. 特别提示 setup方法内不允许用this关键字。Vue2的data、methods等可以用this,且可以通过该关键字获取setup里的内容,但setup不能反过来获取data、methods等里面的内容。不要Vue2/3混用,即Vue3不要再用选项式API。 7. 拓展学习与思考 使用组件有什么好处?从创建组件到使用组件的步骤是什么样的?选项式API与组合式API有什么区别?...
VUE3快速入门(4)——Setup语法糖与数据绑定
本文讲述了如何使用Setup语法糖简化代码,以及如何获取表单数据。在本系列后续的文章中,均使用setup语法糖写法。 1. Setup语法糖使用Setup导出数据或者方法必须使用return,当代码过多时就变得复杂。使用Setup语法糖无需显式声明要导出的内容,也不必再写setup方法名。 1.1 声明组件导出首先将<script>代码中的setup方法部分全部移除,仅留下组件导出声明: <script lang="ts"> export default { name: "MyComp", } 1.2 创建setup语法糖其次,新增一个<script>片段,如下: <script lang="ts" setup> </script> 注意: lang属性对应的语言必须与上一个<script>的代码语言一致,不得JS、TS混用;setup语法糖所在的<script>必须增加一个setup属性 1.3 在setup语法糖标签内写代码最后将原本setup方法里面的内容除了return外全部放入后一个<script>标签内,完整代码如下: <script lang="ts" setup> let author = "Jesse"; let mail = "3898xxxx@qq.com"; let tel = "136****615"; function add(a: number, b: number): number{ return a + b; } function show(content: any): any { alert(content); } //无需return {author, mail, ...} </script> 这样,凡是在setup语法糖内定义的数据和方法全部自动导出,不用再return。 2. 数据绑定数据绑定是指获取表单中填写的值。 2.1 创建一个表单在合适位置增加一个表单标签: <input name=””/> 2.2 创建变量并绑定表单的值创建一个变量,用于接收表单的值: let input_content = "" 在表单标签内使用v-model指令将表单值与该变量绑定: <input name="" v-model="input_content"/> 2.3 测试修改button的click事件,单击时弹出表单的值: <button @click="show(input_content)">单击</button> 其中show方法代码: function show(content: any): any { alert(content); } 3. 总结 使用setup语法糖就无需再显式声明导出的内容,但要求两个<script>片段语言类型一致;v-model指令用于将表单值与变量绑定;v-model指令仅能用于表单相关的标签。...
VUE3快速入门(6)——计算属性
本节讲述了Vue3的计算属性的用法。 1. 什么是计算属性计算属性用于对一些需要展示到模板上的数据进行处理,虽然用函数也能实现,但计算属性会自动缓存,只有值发生变化时才重新计算,加快运行效率。 2. 基本使用方法本节实现一个功能,将输入的电话号码隐去中间四位。 2.1 引用computedimport { computed } from 'vue'; 2.2 使用computed方法定义一个计算属性let encoded_tel = computed(() => { let part_1 = worker.value.tel.substring(0, 3); let part_2 = worker.value.tel.slice(-4); return part_1 + "****" + part_2; }); 其中worker是由ref定义的响应式数据,通过输入框修改电话号码并实时显示的方法参考上一节:VUE3快速入门(5)——响应式数据。 2.3 在模板中使用将上一节的模板变量改为: <h2>电话号码: {{ encoded_tel }}</h2> 这样,当输入电话号码并点击“修改”后,号码将隐去中间四位。 3. 计算属性的读写性如果要通过代码修改计算属性的值,则: function changeComputed() { encoded_tel.value = "..."; } 3.1 只读第二节定义计算属性的方式属于只读属性,采用上述方法修改计算属性的值会报错。 3.2 可读可写要修改计算属性的值,必须定义getter和setter: let encoded_tel = computed(() => { get(){ let part_1 = worker.value.tel.substring(0, 3); let part_2 = worker.value.tel.slice(-4); return part_1 + "****" + part_2; }, set(val){ //针对val的逻辑处理代码 } }); 4. 总结 计算属性与函数类似,但计算属性有缓存,如多次调用其值不变,则仅计算一次;计算属性如果要通过代码修改值,则必须定义getter和setter;对计算属性的value字段赋值,仅仅触发setter的调用,实际上并没有修改任何值,还需要在setter里面编写逻辑处理代码!...
VUE3快速入门(8)——属性
本文讲述了组件属性的实现方法,以及如何限制属性的数据类型。 1. 什么是组件的属性组件的属性是指可以由组件的调用者动态设置的参数,组件在运行时根据这些参数展现调用者需要的数据。组件的属性等同于HTML标签的属性。 2. 最简单的一个属性本节实现一个展现员工信息的列表,第一步先传入一个“department”属性用于显示员工所属的部门。 2.1 属性的定义定义属性: import { defineProps } from "vue";//引入defineProps,该函数属于宏函数,实际无需引入 let props = defineProps(["department"]);//声明department为一个属性 defineProps方法传入一个字符串数组,其内容是将要被设为属性的变量名称。该方法同时返回一个对象,该对象由传入该组件所有属性的名称和值组成。 模板部分: <template> <p>所属部门: {{ department }}</p> </template> 2.2 使用组件并设置属性<WorkerTable department="宣传科"></WorkerTable> 3. 强制类型限定接下来新增一个属性:data,该属性是描述员工信息的数组,用于表格展示。其中模板部分如下: <template> <h1>所属部门:{{ department }}</h1> <table id="main"> <thead> <tr> <th scope="col">员工号码</th> <th scope="col">姓名</th> <th scope="col">性别</th> <th scope="col">电话</th> </tr> </thead> <tbody> <tr v-for=" (item, index) in data" :key="item.id"> <th scope="col">{{ item.id }}</th> <td scope="col">{{ item.name }}</td> <td scope="col">{{ item.sex ? '男' : '女' }}</td> <td scope="col">{{ item.tel }}</td> </tr> </tbody> </table> </template> 根据模板的展示需求,员工信息需要包括ID、姓名、性别、电话等字段,如果上级组件传入的属性数据不符合员工字段的要求,则组件会出现显示异常。为避免这样的问题,需要检查属性数据的类型,当类型不符合要求时,禁止上级组件的属性赋值。 3.1 定义新类型利用TS的接口类,定义一个员工数据类型,并导出:(建议新建一个名为WorkerTable的文件夹,该文件夹包含一个子文件夹src,用于存放组件的辅助代码,而组件的入口文件则与src同级) //file:@/component/WorkerTable/src/IWorker.ts export interface IWorker{ // 序列号 id: number, // 姓名 name: string, // 性别 sex: boolean, // 电话(可选) tel?: string } export type IWorkerArray = IWorker[]; 该文件定义了一个员工类:IWorker以及它的数组类型:IWorkerArray。 3.2 类型检查修改组件TS代码: import { type IWorkerArray } from "@/components/WorkerTable/src/IWorker"; defineProps<{department: string, data: IWorkerArray}>();//通过泛型进行类型检查并声明属性 上述代码有两个注意点: 引入类型需要使用type关键字通过泛型的方式进行类型检查时,所有属性均需进行类型检查(要么所有,要么都不) 3.3 属性赋值最后调用该组件的TS部分: import WorkerTable from '@/components/WorkerTable/WorkeTable.vue'; import { ref } from "vue"; let workers = ref([ {id: 1234, sex: true, name: "张三", tel: "13600000000"}, {id: 1235, sex: false, name: "李四", tel: "13600000001"}, {id: 1235, sex: false, name: "王五", tel: "13600000002"}, {id: 1234, sex: false, name: "赵六"} ]); 也可以向ref(reactive)传递泛型,在此处限定workers的类型: import { type IWorkerArray } from '@/components/WorkerTable/src/IWorker'; import { ref } from "vue"; let workers = ref<IWorkerArray>(...); 但由于WorkerTable组件已经进行了类型检查,因此上述代码的写法似乎没必要。 模板部分: <WorkerTable department="办公室" :data="workers"></WorkerTable> 注意: 当传入的属性不符合类型要求时,代码将无法运行,避免显示异常。属性的“:”表示后面的内容作为表达式解析,如果不加“:”,则将会把“worker...
VUE3快速入门(9)——插槽
插槽可以实现组件的样式由调用者决定的功能。本文讲述了默认插槽、具名插槽以及作用域插槽的三种使用方式。 1. 什么是插槽插槽是指组件的部分或全部HTML样式由调用者决定,即动态的Template。例如组件的列表有可能是无序列表、有序列表或图片列表,无法在设计组件时指定,在这种情况下需要使用插槽。 2. 默认插槽默认插槽类似HTML的嵌套标签。本节在上一节的基础上对员工列表组件进行改造(WorkerTableEx),上一节组件的列表标题使用了<h1>标签,但调用者可能希望行换成其他的形式,这里使用默认插槽实现。 组件代码如下: <template> <slot></slot><!-- 使用默认插槽形成占位符 --> <table id="main"> <!-- 表格部分省略 --> </table> </template> 则调用该组件的代码为: <WorkerTableEx><h2>部门:办公室</h2></WorkerTableEx> <WorkerTableEx><p>部门:办公室</p></WorkerTableEx> <WorkerTableEx><img src="..."/></WorkerTableEx> 这样,表格的标题展示形式由调用者决定,它可以是头部标题、段落或者图片以及其他。 通过在<template>中使用<slot></slot>形成占位符,当调用者在组件标签中插入HTML片段或另一个组件时,VUE将会把插入的内容放到占位符中(有几个占位符就放几个)。 3. 具名插槽有时希望多个占位符展示的内容不一样,这种情况需要使用具名插槽。假如要求表格底部可以显示备注信息,这就需要与展示标题的插槽区分开来: <template> <slot name="title"></slot><!-- 使用具名插槽,标题显示部分 --> <table id="main"> <!-- 表格部分代码省略 --> </table> <slot name="description"></slot><!-- 使用具名插槽,备注显示部分 --> </template> 则调用该组件的代码为: <WorkerTableEx> <template v-slot:title><!-- 使用v-slot指令 --> <h3>部门:办公室</h3> </template> <template #description><!-- v-slot语法糖 --> <p>导出时间:2024年6月26日</p> </template> </WorkerTableEx> 提示: 使用v-slot指令可以指明内容放在组件的哪个插槽内,同时v-slot指令可以简写为“#”。v-slot指令只能用在<template>标签和组件标签上,不能用在HTML标签上,因此使用具名插槽必须把普通HTML代码用<template>标签包裹。由于使用了具名插槽,因此组件展示的内容顺序与调用者的编码顺序无关。 4. 作用域插槽有时会有这样的需求:数据由组件生成(如请求服务器得到后端数据),但展示形式却由调用者决定,这种情况需要使用作用域插槽。作用域插槽常见于UI框架。 继续改造WorkerTableEx组件,其中该组件仅提供数据(员工、部门及导出时间)以及头部、正文和注脚三个具名插槽: let ajax_data = ref( { workers: [ {id: 1234, sex: true, name: "张三", tel: "13600000000"}, {id: 1235, sex: false, name: "李四", tel: "13600000001"}, {id: 1235, sex: false, name: "王五", tel: "13600000002"}, {id: 1234, sex: false, name: "赵六"} ], department: "技术部", exp_t: "2024年6月27日20:22:37" });//实际开发从应从服务器获取 组件的模板部分: <template> <slot :title="ajax_data.title" name="header"></slot> <slot :workers="ajax_data.workers" name="content"></slot> <slot :exp_t="ajax_data.exp_t" name="footer"></slot> </template> 上述代码使用了具名作用域插槽,将ajax_data的title、workers和exp_t属性分别绑定到三个不同的具名插槽。 则调用者的代码为: <WorkerTableEx> <template #header="parame"> <h3>部门:{{ parame.title }}</h3> </template> <template #footer="parame"> <p>导出时间:{{ parame.exp_t }}</p> </template> <template #content="parame"> <table id="main"> <thead> <tr> <th scope="col">员工号码</th>...