网站做子域名,长沙是什么时候建立的,移动应用开发实训报告,电脑网站制作教程Vue3选项式风格-基础部分篇 简介模板语法文本插值原始HTMLAttribute 绑定使用 JavaScript 表达式调用函数全局组件调用内置指令动态参数注意事项 data()data()深度响应 methods有状态的methods(防抖) DOM更新时机计算属性class和style绑定条件渲染列表渲染数组变换侦听事件处理… Vue3选项式风格-基础部分篇 简介模板语法文本插值原始HTMLAttribute 绑定使用 JavaScript 表达式调用函数全局组件调用内置指令动态参数注意事项 data()data()深度响应 methods有状态的methods(防抖) DOM更新时机计算属性class和style绑定条件渲染列表渲染数组变换侦听事件处理表单输入绑定生命周期钩子侦听器watch模板引用ref组件基础组件注册项目文件结构RootApp.vuemain.jsChildApp.vueChildApp1.vueChildApp2.vue其他注意事项 简介
本篇知识点主要来自Vue官网是对基础部分知识的学习总结适用于对vue稍微了解的人群可以更加规范的使用Vue相关语法本次代码是脚手架搭建后修改根组件后的代码具体内容看最后的截图最后会附上修改和编辑后文件的全部代码。
模板语法
我们先对一个SFC(单文件组件)的组成部分做一个了解。
template!-- 组件模板内容 --
/template
scriptexport default(){//当前组件实例}
/script
style组件模板样式
/style文本插值
template!-- 1.双花括号语法里面是javascript表达式组件的data数据发生变化时也会动态改变 --h1{{ msg : name }}/h1
/template原始HTML
template!-- 2.html动态语言 --{{htmls}}:span v-htmlhtmls/span
/templateAttribute 绑定
template!-- 3.1 Attribute 绑定 一般的Attribute如果绑定的为假值则id 被移除--!-- div v-bind:idid --!-- v-bind:id简写成:id div:idid --!-- 3.3 v-bind不指定Attribute可用接收Attribute对象 --div v-bindattributes/div
/template使用 JavaScript 表达式
template!-- 4.更加复杂的javascript表达式 --div :idlist-${id}{{number 1}}{{ok ? 是:否}}{{msg.split().reverse().join()}}/div
/template调用函数
template!-- 5.直接调用函数时当页面重新渲染就会再次被调用函数有几个直接调用函数就会调用几次当页面中的数据发生变化时就会重新渲染 --div{{getNumber()}}/div
/template全局组件调用
import { createApp } from vue
import App from ./RootApp.vuelet name 吕懿洋
// createApp(组件,组件的props对象)
let app createApp(App, { name: name })// 6.设置全局变量可被任意组件调用
app.config.globalProperties.rootObj {author: lvyy
}
app.mount(#app)
template!-- 6.全局组件可用直接调用 --{{rootObj.author}}
/template内置指令 !-- 7.1 v-text --span v-textmsg/spanspan{{msg}}/spanbr /!-- 7.2 v-html --span v-htmlhtmls/spanspanfont colorred红色文字/font/spanbr /!-- 7.3 v-show --span v-showfalse测试v-show/spanspan styledisplay:none;测试等价v-show/span!-- 7.4 v-if v-else v-else-if --span v-ifnumber 1number 1/spanspan v-else-ifnumber 2number 2/spanspan v-elsenumber ! 1 且 number ! 2/span!-- 7.5 v-for key用于指定排序key要求时字符串且不要重复--!-- 7.5.1 v-for (value, index) in array --div v-for(peo,index) in forList :keyindex!-- 7.5.2 v-for (value, key, index) in obj --span v-for(value,key,index1) in peo :keyindex key index1{{${index1} ${key} : ${value}}}br //spanbr //div!-- 7.6 v-on: --!-- 7.6.1 v-on:的缩写是如下是基本用法 --button v-on:clicksayHellohello1/buttonbr /button clicksayHellohello2/buttonbr /!-- 7.6.2 []可以赋予动态参数的事件类型, 注意动态参数应该只可能时字符串或者null,为null将移除该事件 --button v-on:[event]sayHellohello3/buttonbr /button [event]sayHellohello4/buttonbr /!-- 7.6.3 $event是内联声明的参数按照个人理解$event就是事件触发时这个绑定这个事件的标签的各种信息包括了触发的方式鼠标还是键盘 --button v-on:[event]getMsg(hello,$event)hello5/buttonbr /button [event]getMsg(hello,$event)hello6/buttonbr /!-- 7.6.4 事件修饰符 --!-- 7.6.4.1 stop 暂无应用场景 --button v-on:[event].stopgetMsg(hello,$event)hello7/buttonbr /button [event].stopgetMsg(hello,$event)hello8/buttonbr /!-- 7.6.4.2 prevent 暂无应用场景 --button v-on:[event].preventgetMsg(hello,$event)hello9/buttonbr /button [event].preventgetMsg(hello,$event)hello10/buttonbr /!-- 7.6.4.3 capture 暂无应用场景 --button v-on:[event].capturegetMsg(hello,$event)hello11/buttonbr /button [event].capturegetMsg(hello,$event)hello12/buttonbr /!-- 7.6.4.4 self 暂无应用场景 --button v-on:[event].selfgetMsg(hello,$event)hello13/buttonbr /button [event].selfgetMsg(hello,$event)hello14/buttonbr /!-- 7.6.4.5 once 应用场景只需要点击一次的事件 --button v-on:[event].oncegetMsg(hello,$event)hello15/buttonbr /button [event].oncegetMsg(hello,$event)hello16/buttonbr /!-- 7.6.4.6 left,right,middle 经测试在IE浏览器点击没有效果 --button v-on:[event].leftgetMsg(hello,$event)hello17/buttonbr /button [event].leftgetMsg(hello,$event)hello18/buttonbr /button v-on:[event].rightgetMsg(hello,$event)hello19/buttonbr /button [event].rightgetMsg(hello,$event)hello20/buttonbr /button v-on:[event].middlegetMsg(hello,$event)hello21/buttonbr /button [event].middlegetMsg(hello,$event)hello22/buttonbr /!-- 7.6.4.7 键盘按键指定触发:keyup.键盘字母或其他 --button v-on:keyup.x.oncegetMsg(hello,$event)hello23/buttonbr /button keyup.ygetMsg(hello,$event)hello24/buttonbr /!-- 7.6.4.8 子组件事件 --ChildApp v-on:myEventgetMsg(hello,$event)/ChildAppbr /ChildApp myEventgetMsg(hello,$event)/ChildAppbr /!-- 7.7 v-bind: --!-- 7.7.1 绑定 静态attribute --img v-bind:srcimageSrc /!-- 7.7.2 绑定 动态attribute --img v-bind:[attribute1]imageSrc /!-- 7.7.3 绑定缩写 --img :[attribute1]imageSrc /!-- 7.7.4 内联字符串拼接 --div :idapp44/div!-- 7.7.5 class 绑定 --!-- 7.7.5.1 {静态class名boolean...} --div :class{red:isRed}文字1/div!-- 7.7.5.2 [动态class1,动态class2...] --div :class[className1,className2]文字2/div!-- 7.7.5.3 2混用1 --div :class[className1,{className2:true}]文字3/div!-- 7.7.6 style 绑定 --!-- 7.7.6.1 {静态style样式值...} --div :style{fontSize: 28 px}文字1/div!-- 7.7.6.2 [动态style样式obj1,...] --div :style[style1,style2]文字2/div!-- 7.7.7 绑定对象形式的attribute --div v-bindattributes1测试绑定ObjAttribute/div!-- 7.7.8 单个prop 绑定 要求id,name都在子组件声明--ChildApp1 :idid :namename/ChildApp1!-- 7.7.8 整个props 绑定 --ChildApp1 v-bind{id:app6,name:name}/ChildApp1动态参数注意事项 !-- 8 动态参数的语法限定 --!-- 8.1 参数数据类型应当是字符串或者为null,null是将事件移除其他情况会报警告--!-- 8.2 复杂的参数表达式类型应当用计算属性来代替--!-- 8.3 参数名应当全部小写如果大写也会被识别为小写 --data() scriptdata(){return {...}}/script!-- 9.1 data选项的格式是一个函数该函数返回一个obj数据 --!-- 9.2 当组件被创建时会调用data函数返回的obj中的顶层属性都会被代理到组件实例中通过this调用动态的渲染数据 --!-- 9.3 需要被代理的属性应该一开始就要放在data中一开始不确认默认值时可以赋null、undefined或其他值 --!-- 9.4 vue暴露出来的内置api会以$开头暴露出来的内置属性以_开头因此我们自定义的属性和方法不要以符号开头 --注意 当一个obj赋值给this.obj时赋值后this.obj是响应式状态而obj不是因此他们两个比较为false
data()深度响应 !-- 12.1 data中obj中的obj的属性发生变化也可以进行响应渲染 --!-- 12.2 data中obj中的arr的发生变化也可以进行响应渲染 --methods !-- 11 methods:{} methods是一个包含所有方法的对象--!-- 11.1 methods中的方法永远指向组件实例的this --!-- 11.2 methods定义方法的时候不可以用箭头函数因为箭头函数没有自己this上下文 --有状态的methods(防抖) !-- 14 预置防抖的事件处理器 --!-- 14.4 防抖函数调用 --button clicksayDelayHello1防抖响应/button// 14.1 引入防抖函数(需要npm i lodash)import { debounce } from lodash;export default(){data(){return{}},methods:{// 14.2 引入防抖函数(需要npm i lodash)sayHello1() {console.log(防抖函数2);},},created(){// 14.3 created中自定义的属性貌似不用再data中声明,为了遵循规范还是再data中定义一下this.sayDelayHello1 debounce(this.sayHello1, 1000);}}DOM更新时机 !-- 13.1 当响应式状态发生变化DOM就会更新 --!-- 13.2 DOM更新不是同步的而是进行周期渲染到下一个周期前把响应式状态改变的存入缓存队列到下一个周期后更新缓存队列 --!-- 13.3 周期执行完毕可以再次执行回调函数 --计算属性 !-- 15.1 计算属性的应用场景: 一个复杂的javascript表达式再组件中被多处使用应该定义在计算属性中代替显示简化代码增加复用性 --{{ reverseMsg }}!-- 15.2 计算属性和方法的区别调用的时机不同 --!-- 15.2.1 计算属性调用的情况发生在里面依赖的数据改变的时候在多处使用的情况下只会调用一次更新缓存空间数据页面调用的是缓存中的数据--!-- 15.2.2 非事件类型的方法调用是一旦页面重新渲染时就会调用调用的次数和显示的次数一致--!-- 15.2.3 因此当我们可以用计算属性代替方法的时候优先使用计算属性的方式 --!-- 15.2.4 get方法里面不要有副作用计算属性一般不直接修改 --export default(){data(){return{msg1:hello}},computed: {// 计算属性看上去像一个方法其实他是一个属性如果里面只写get方法可以简写成这样reverseMsg() {return this.msg1.split().reverse().join();},}class和style绑定 !-- 16.1 class静态 --span classerr结果/span!-- 16.2 class动态是否绑定err --span :class{err:!isSuccess}结果/span!-- 16.3 class数组, 是否绑定errClass对应的class值 --span :class[errClass]结果/span!-- 16.4 计算属性应用 --button clickisSuccess !isSuccess{{buttonName}}/buttonspan v-bind:classspanClass结果/span!-- 16.5 组件元素使用class 单个根元素直接绑定多个根元素可以在$attrs.class,接收父组件传入的class --ChildApp1 :class{success:isSuccess}/ChildApp1!-- 16.6 style静态 --span stylecolor: red; font-size: 28px;结果/span!-- 16.7 style动态obj --span :style{color: red,font-size: 28px}结果/span!-- 16.8 style动态obj数组 --span :style[{color: red},{font-size: 28px}]结果/span条件渲染 !-- 17.1 v-if v-else v-else-if判断是否渲染当前元素 --!-- 17.2 切换多个元素可以用template元素 --!-- 17.3 切换多个元素可以用template元素 --!-- 17.4 v-show 相当于display:none; 不可以用于修饰template元素没有v-else --!-- 17.5 v-if是真实的也是惰性的true才渲染元素初始若false则不会渲染元素而v-show则是一开始就渲染元素只是设置是否可见 --列表渲染 !-- 18.1 数组: v-for(item[,index]) in items --!-- 18.2 对象数组: v-for({prop1, prop2}[,index]) in items --spanv-for({id,name,age}, index) in forList:keyidnameindex{{id - name - age \t}}/span!-- 18.3 对象: v-for(value [,key ,index]) in obj --!-- 18.4 数值: v-forn in number n从1开始--!-- 18.5 原则上v-for修饰的元素和内部都是可以直接使用v-for里面的数据,原因是v-for的优先级要高于其他attribute,但是因为v-for的优先级低于v-if,则v-if用不了v-for的数据,不建议v-if和v-for一个元素并用--!-- 18.6 key是特殊的attribute, 可用于重用和排序元素,如果没有key修饰,则是就地更新,key的值一般是字符串或者数值,不重复的 --!-- 18.7 在for循环中建议加入key值 --!-- 18.8 for循环作用于组件时, 数据不会自动传入给组件,需要手动将数据指定给props, 我们需要注意传入给组件的obj或数组类型的数据,组件里发生变化,父组件也会跟着变化,我们要子组件和父组件明确我们是否要共用数据非常不建议--数组变换侦听 !-- 19.1 Vue可以数据侦听的变更方法 --!-- 19.1.1 push(data1[,data2,data3...]) - length: 尾部追加一条或多条数据,返回新长度 --button clickpushDatas尾部追加/button!-- 19.1.2 pop() - data: 尾部移除一条数据,返回移除数据 --button clickpopData尾部删除/button!-- 19.1.3 shift() - data:头部移除一条数据,返回移除数据 --button clickshiftData头部删除/button!-- 19.1.4 unshift() - length: 头部追加一条或多条数据返回新长度 --button clickunshiftDatas头部追加/button!-- 19.1.5 splice(index,deleteLen[,addData]) - deleteData: 从指定下标开始删除删除指定的数目删除后替换指定数据 --button clickspliceDatas替换/button!-- 19.1.6 sort((a,b){return a.xxx-b.xxx}) - 排序排序的方法前者大于后者时排序为正序从小到大排列,排序的方法后者大于前者时排序为逆序从大到小排列 --button clicksortAscDatas正序/buttonbutton clicksortDescDatas逆序/button!-- 19.1.7 reverse(): 数组反转 --button clickreverseDatas反转/button!-- 19.1.8 filter(item{return ...}) - newArray: 过滤符合条件的数据返回新的数组旧的数组不发生变化 --!-- 19.1.9 concat(array) - newArray: 合并两个数组返回新的数组旧的数组不发生变化 --!-- 19.1.10 slice(startIndex, endIndex) - newArray: 截取指定下标范围的数组不包括endIndex旧的数组不发生变化 --!-- 19.2 如果我们要对现有列表进行过滤不应该考虑v-forv-if而是创建一个计算属性过滤现有的列表v-for遍历计算属性解决如果计算属性无法解决用于方法替换计算属性 --事件处理 !-- 20.1 内联监听事件时一个表达式就可处理简单的事情 --!-- 20.2 方法事件处理有个$event参数记录事件触发元素的详细信息--!-- 20.3 省略部分事件修饰符键盘修饰符鼠标按键修饰符(实际业务开发应用较少) --表单输入绑定 !-- 21.1 常规方式 --input :valuetext inputevent text event.target.value /!-- 21.2 v-model 是当输入框内容变动时text也会跟着改变--input v-modeltext /!-- 21.2.1 v-model.lazy 是输入框内容输入完毕失焦后text才会改变--input v-model.lazytext /!-- 21.2.2 v-model.number 如果text可以被parseFloat则会转换成number类型的数据否则保留原样--input v-model.numbertext /!-- 21.2.3 v-model.trim 输入框自动去除前后空格--input v-model.trimtext /!-- 21.3 textarea --textarea :valuetext inputevent textevent.target.value/textareatextarea v-modeltext/textarea!-- 21.4 checkbox input checkbox v-model单个情况--!-- 21.4.1 value默认情况是true/false,可以自定义true-value和false-value attribute自定义选中和不选中的value值 --{{checked}}input typecheckbox v-modelchecked true-valueyes false-valueno /!-- 21.5 checkbox input checkbox v-model相同情况定义成数组--{{names}}input typecheckbox v-modelnames :valuename1 /input typecheckbox v-modelnames :valuename2 /input typecheckbox v-modelnames :valuename3 /!-- 21.6 radio单选 --{{radioValue}}input typeradio v-modelradioValue valueone /input typeradio v-modelradioValue valuetwo /!-- 21.7 selected选择框 单选 --{{selected}}select v-modelselectedoption value disabledtrue请选择/optionoptionA/optionoptionB/optionoptionC/option/select!-- 21.8 selected选择框 多选 --{{selected1}}select v-modelselected1 multipleoption valueAA.上班/optionoption valueBB.吃饭/optionoption valueCC.睡觉/option/select!-- 21.9 selected选择框的option中value可以绑定obj,v-model获取的也就是obj --{{selectObj}}select v-modelselectObjoptionv-foroption in selectedOptions:valueoption:keyoption.number{{option.number}}/option/select生命周期钩子 !-- 22 生命周期钩子执行顺序beforeCreate() created() beforeMount() mounted() beforeUpdate() updated() beforeUnmount() unmounted() --
侦听器watch
!-- 23.1 侦听器相比较于计算属性计算属性里面不希望有DOM数据的变动或者异步请求侦听器则是处理需要有DOM数据变动或者异步请求的发送 --模板引用ref !-- 24.1 refs在mounted()生命周期函数之后使用之前都是为null的 --!-- 24.2 this.$refs.refName 表示当前的底层DOM --聚焦输入框input refinput v-modeluserId1 /!-- 24.3 组件上应用ref时子组件可以通过expose:[data属性名,...] 暴露出子组件的属性父组件可以通过 this.$refs.refName.属性名 获取到--ChildApp1 refchildApp1/ChildApp1export default(){data(){return{userId:}},watch: {userId: {handler(newValue, oldValue) {// this.searchDelayUserId();this.searchUserId();},// 23.2 immediate的触发时机是在created生命周期钩子之前所以created中定义的有状态的方法不能被调用immediate: true}},}// 聚焦输入框this.$refs[input].focus();// 组件上应用ref时子组件可以通过expose:[data属性名,...] 暴露出子组件的属性// 父组件可以通过this.$refs.refName.属性名 获取到console.log(this.$refs.childApp1.childName);console.log(this.$refs.childApp1.childId);组件基础 !-- 25.1 创建一个SFC --!-- 25.2 引入SFC import xxx from xxx.vue --!-- 25.3 注册SFC components:{xxx} --!-- 25.4 如果在SFC中使用模板标签建议使用驼峰命名方式prop和属性用是xxx-xxx, 元素可以使用闭合标签 --!-- 25.5 如果在HTML文件中使用模板 都应该使用xxx-xxx 元素不可以使用闭合标签 --!-- 25.6 监听事件 this.$emit(事件名,参数...) --!-- 25.7 emits:[事件名] 可以暴露要监听的事件--!-- 25.8 插槽 slot/ --!-- 26.9 动态组件适用于来回切换组件的情况 --!-- 26.10 不用keep-alive修饰时切换注销组件用keep-alive修饰暂存组件 --button clickcomponentName componentName ChildApp?ChildApp1:ChildApp切换/buttonkeep-alivecomponent :iscomponentName/component/keep-alive
组件注册 !-- 27.1 在根组件App注册组件可以全局使用 --ChildApp2/ChildApp2!-- 27.2 在SFC中注册组件后代组件不能使用 --!-- 27.3 Props应当是向下传递因此当传递的是对象或数组时应当注意不应该直接改变影响父组件的数据值可以选择事件回调交由父组件操作 --项目文件结构 黄色截图就是修改和新增的相关文件
RootApp.vue
template!-- 3.1 Attribute 绑定 一般的Attribute如果绑定的为假值则id 被移除--!-- div v-bind:idid --!-- v-bind:id简写成:id div:idid --!-- 3.3 v-bind不指定Attribute可用接收Attributes对象 --div v-bindattributes!-- 1.双花括号语法里面是javascript表达式组件的data数据发生变化时也会动态改变 --h1{{ msg : name }}/h1!-- 2.html动态语言 --{{htmls}}:span v-htmlhtmls/spanbr /!-- 3.2 对于接收真假值的Attribute 不会被移除 --button v-bind:disableddisabled clicksetNumber不可点击按钮/button!-- 4.更加复杂的javascript表达式 --{{number 1}}{{ok ? 是:否}}{{msg.split().reverse().join()}}div :idlist-${id}!-- 5.直接调用函数时当页面重新渲染就会再次被调用函数有几个直接调用函数就会调用几次当页面中的数据发生变化时就会重新渲染 --{{getNumber()}}{{getNumber()}}br /!-- 6.全局组件可用直接调用 --{{rootObj.author}}br /!-- 7.内置指令 --!-- 7.1 v-text --span v-textmsg/spanspan{{msg}}/spanbr /!-- 7.2 v-html --span v-htmlhtmls/spanspanfont colorred红色文字/font/spanbr /!-- 7.3 v-show --span v-showfalse测试v-show/spanspan styledisplay:none;测试等价v-show/span!-- 7.4 v-if v-else v-else-if --span v-ifnumber 1number 1/spanspan v-else-ifnumber 2number 2/spanspan v-elsenumber ! 1 且 number ! 2/span!-- 7.5 v-for key用于指定排序key要求时字符串且不要重复--!-- 7.5.1 v-for (value, index) in array --div v-for(peo,index) in forList :keyindex!-- 7.5.2 v-for (value, key, index) in obj --span v-for(value,key,index1) in peo :keyindex key index1{{${index1} ${key} : ${value}}}br //spanbr //div!-- 7.6 v-on: --!-- 7.6.1 v-on:的缩写是如下是基本用法 --button v-on:clicksayHellohello1/buttonbr /button clicksayHellohello2/buttonbr /!-- 7.6.2 []可以赋予动态参数的事件类型, 注意动态参数应该只可能时字符串或者null,为null将移除该事件 --button v-on:[event]sayHellohello3/buttonbr /button [event]sayHellohello4/buttonbr /!-- 7.6.3 $event是内联声明的参数按照个人理解$event就是事件触发时这个绑定这个事件的标签的各种信息包括了触发的方式鼠标还是键盘 --button v-on:[event]getMsg(hello,$event)hello5/buttonbr /button [event]getMsg(hello,$event)hello6/buttonbr /!-- 7.6.4 事件修饰符 --!-- 7.6.4.1 stop 暂无应用场景 --button v-on:[event].stopgetMsg(hello,$event)hello7/buttonbr /button [event].stopgetMsg(hello,$event)hello8/buttonbr /!-- 7.6.4.2 prevent 暂无应用场景 --button v-on:[event].preventgetMsg(hello,$event)hello9/buttonbr /button [event].preventgetMsg(hello,$event)hello10/buttonbr /!-- 7.6.4.3 capture 暂无应用场景 --button v-on:[event].capturegetMsg(hello,$event)hello11/buttonbr /button [event].capturegetMsg(hello,$event)hello12/buttonbr /!-- 7.6.4.4 self 暂无应用场景 --button v-on:[event].selfgetMsg(hello,$event)hello13/buttonbr /button [event].selfgetMsg(hello,$event)hello14/buttonbr /!-- 7.6.4.5 once 应用场景只需要点击一次的事件 --button v-on:[event].oncegetMsg(hello,$event)hello15/buttonbr /button [event].oncegetMsg(hello,$event)hello16/buttonbr /!-- 7.6.4.6 left,right,middle 经测试在IE浏览器点击没有效果 --button v-on:[event].leftgetMsg(hello,$event)hello17/buttonbr /button [event].leftgetMsg(hello,$event)hello18/buttonbr /button v-on:[event].rightgetMsg(hello,$event)hello19/buttonbr /button [event].rightgetMsg(hello,$event)hello20/buttonbr /button v-on:[event].middlegetMsg(hello,$event)hello21/buttonbr /button [event].middlegetMsg(hello,$event)hello22/buttonbr /!-- 7.6.4.7 键盘按键指定触发:keyup.键盘字母或其他 --button v-on:keyup.x.oncegetMsg(hello,$event)hello23/buttonbr /button keyup.ygetMsg(hello,$event)hello24/buttonbr /!-- 7.6.4.8 子组件事件 --ChildApp v-on:myEventgetMsg(hello,$event)/ChildAppbr /ChildApp myEventgetMsg(hello,$event)/ChildAppbr /!-- 7.7 v-bind: --!-- 7.7.1 绑定 静态attribute --img v-bind:srcimageSrc /!-- 7.7.2 绑定 动态attribute --img v-bind:[attribute1]imageSrc /!-- 7.7.3 绑定缩写 --img :[attribute1]imageSrc /!-- 7.7.4 内联字符串拼接 --div :idapp44/div!-- 7.7.5 class 绑定 --!-- 7.7.5.1 {静态class名boolean...} --div :class{red:isRed}文字1/div!-- 7.7.5.2 [动态class1,动态class2...] --div :class[className1,className2]文字2/div!-- 7.7.5.3 2混用1 --div :class[className1,{className2:true}]文字3/div!-- 7.7.6 style 绑定 --!-- 7.7.6.1 {静态style样式值...} --div :style{fontSize: 28 px}文字1/div!-- 7.7.6.2 [动态style样式obj1,...] --div :style[style1,style2]文字2/div!-- 7.7.7 绑定对象形式的attribute --div v-bindattributes1测试绑定ObjAttribute/div!-- 7.7.8 单个prop 绑定 要求id,name都在子组件声明--ChildApp1 :idid :namename/ChildApp1!-- 7.7.8 整个props 绑定 --ChildApp1 v-bind{id:app6,name:name}/ChildApp1!-- 8 动态参数的语法限定 --!-- 8.1 参数数据类型应当是字符串或者为null,null是将事件移除其他情况会报警告--!-- 8.2 复杂的参数表达式类型应当用计算属性来代替--!-- 8.3 参数名应当全部小写如果大写也会被识别为小写 --!-- 9 data(){} --!-- 9.1 data选项的格式是一个函数该函数返回一个obj数据 --!-- 9.2 当组件被创建时会调用data函数返回的obj中的顶层属性都会被代理到组件实例中通过this调用动态的渲染数据 --!-- 9.3 需要被代理的属性应该一开始就要放在data中一开始不确认默认值时可以赋null、undefined或其他值 --!-- 9.4 vue暴露出来的内置api会以$开头暴露出来的内置属性以_开头因此我们自定义的属性和方法不要以符号开头 --!-- 10 当一个obj赋值给this.obj时注意:赋值后this.obj是响应式状态而obj不是因此他们两个比较为false --!-- 11 methods:{} methods是一个包含所有方法的对象--!-- 11.1 methods中的方法永远指向组件实例的this --!-- 11.2 methods定义方法的时候不可以用箭头函数因为箭头函数没有自己this上下文 --!-- 12 深度响应 --!-- 12.1 data中obj中的obj的属性发生变化也可以进行响应渲染 --!-- 12.2 data中obj中的arr的发生变化也可以进行响应渲染 --!-- 13 DOM更新时机 --!-- 13.1 当响应式状态发生变化DOM就会更新 --!-- 13.2 DOM更新不是同步的而是进行周期渲染到下一个周期前把响应式状态改变的存入缓存队列到下一个周期后更新 --!-- 13.3 周期执行完毕可以再次执行回调函数 --!-- 14 预置防抖的事件处理器 --!-- 14.3 防抖函数调用 --button clicksayDelayHello防抖响应/button!-- 14.4 在methods里设置有防抖状态的函数如果有多处调用会相互影响 --!-- 14.4.1 再面对一个函数多处调用且并不是每处调用都需要防抖时需要如下设置 --!-- 14.4.2 methods里定义没有状态的逻辑处理函数 --!-- 14.4.3 防抖函数再created钩子中声明 --!-- 14.4.4 这样防抖函数和没有状态的逻辑处理函数就分开了需要防抖调用就用created中的防抖函数不需要则使用methods中的函数 --button clicksayDelayHello1防抖响应/buttonbutton clicksayHello1非防抖响应/button!-- 15. 计算属性 --!-- 15.1 计算属性的应用场景: 一个复杂的javascript表达式再组件中被多处使用应该定义在计算属性中代替显示简化代码增加复用性 --{{ reverseMsg }}{{ reverseMsg }}br /{{ reverseMsg }}{{ reverseMsg }}br /!-- 15.2 计算属性和方法的区别调用的时机不同 --!-- 15.2.1 计算属性调用的情况发生在里面依赖的数据改变的时候在多处使用的情况下只会调用一次更新缓存空间数据页面调用的是缓存中的数据--!-- 15.2.2 非事件类型的方法调用是一旦页面重新渲染时就会调用调用的次数和显示的次数一致--!-- 15.2.3 因此当我们可以用计算属性代替方法的时候优先使用计算属性的方式 --!-- 15.2.4 get方法里面不要有副作用计算属性一般不直接修改 --{{ reverseMsg1 }}{{ reverseMsg1 }}br /{{ reverseMsg1 }}{{ reverseMsg1 }}br /!-- 16. class和style绑定 --!-- 16.1 class静态 --span classerr结果/span!-- 16.2 class动态是否绑定err --span :class{err:!isSuccess}结果/span!-- 16.3 class数组, 是否绑定errClass对应的class值 --span :class[errClass]结果/span!-- 16.4 计算属性应用 --button clickisSuccess !isSuccess{{buttonName}}/buttonspan v-bind:classspanClass结果/span!-- 16.5 组件元素使用class 单个根元素直接绑定多个根元素可以在$attrs.class,接收父组件传入的class --ChildApp1 :class{success:isSuccess}/ChildApp1!-- 16.6 style静态 --span stylecolor: red; font-size: 28px;结果/span!-- 16.7 style动态obj --span :style{color: red,font-size: 28px}结果/span!-- 16.8 style动态obj数组 --span :style[{color: red},{font-size: 28px}]结果/span!-- 17. 条件渲染 --!-- 17.1 v-if v-else v-else-if判断是否渲染当前元素 --!-- 17.2 切换多个元素可以用template元素 --!-- 17.3 切换多个元素可以用template元素 --!-- 17.4 v-show 相当于display:none; 不可以用于修饰template元素没有v-else --!-- 17.5 v-if是真实的也是惰性的true才渲染元素初始若false则不会渲染元素而v-show则是一开始就渲染元素只是设置是否可见 --!-- 18 列表渲染 --!-- 18.1 数组: v-for(item[,index]) in items --!-- 18.2 对象数组: v-for({prop1, prop2}[,index]) in items --spanv-for({id,name,age},index) in forList:keyidnameindex{{id - name - age \t}}/spanbr /!-- 18.3 对象: v-for(value [,key ,index]) in obj --!-- 18.4 数值: v-forn in number n从1开始--!-- 18.5 原则上v-for修饰的元素和内部都是可以直接使用v-for里面的数据,原因是v-for的优先级要高于其他attribute,但是因为v-for的优先级低于v-if,则v-if用不了v-for的数据,不建议v-if和v-for一个元素并用--!-- 18.6 key是特殊的attribute, 可用于重用和排序元素,如果没有key修饰,则是就地更新,key的值一般是字符串或者数值,不重复的 --!-- 18.7 在for循环中建议加入key值 --!-- 18.8 for循环作用于组件时, 数据不会自动传入给组件,需要手动将数据指定给props, 我们需要注意传入给组件的obj或数组类型的数据,组件里发生变化,父组件也会跟着变化,我们要子组件和父组件明确我们是否要共用数据--!-- 19 数组变换侦听 --!-- 19.1 Vue可以数据侦听的变更方法 --!-- 19.1.1 push(data1[,data2,data3...]) - length: 尾部追加一条或多条数据,返回新长度 --button clickpushDatas尾部追加/button!-- 19.1.2 pop() - data: 尾部移除一条数据,返回移除数据 --button clickpopData尾部删除/button!-- 19.1.3 shift() - data:头部移除一条数据,返回移除数据 --button clickshiftData头部删除/button!-- 19.1.4 unshift() - length: 头部追加一条或多条数据返回新长度 --button clickunshiftDatas头部追加/button!-- 19.1.5 splice(index,deleteLen[,addData]) - deleteData: 从指定下标开始删除删除指定的数目删除后替换指定数据 --button clickspliceDatas替换/button!-- 19.1.6 sort((a,b){return a.xxx-b.xxx}) - 排序排序的方法前者大于后者时排序为正序从小到大排列,排序的方法后者大于前者时排序为逆序从大到小排列 --button clicksortAscDatas正序/buttonbutton clicksortDescDatas逆序/button!-- 19.1.7 reverse(): 数组反转 --button clickreverseDatas反转/button!-- 19.1.8 filter(item{return ...}) - newArray: 过滤符合条件的数据返回新的数组旧的数组不发生变化 --!-- 19.1.9 concat(array) - newArray: 合并两个数组返回新的数组旧的数组不发生变化 --!-- 19.1.10 slice(startIndex, endIndex) - newArray: 截取指定下标范围的数组不包括endIndex旧的数组不发生变化 --!-- 19.2 如果我们要对现有列表进行过滤不应该考虑v-forv-if而是创建一个计算属性过滤现有的列表v-for遍历计算属性解决如果计算属性无法解决用于方法替换计算属性 --!-- 20 事件处理 --!-- 20.1 内联监听事件时一个表达式就可处理简单的事情 --!-- 20.2 方法事件处理有个$event参数记录事件触发元素的详细信息--!-- 20.3 省略部分事件修饰符键盘修饰符鼠标按键修饰符(实际业务开发应用较少) --!-- 21 表单输入绑定 --!-- 21.1 常规方式 --input :valuetext inputevent text event.target.value /!-- 21.2 v-model 是当输入框内容变动时text也会跟着改变--input v-modeltext /!-- 21.2.1 v-model.lazy 是输入框内容输入完毕失焦后text才会改变--input v-model.lazytext /!-- 21.2.2 v-model.number 如果text可以被parseFloat则会转换成number类型的数据否则保留原样--input v-model.numbertext /!-- 21.2.3 v-model.trim 输入框自动去除前后空格--input v-model.trimtext /!-- 21.3 textarea --textarea :valuetext inputevent textevent.target.value/textareatextarea v-modeltext/textarea!-- 21.4 checkbox input checkbox v-model单个情况--!-- 21.4.1 value默认情况是true/false,可以自定义true-value和false-value attribute自定义选中和不选中的value值 --{{checked}}input typecheckbox v-modelchecked true-valueyes false-valueno /!-- 21.5 checkbox input checkbox v-model相同情况定义成数组--{{names}}input typecheckbox v-modelnames :valuename1 /input typecheckbox v-modelnames :valuename2 /input typecheckbox v-modelnames :valuename3 /!-- 21.6 radio单选 --{{radioValue}}input typeradio v-modelradioValue valueone /input typeradio v-modelradioValue valuetwo /!-- 21.7 selected选择框 单选 --{{selected}}select v-modelselectedoption value disabledtrue请选择/optionoptionA/optionoptionB/optionoptionC/option/select!-- 21.8 selected选择框 多选 --{{selected1}}select v-modelselected1 multipleoption valueAA.上班/optionoption valueBB.吃饭/optionoption valueCC.睡觉/option/select!-- 21.9 selected选择框的option中value可以绑定obj,v-model获取的也就是obj --{{selectObj}}select v-modelselectObjoptionv-foroption in selectedOptions:valueoption:keyoption.number{{option.number}}/option/select!-- 22 生命周期钩子beforeCreate() created() beforeMount() mounted() beforeUpdate() updated() beforeUnmount() unmounted() --!-- 23 侦听器watch --!-- 23.1 侦听器相比较于计算属性计算属性里面不希望有DOM数据的变动或者异步请求 侦听器则是处理需要有DOM数据变动或者异步请求的发送 --工号input v-modeluserId /!-- 24 模板引用ref --!-- 24.1 refs在mounted()周期函数之后使用之前都是为null的 --!-- 24.2 this.$refs.refName 表示当前的底层DOM --聚焦输入框input refinput v-modeluserId1 /!-- 24.3 组件上应用ref时子组件可以通过expose:[data属性名,...] 暴露出子组件的属性父组件可以通过 this.$refs.refName.属性名 获取到--ChildApp1 refchildApp1/ChildApp1!-- 25 组件基础 --!-- 25.1 创建一个SFC --!-- 25.2 引入SFC import xxx from xxx.vue --!-- 25.3 注册SFC components:{xxx} --!-- 25.4 如果在SFC中使用模板元素建议使用驼峰命名方式prop和元素可以是xxx-xxx, 元素可以使用闭合标签 --!-- 25.5 如果在HTML文件中使用模板prop prop和元素应该使用xxx-xxx 元素不可以使用闭合标签 --!-- 25.6 监听事件 this.$emit(事件名,参数...) --!-- 25.7 emits:[事件名] 可以暴露要监听的事件--!-- 25.8 插槽 slot/ --!-- 26.9 动态组件适用于来回切换组件的情况 --!-- 26.10 不用keep-alive修饰时切换注销组件用keep-alive修饰暂存组件 --button clickcomponentName componentName ChildApp?ChildApp1:ChildApp切换/buttonkeep-alivecomponent :iscomponentName/component/keep-alive!-- 27.1 在根组件App注册组件可以全局使用 --ChildApp2/ChildApp2!-- 27.2 在SFC中注册组件后代组件不能使用 --!-- 27.3 Props应当是向下传递因此当传递的是对象或数组时应当注意不应该直接改变影响父组件的数据值可以选择事件回调交由父组件操作 --!-- 27.4 组件标签采用驼峰命名组件中的Attribute采用xxx-xxx方式使用命名使用驼峰命名 --/div/div
/templatestyle scoped
.red {font-size: 28px;
}
.className1 {font-size: 28px;
}
.className2 {color: red;
}
.success {color: green;
}
.err {color: red;
}
/stylescript
// 引入一个子组件
import ChildApp from ./components/ChildApp.vue;
import ChildApp1 from ./components/ChildApp1.vue;
// 引入一张图片
import img1 from ./img/1.png;
// 14.1 引入防抖函数(需要npm i lodash)
import { debounce } from lodash;
export default {// 父组件传入的数据props: {name: String},// 子组件components: { ChildApp: ChildApp, ChildApp1: ChildApp1 },// 本组件定义的数据data() {return {id: app2,msg: hello world,htmls: font colorred红色文字/font,disabled: false,attributes: {id: app3,name: div1},number: 1,ok: true,forList: [{id: 1,name: 张三,age: 18},{id: 2,name: 李四,age: 20}],event: click,imageSrc: img1,attribute1: src,app4: app,isRed: true,className1: className1,className2: className2,style1: {fontSize: 28px},style2: {color: red},attributes1: {id: app5,other-attr: hello},name: 美少女,sayDelayHello1: null,msg1: i love you,submit: 提交,revert: 还原,isSuccess: false,errClass: err,text: hello,checked: no,name1: 张三,name2: 李四,name3: 王五,names: [],radioValue: ,selected: ,selected1: [],selectedOptions: [{ number: 1 }, { number: 2 }, { number: 3 }],selectObj: ,userId: ,userId1: ,componentName: ChildApp};},created() {// created中自定义的属性貌似不用再data中声明,为了遵循规范还是再data中定义一下this.sayDelayHello1 debounce(this.sayHello1, 1000);console.log(this.sayDelayHello1);this.user name;console.log(this.user);this.searchDelayUserId debounce(this.searchUserId, 1000);},computed: {// 计算属性看上去像一个方法其实他是一个属性如果里面只写get方法可以简写成这样reverseMsg() {console.log(hello);return this.msg1.split().reverse().join();},// 非简写形式reverseMsg1: {get() {return this.msg1.split().reverse().join();},set(newValue) {console.log(改变了);}},// 复杂的表达式写在计算属性中spanClass: {get() {return {success: this.isSuccess,err: !this.isSuccess};}},buttonName: {get() {return this.isSuccess ? this.revert : this.submit;}}},watch: {userId: {handler(newValue, oldValue) {// this.searchDelayUserId();this.searchUserId();},// 23.2 immediate的触发时机是在created之前所以created中定义的有状态的方法不能被调用immediate: true}},mounted() {this.$refs[input].focus();console.log(this.$refs.childApp1.childName);console.log(this.$refs.childApp1.childId);},// 本组件定义的方法methods: {setNumber() {this.number this.number 1;},getNumber() {console.log(msg改变就会触发事件);return this.number;},sayHello() {console.log(hello world!);console.log(this.user);},getMsg(param1, event) {console.log(param1);console.log(event);},// 14.2 设置防抖函数 调用函数名debounce(业务处理函数, 防抖毫秒数)sayDelayHello: debounce(function() {console.log(防抖函数);}, 1000),sayHello1() {console.log(防抖函数2);},// 尾部追加多个数据pushDatas() {let data1 { id: 3, name: 王五, age: 22 };let data2 { id: 4, name: 秦六, age: 33 };let length this.forList.push(data1, data2);console.log(追加后长度为 length);},// 尾部删除一个数据popData() {let data this.forList.pop();console.log(删除尾部数据, data);},// 头部追加一条或多条数据unshiftDatas() {let data1 { id: 3, name: 王五, age: 22 };let data2 { id: 4, name: 秦六, age: 33 };let length this.forList.unshift(data1, data2);console.log(头部追加后长度为 length);},// 头部删除数据shiftData() {let data this.forList.shift();console.log(头部删除数据为, data);},// 替换数据spliceDatas() {let data1 { id: 3, name: 王五, age: 22 };let data2 { id: 4, name: 秦六, age: 33 };let data this.forList.splice(0, 1, data1, data2);console.log(替换前的数据为, data);},// 正序sortAscDatas() {this.forList.sort((a, b) a.id - b.id);},// 逆序sortDescDatas() {this.forList.sort((a, b) b.id - a.id);},// 反转reverseDatas() {this.forList.reverse();},searchUserId() {console.log(检索userId);}}
};
/scriptmain.js
import { createApp } from vueimport App from ./RootApp.vue
import ChildApp2 from ./components/ChildApp2.vuelet name 吕懿洋
// createApp(组件,组件的props对象)
let app createApp(App, { name: name })// 貌似没有效果
app.config.errorHandler (err) {/* 处理错误 */console.log(err)
}// 6.设置全局变量可被任意组件调用
app.config.globalProperties.rootObj {author: lvyy
}app.component(ChildApp2,ChildApp2)app.mount(#app)
ChildApp.vue
templatedivinput v-modeldata /button clickchildClick子组件按钮/button/div
/templatescript
export default {name: ChildApp,data() {return {data: };},methods: {childClick() {this.$emit(myEvent);}}
};
/scriptChildApp1.vue
templatedivinput v-modeldata /div :class$attrs.class{{id - name}}/div/div
/templatescript
export default {name: ChildApp1,props: {id: String,name: String},data() {return {childName: ChildApp1,childId: ChildApp1,data: };},expose: [childName]
};
/scriptChildApp2.vue
templatedivinput v-modeldata //div
/templatescript
export default {name: ChildApp2,data() {return {childName: ChildApp2,childId: ChildApp2,data: };},expose: [childName]
};
/script其他注意事项
图片自行填充需要执行命令 npm i lodash 再执行npm install ,最后 npm run dev,主要是为了下载防抖函数的插件