万字血书Vue—Vue语法
模板语法
插值语法Mustache插值采用{{ }} ,用于解析标签体内容 ,将Vue实例中的数据插入DOM中
<h1>Hello {{name}}</h1> 指令语法指令用于解析标签 ,是vue为开发者提供的一套模板语法 ,辅助开发者渲染页面的基本结构 。
(指令是vue开发中最基础 、最常用 、最简单的知识点)(支持绑定简单的数据值之外 ,还支持js表达式运算)
内容渲染指令1 、v-text=" " 会覆盖元素内默认的值 、无法写HTML标签语句
2 、{{ }} 插值表达式(Mustache) 不会覆盖元素中默认的内容
3 、v-html 可以渲染包含HTML标签的字符串
v-html有安全性问题 ,在网站上动态渲染任意HTML是非常危险的 ,容易导致XSS攻击;永远不要再用户提交的内容上使用v-html 。
属性绑定指令v-bind: 为元素的属性动态绑定属性值
属性:placeholder 、src等
简写::
<a v-bind:href="https://www.cnblogs.com/gfhcg/archive/2023/03/17/url">点击跳转</a> <a :href="https://www.cnblogs.com/gfhcg/archive/2023/03/17/url">点击跳转</a> 事件绑定指令v-on: 为DOM元素绑定事件监听
v-on:click= ” “ 、v-on:input 、v-on:keyup
事件处理函数 ,需要在methods节点中进行声明
简写:@、如果事件处理函数的代码足够简单 ,只有一行代码,则可以简写到行内
事件对象event <body> <div id="app">{{username}}</div> <button @click="addcount($event,88)"> 点击我 </button> <script src="https://www.cnblogs.com/gfhcg/archive/2023/03/17/vue.js"></script> <script> const vm=new Vue({ el:#app, data:{ username:zs, count:0 }, methods:{ addcount(e,88){ const nowBgColor =e.target.style.backgroundColor console.log(nowB gColor) this.count+=1 } } }) </script> </body>绑定事件并传参 ,使用() 小括号 ,但会占用event的位置
$event是vue提供的特殊变量用于占位,用来表示原生事件参数对象event ,使用e接受
事件修饰符vue提供事件修饰符 ,来辅助程序员更方便的对事件的触发进行控制
.stop阻止事件冒泡()里到外
.prevent 阻止默认行为()比如阻止跳转
.capture以捕获模式触发当前事件处理函数(外到里)
.self只有在event.target是当前元素自身时触发事件处理函数
.once绑定的事件只触发一次
.passive事件的默认行为立即执行,无需等待事件回调执行完毕
按键修饰符监听键盘事件时 ,我们经常需要判断详细的按键 ,此时可为键盘相关的事件添加按键修饰符
.enter 、.delete 、.esc、.space 、.tab(特殊:只适用于keydown) 、.up、.down 、.left 、.right 系统修饰符(用法特殊):ctrl 、alt 、shift 、mta 配合keyup使用:按下按键的同时需要再按下其他键 ,随后事件才被触发;keydown正常触发事件 也可以使用keyCode去指定具体的按键(不推荐) Vue.config.keyCodes.自定义键名=键码 可以去定制按键别名 双向绑定指令v-model 在不操作DOM的情况下 ,快速获取表单数据(只能配合表单元素一起使用)
<input type="text" v-model:value="username"/> <input type="text" v-model="username"/> v-model 指令的修饰符方便用户对输入的内容进行处理
.number自动将用户输入值转化为数值 .trim 自动过滤用户输入的首尾空白字符 .lazy 在change时更新而非input时更新(不实时更新 ,文本框失去焦点更新) 条件渲染指令按需控制DOM的显示和隐藏
v-if =" " 动态创建或移除DOM元素 ,有更高的切换开销(重绘和回流)
v-else-if =" " 、v-else =" "
v-show=" " 动态为元素添加或移除display样式 ,有更高的初始渲染开销。
列表渲染指令v-for=" " 辅助开发者基于一个数组来循环渲染相似的UI结构
特殊语法:item in items
<body> <div id="root"> <!-- 遍历数组 --> <ul> <li v-for="item in persons" :key="item.id"> {{item.id}}-{{item.name}}-{{item.age}} </li> </ul> <!-- 遍历对象 --> <ul> <li v-for="(value,key) of cars" :key="key"> {{key}}-{{value}} </li> </ul> <!-- 遍历字符串 --> <ul> <li v-for="(char,index) of str" :key="index"> {{index}}-{{char}} </li> </ul> <!-- 遍历指定次数 --> <ul> <li v-for="(number,index) of 5" :key="index"> {{index}}-{{number}} </li> </ul> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm=new Vue({ el:#root, data:{ persons:[ {id:001,name:张三,age:18}, {id:002,name:李四,age:17}, {id:003,name:王五,age:42}, ], cars:{ name:Audi, price:"70W", color:"black" }, str:"hello" } }) </script> </body> for in和for offor in一般遍历对象 ,不建议遍历数组 。遍历数组请使用for of或forEach 。
v-for中的索引(item ,index) in items
注:v-for中的item项和index索引都是形参,任意命名
key作用和原理当列表的数据变化(添加 、删除)时 ,vue会尽可能复用已存在的DOM元素 ,从而提升渲染的性能,但这种性能优化策略会导致有状态的列表无法被正确更新 ,key的使用将减少不必要的DOM操作 ,提高更新效率 。
解释:
Vue根据初始数据生成初始虚拟DOM(Vnodes),将虚拟DOM转为真实DOM ,用户添加新的数据 ,产生新虚拟DOM(Vnodes) ,此时将两份虚拟DOM根据key进行对比(diff 算法) ,如果对比一样的直接复用 ,将之前的真实DOM直接渲染;不一样的无法复用 ,将其生成真实DOM 。
如果使用index作为key ,diff对比时会完全错位 ,所有节点都无法复用 ,效率降低 。 如果不指定key时,vue自动使用遍历时的索引值index作为key 。为了给vue一个提示 ,以便它能跟踪每个节点的身份 ,需要为每项提供一个唯一的key属性
注:
key只能是字符串或数字类型
key的值必须具有唯一性
建议把数据项id属性的值作为key的值,将index的值作为key的值没有任何意义(https://blog.csdn.net/z591102/article/details/106682298/)
建议使用v-for时一定要指定key的值(提升性能 ,防止列表状态紊乱)
但不存在对数据的操作 ,仅是渲染列表用于展示,使用index作为key没有问题
其他内置指令v-cloak没有值 ,配合CSS ,解决网速慢 、服务器响应慢时未经解析的模板渲染到页面上 ,Vue实例创建并接管容器后 ,会删掉该属性 。
[v-cloak]:{ display:none; }v-once没有值 ,记录初始值 ,在初次动态渲染后 ,就视为静态内容 ,以后数据的改变不会引起v-once所在结构的更新 ,可以用于性能优化 。
v-pre没有值,跳过其所在节点的编译过程 ,可以用它跳过:没有使用指令语法 、插值语法的节点 ,会加快编译 。
自定义指令本质:将原生操作DOM进行二次封装。
<body> <div id="root"> <!-- v-big放大10倍 --> <h2>当前的n值是:<span v-text="n"></span></h2> <h2>放大10倍后的n值是:<span v-big="n"></span></h2> <button @click="n++">点位n++</button> <hr> <!-- v-fbind在v-bind基础上,自动获得焦点 --> <input type="text" v-fbind:value="n"> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm=new Vue({ el:#root, data:{ n:0, }, directives:{ //函数式 //何时会被调用:1、指令和元素成功绑定;2 、指令所在的模板被重新解析时 big(element,binding){ element.innerText=binding.value*10 }, //错误写法: fbind(element,binding){ element.value=binding.value element.focus()//.focus()调用时机不对 ,此时input还未被插入页面 }, //对象式 fbind:{ //指令与元素成功绑定时调用 bind(element,binding){ element.value=binding.value }, //指令所在元素被插入页面时调用 inserted(element,binding){ element.focus() }, //指令所在模板被重新解析时调用 update (element,binding) { element.value=binding.value }, } }, }) </script> </body>注意:
命名多个单词使用-分隔; 指令中this的指向是window; 自定义指令默认都是局部指令 ,全局写法:Vue.directive;计算属性
计算属性本质上就是一个function函数,它可以实时监听data中数据的变化 ,并return一个计算后的新值 ,供组件渲染DOM时使用 。
开发者需要以function函数的形式声明到组件的computed节点中
<template> <div> <input type="text" name="" id="" v-model.number="count"> <p>{{count}} 乘以2的值为:{{plus}}</p>//必须当做普通属性使用 </div> </template> <script> export default { name:MyCount, data(){ return{ count:1, } }, //必须定义在computed节点 computed:{ //必须是一个function函数 plus(){ //必须具有返回值 return this.count*2 } //相当于 plus:{ //当读取plus ,get会被调用 ,且返回值作为plus的值 //get何时被调用?1 、初次调用plus;2、所依赖的数据发生变化 get(){ return this.count*2 } } } } </script>侧重于得到一个计算的结果 ,必须有return返回值
计算属性(computed)vs方法(methods):
相对于方法 ,计算属性会缓存计算结果 ,只有计算属性的依赖项发生变化时 ,才会重新进行运算 ,因此计算属性的性能会更好 。
watch侦听器
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作
开发者需要在watch节点之下 ,定义自己的侦听器
<script> export default { name:MyCount, data(){ return{ username:, } }, watch:{ //当username发生改变时 ,调用 handler username:{ handler(newVal,oldVal){ console.log(newVal,oldVal) } } //简写 username(newVal,oldVal){ console.log(newVal,oldVal) } } } </script> <body> <div id="app">{{username}}</div> #导入脚本文件 <script src="https://www.cnblogs.com/gfhcg/archive/2023/03/17/vue.js"></script> <script> const vm=new Vue({ data(){ return{ username:zs } } }) vm.$mount=(#app)//挂载 vm.$wtach(username,{ //第二种写法 handler(newVal,oldVal){ console.log(newVal,oldVal) } }) //简写 vm.$wtach(username,function(newVal,oldVal){ console.log(newVal,oldVal) } }) </script> </body> 应用场景使用watch检测用户名是否可用,监听username值得变化 ,并使用axios发起ajax请求 ,检测当前输入的用户名是否可用
<script> import axios from axios export default { name:MyCount, data(){ return{ username:, } }, watch:{ async username(newVal,oldVal){ console.log(newVal,oldVal) const {data:res}=await axios.get(https://www.escook.cn/api/finduser+newVal) //await简化promise实例对象为数据 console.log(res) } } } </script> immediate选项默认组件在初次加载完毕后不会调用watch侦听器,如果想让watch侦听器立即被调用 ,则需要使用immediate选项
<script> import axios from axios export default { name:MyCount, data(){ return{ username:, } }, watch:{ //不能直接定义成方法 ,要让监听的数据指向一个配置对象 username:{ async handler(newVal,oldVal){ const {data:res}=await axios.get(https://www.escook.cn/api/finduser+newVal) //await简化promise实例对象为数据 console.log(res) }, //立即触发watch侦听器 immediate:true, } } } </script> deep选项当watch侦听的是一个对象 ,如果对象中的属性值发生了变化 ,则无法被监听到 ,需要使用deep选项侦听所有属性的变化。
<script> import axios from axios export default { name:MyCount, data(){ return{ username:, } }, watch:{ //不能直接定义成方法 ,要让监听的数据指向一个配置对象 username:{ async handler(newVal,oldVal){ const {data:res}=await axios.get(https://www.escook.cn/api/finduser+newVal) //await简化promise实例对象为数据 console.log(res) }, deep:true,//监视多级结构(对象)中所有属性的变化 } } } </script> 监视多级结构(对象)中单个属性的变化 <script> import axios from axios export default { name:MyCount, data(){ return{ info:{username:zs,password:123456} } }, watch:{ //不能直接定义成方法 ,要让监听的数据指向一个配置对象 info.username:{//只想监听info.username的属性变化 async handler(newVal,oldVal){ const {data:res}=await axios.get(https://www.escook.cn/api/finduser+newVal) //await简化promise实例对象为数据 console.log(res) }, deep:true, } } } </script> 计算属性vs侦听器 computed能完成的功能 ,watch都可以完成 ,都能完成的,优先使用computed 。 watch可以完成的 ,computed不一定能完成 ,例如watch可以处理异步任务 。 计算属性和侦听器侧重的应用场景不同。前者侧重监听多个值的变化,最终计算返回一个新值
后者侧重于单个数据的变化 ,最终执行特定的业务处理 ,不需要任何返回值
两个原则:
Vue所管理的函数,最好写成普通函数 ,这样this的指向才是vm或组件实例对象 ,否则指向window 。 所有不被Vue所管理的函数(定时器的回调函数 、ajax的回调函数 、Promise的回调函数) ,最好写成箭头函数 ,这样this的指向才是vm或组件实例对象 ,否则指向window 。绑定样式
绑定class样式 <!--字符串写法 ,适用于样式的类名不确定 ,需要动态指定--> <h1 class="basic" :class:"className">Hello World!</h1> <!--数组写法 ,适用于样式的个数和类名都不确定--> <h1 class="basic" :class:"classArr">Hello World!</h1> <!--对象写法 ,适用于样式的个数和类名都确定,但要动态觉得用不用--> <h1 class="basic" :class:"classObj">Hello World!</h1> 绑定style样式 <!--动态指定--> <h1 class="basic" :style="{fontSize: fsize+px;}">Hello World!</h1> <h1 class="basic" :style="styleObj">Hello World!</h1> <h1 class="basic" :style="[styleObj1,styleObj2]">Hello World!</h1>过滤器
(Vue3.x废弃 ,用计算属性、方法代替)
什么是过滤器?过滤器(Filters)常用于文本的格式化 ,本质是一个函数
过滤器应该被添加到js表达式的尾部,由“管道符 ”进行调用
用于插值表达式 用于v-bind属性绑定 定义(局部)过滤器在创建vue实例期间 ,可以在filters节点中定义过 滤器
私有和全局过滤器私有过滤器:只能在被vm实例控制的区域下控制
如果想在多个vue实例之间共享过滤器 ,则可以按照如下格式声明全局过滤器:
<script> vue.filter(capitalize,(str)=>{ return str.charAt(0).toUpperCase() + str.slice(1)+-- }) new Vue... </script>注:如果二者冲突以私有过滤器为准,就近原则
连续调用多个过滤器过滤器可以串联的地调用
{{message | capitalize | maxlength}
过滤器传参过滤器本质是js函数,第一个参数永远是管道符前面的值 ,第二个参数开始才是arg1 、arg2...
{{message | filterA(agr1,arg2)} vue.filter(filterA,(msg,arg1,aarg2)=>{}) 过滤器的兼容性在vue3.x版本中已经剔除了过滤器相关功能 ,可以使用计算方法或属性来代替
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!