写点什么

万字血书 Vue—Vue 语法

  • 2023-07-03
    福建
  • 本文字数:7096 字

    阅读完需:约 23 分钟

模板语法


插值语法


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。开源获取:http://www.jnpfsoft.com/?from=infoq


属性绑定指令


v-bind: 为元素的属性动态绑定属性值


属性:placeholder、src 等


简写:


<a v-bind:href="url">点击跳转</a><a :href="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="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 of


for 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="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 可以处理异步任务

  • 计算属性和侦听器侧重的应用场景不同。


  1. 前者侧重监听多个值的变化,最终计算返回一个新值

  2. 后者侧重于单个数据的变化,最终执行特定的业务处理,不需要任何返回值


两个原则:


  • 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 版本中已经剔除了过滤器相关功能,可以使用计算方法或属性来代替


文章转载自:https://www.cnblogs.com/gfhcg/p/17222239.html

原文链接:https://www.cnblogs.com/gfhcg/p/17222239.html

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
万字血书Vue—Vue语法_Vue_不在线第一只蜗牛_InfoQ写作社区