Vue指令

内容处理

  • v-once
  • v-text
  • v-html

v-once : 使元素内部的插值表达式只生效一次

<div id="app">
  <p v-once> {{xxxxx}} </p>
</div>

v-text : 元素内容整体替换为指定纯文本数据

  • 与插值表达式区别:插值表达式是用来进行元素动态设置的,v-text是直接将 纯文本内容 设置为 指定数据,会覆盖老元素
  • 只会显示纯文本,添加标签元素,也不会生成标签元素
<div id="app">
  <p v-text="content"> 这段内容会被覆盖 </p>
</div>
new Vue({
  el:"#app",
  data:{
    content:"我是新内容" // 纯文本

    content:"<span> span内容 </span>" // 非纯文本 不会生成span标签
  }
})

v-html :元素内容整体替换为指定的HTML文本

  • 类似于v-text,但是非纯文本可以转换成对应元素
<div id="app">
  <p v-html="content"> 这段内容会被覆盖 </p>
</div>
new Vue({
  el:"#app",
  data:{
    content:"我是新内容" // 纯文本 ok

    content:"<span> span内容 </span>" // 非纯文本 生成span标签
  }
})

属性绑定

v-bind指令:v-bind指令用于动态绑定HTML属性

  • Class绑定
  • Style绑定

内容绑定方法只能处理内容,如果对标签属性进行处理,通过绑定属性

<div id="app">
  <p v-bind:title ="content_title"> 内容 </p>
  <p :title ="content_title"> 内容 </p>  // 简写
</div>
new Vue({
  el:"#app",
  data:{
    content_title :"我是title属性内容",
    demo:"hello"
  }
})
  • v-bind允许使用表达式 , 与插值表达式类似
  • 不允许使用语句内容 <p :class ="var num = 10"> , error
<div id="app">
  <p :class ="'demo'+3"> 内容 </p> // ok
</div>
  • 如果需要一次绑定多个属性,还可以绑定对象。
<div id="#app">
  <p v-bind="attrObj"> 内容 </p>
</div>
new Vue({
  el:"#app",
  data:{
    attrObj:{

      id :"box", // id属性

      title :"我是title", // title属性

      class :"clsbox", // class属性

      'data-title':"这是内容" // 自定义属性
    }
  }
})

Class绑定

  • class是HTML属性,可以通过v-bind进行绑定,并且可以与class属性共存
<div id="app">
  <p class="a" :class= "clsbox"> 内容 </p>
</div>
new Vue({
  el:"#app",
  data:{
    clsbox:"x" // 此时添加了两个class 一个 "a" 一个 "x", clsbox是动态绑定的
  }
})

注意事项

  • 元素多个动态类名的绑定的错误写法
<p class="a" :class= "clsbox clsbox1 clsbox2"> 内容 </p>  // error

<p class="a" :class= "clsbox"> 内容 </p>  // ok
new Vue({
  el:"#app",
  data:{
    clsbox:"x y z" // 多动态名称 不常用

    // clsbox1:"y"
    // clsbox2:"z"
  }
})
  • 三元运算动态添加 class
<p class="a" :class= "bol ? clsbox1 : clsbox2"> 内容 </p>  // ok
new Vue({
  el:"#app",
  data:{
    bol:true,
    clsbox1:"y",
    clsbox2:"z"
  }
})
  • 如果类名既有条件判断,又同时存在多个类名,组合则写法比较复杂。对于class绑定,Vue.js中还提供了特殊处理方式。
  • 对象表示法,键表示类名,值表示键是否生效。对于带横线类名用引号包裹
<p :class= "{ b:isB, c:isC, 'class-d':true }"> 内容 </p>
new Vue({
  el:"#app",
  data:{
    isB:true,
    isC:false
  }
})
  • 数组表示法,对 对象表示法 的扩展
<p :class= "['a',{ b:isB, 'class-d':true }, c]"> 内容 </p>
new Vue({
  el:"#app",
  data:{
    isB:false,   // 此时有 a class-d z 三个属性
    c:"z"
  }
})

Style绑定

  • style是HTML属性,可以通过v-bind进行绑定,并且可以与style属性共存。
  • 不建议写在行内不好维护,建议从 data 中获取 , 注意要加单位px等。
  • 相同属性,框架会优先取 绑定的属性的值
<p style="width=50px;" :style= "styleObj"> 内容 </p>
new Vue({
  el:"#app",
  data:{
    styleObj:{
      width:'100px',  // 覆盖之前设置的 50px width
      height:'100px',
      border:'1px solid #ccc',
      backgroundColor:'red', // 驼峰
      'font-size':'30px' // 非驼峰
    }
  }
})
  • 当我们希望给元素绑定多个样式对象时,可以设置为数组
<p :style= "[styleObj1 , styleObj2]"> 内容 </p>
new Vue({
  el:"#app",
  data:{
    styleObj1:{ ... },
    styleObj2:{ ... }
  }
})

常用于公共样式和单独样式的组合,如图

image.png

渲染指令

  • v-for
  • v-show
  • v-if

v-for指令

  • 用于遍历数据渲染结构,常用的数组与对象均可遍历。
  • 哪个元素要多次创建,将指令添加到哪个元素
  • 遍历时的参数: index为索引,key为键
<div id="app">
  <ul>
    <li v-for="(item,index) in arr">{{ item }}</li> // 数组
  </ul>

  <ul>
    <li v-for="(val,key,index) in obj">{{ val }}</li> // 对象
  </ul>
</div>
new Vue({
  el:"#app",
  data:{
    arr:["1","asd",2],
    obj:{ 
      content1:"内1",
      content2:"内2"
    }
  }
})
  • 数值遍历 : 适用于没有基础数据,凭空创建 数值个 元素
<div id="app">
  <ul>
    <li v-for="(item,index) in 5">{{ item }}</li>  // 1,2,3,4,5
  </ul>
</div>

注意事项

  • 使用v-for的同时,应始终指定唯一的 key属性
  • key属性是通过 v-bind 绑定的一个属性,是标识 每项的 唯一值
  • for循环中 index下标 无法作为 key,如果属性值也不唯一(无法作为key)。可以把数据改成对象,添加唯一key属性
  • 为什么会要添加key?
    • vue.js 在进行结构渲染时,会为了提高执行效率,对于结构一致的内容只进行修补操作,不会进行移除替换,因此用户输入的内容得以保留未被删除。

如图,初始时文本1->输入框1,一一对应。当控制台执行 vm.arr.reverse()

vue 修改而非替换的操作,会导致结构和内容不一致

正确写法

<ul>
  <li v-for="item in items" :key="item.id">{{ item }}</li>
</ul>

  • 通过<template>标签设置模板占位符,可以将部分元素或内容作为整体进行操作。
  • template 不会生成标签,只是占位符,内部内容是个整体,可以只对整体进行重复添加。
  • 如果用div,会额外增加div标签,可能并不是我们想要的结构。
  • 由于 template 本身不是元素,无法绑定 key 属性
<div id="app">
  <template v-for="(item,index) in items">
    <span>{{ 标签内容1 }}</span>
    <span>{{ 标签内容2 }}</span>
  </template>
</div>

v-show指令

  • 用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用
  • 通过display 控制元素显示和隐藏
<div id="app">
  <p v-show="true">这个元素显示</p>
  <p v-show="false">这个元素隐藏</p>
  <p v-show="2>11">这个元素隐藏</p>
  <p v-show="bol">这个元素看bol值</p>
</div>

注意事项:

  • template无法使用 v-show 指令,不是元素

v-if指令

  • 用于根据条件控制元素的创建与移除。
  • 不适合频繁的显示隐藏,因为他是移除和创建,是消耗性能的操作
<div id="app">
  <p v-if="false">这个元素不会创建</p>
  <p v-else-if="true">这个元素会创建</p>
  <p v-else-if="true">这个元素不会创建</p> // 上一个进了这个不会进
  <p v-else>这个元素不会创建</p>
</div>

注意事项:

  • 给使用v-if 的同类型元素绑定不同的 key

如图,添加了v-ifv-else

  • bool=true时,代码会运行至 v-if,此时给输入框输入123。
  • 修改 bool,当bool=false时,代码会执行v-else内的代码,输入框内的 123 也被第二个输入框保留
  • 这种代码方式 应用于在用户登陆时,使用账号,手机号,邮箱等 , 样式一致,但是不同功能元素切换登录时,输入框内判断逻辑不同肯定是不同的。
  • 问题也发生在,vue对相同结构进行修补,而不是移除旧的,创建新的

[图片上传失败...(image-79f687-1625222078272)]

正确做法,添加key绑定

<div id="app">
  <p v-if=" type === 'username' " :key="'username'">
    用户输入框: <input type="text">
  </p>
  <p v-else :key="'email'">
    邮箱输入框: <input type="text">
  </p>
</div>

  • 出于性能考虑,应避免将v-if 与v-for应用于同一标签

例如有个列表,要通过指定数据 v-for 循环创建, 同时列表内每项的 创建和移除 还要取决于某个条件

v-for的优先级会更高,如果此时v-if=false,则v-for执行是毫无意义的,还会消耗不必要的性能

解决办法,创建列表循环的v-for操作赋予子元素liv-if条件判断赋予父元素ul

此函数执行效率很低

<div id="app">
  <ul>
    <li v-if="false" v-for="item in items">{{ item }}</li>
  </ul>
</div>
new Vue({
  el:"#app",
  data:{
    items:{ 
      content1:"内1",
      content2:"内2",
      content3:"内3",
    }
  }
})

修改后

<div id="app">
  <ul v-if="false">   // 放到父元素,false时 内部的 v-for不会被执行
    <li v-for="item in items">{{ item }}</li>
  </ul>
</div>

其他修改方法,既然遍历的循环对象有判断,那么我们把判断写在方法内,即在遍历前处理遍历的数据

<div id="app">
  <ul>
    <li v-for="item in handleItems()">{{ item }}</li>
  </ul>
</div>

事件处理

  • v-on

v-on指令

  • 用于进行元素的事件绑定。
  • 当事件处理程序较少时,可以直接写在行内,尽量不要,不好维护
  • 可以指定 methods 函数 处理事件
<div id="app">
  <p>{{ content }}</p>

  <button v-on:click=" content='新内容' ">按钮</button>

  <button @click=" content='新内容' ">按钮</button>   // 简写

  <button @click="fn">按钮</button>   // methods 函数设置
</div>
new Vue({
  el:"#app",
  data:{
    content:"默认内容"
  },
  methods:{
    fn(){
      this.content='新内容'
    }
  }
})
  • 设置事件处理程序后,可以从参数中接收事件对象 event。
new Vue({
  el:"#app",
  data:{
    content:"默认内容"
  },
  methods:{
    fn(event){   // 接收事件对象
      console.log(event) 
    }
  }
})
  • 在 视图中 可以通过 $event 访问事件对象。
  • 当传参时也想访问event事件对象,可以通过传入 $event在 方法中获取 event 对象
<div id="app">
  <p>{{ content }}</p>

  <button @click="fn(content, $event)">按钮</button> // 自己传参也想访问event事件对象时
</div>
new Vue({
  el:"#app",
  data:{
    content:"默认内容"
  },
  methods:{
    fn(content,event){
      console.log(content)
      console.log(event)
    }
  }
})

表单输入绑定

  • v-model

v-model指令

  • 用于给可输入元素 <input><textarea><select>元素设置双向数据绑定。
  • 当输入框输入时,依赖v-model的变量的元素都会动态改变
  • v-model 不能使用表达式,如果要计算,可以添加计算属性双向绑定
  • v-model 实质就是 v-bind+v-on:input事件结合
<div id="app">
  <p>{{ value }}</p>

  <input type="text" v-model="value">
</div>
new Vue({
  el:"#app",
  data:{
    value:""
  }
})

输入框绑定

输入框分为单行输入框input与多行输入框 textarea

<div id="app">
  <p>{{ value1 }}</p>
  <input type="text" v-model="value1">

  <p>{{ value2 }}</p>
  <textarea v-model="value2"></textarea>
</div>

单选按钮绑定

单选按钮的双向数据绑定方式如下:

<div id="app">
  <p>{{ value3 }}</p>

  <input type="radio" id="one" value="1" v-model="value3">
  <label for="one">选项一</label>
  
  <input type="radio" id="two" value="2" v-model="value3">
  <label for="two">选项二</label>
</div>
new Vue({
  el:"#app",
  data:{
    value3:""  // 选哪个,哪个input 的 value 就会赋给 value3
  }
})

复选框绑定

复选框绑定分为单个选项与多个选项两种情况,书写方式不同

单个复选框应用,可勾可取消

<div id="app">
  <p>单复选框: {{ value4 }}</p>
  <input type="checkbox" id="item" value="内容" v-model="value4">
  <label for="item">选项</label>
  
  <p>多复选框: {{ value5 }}</p>
  <input type="checkbox" id="one" value="选项一内容" v-model="value5">
  <label for="one">选项一</label>
  <input type="checkbox" id="two" value="选项二内容" v-model="value5">
  <label for="two">选项二</label>
</div>

单复选和多复选区别在于

  • 点击单复选时,返回true / false表示是否勾选, value4值不会返回。但是value4依然要设置,如果处理作表单提交,提交的值是value4
  • 多复选是个数组,存放每个复选框的value5值,且value5值必须不同
new Vue({
  el:"#app",
  data:{
    value4:"",  // 单复选
    value5:[] // 多复选
  }
})

选择框绑定

选择框绑定分为单选绑定与多选绑定两种情况,书写方式不同。

<div id="app">
  <p>单选select: {{ value6 }}</p>  // 显示的是option的value值
  <select v-model="value6">   // v-model绑定给select
    <option value="">请选择</option> // 默认选项,无实际意义
    <option value="1">选项一</option>
    <option value="2">选项二</option>
    <option value="3">选项三</option>
  </select>
  
  <p>多选select: {{ value7 }}</p>
  <select v-model="value7" multiple>
    <option value="1">选项一</option>
    <option value="2">选项二</option>
    <option value="3">选项三</option>
  </select>
</div>
var vm = new Vue({
  data:{
    value6:'',
    value7:[]
  },
}).$mount("#app")

按住ctrl进行多选

v-model 小结

  • input输入框:绑定字符串值。
  • textarea输入框:绑定字符串值。
  • radio:绑定字符串值。
  • checkbox:单个绑定布尔值,多个绑定数组。
  • select:单选绑定字符串,多选绑定数组。

欢迎赞赏关注!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容

  • 页面展示 基本指令 v-text用于在页面中展示数据,可以简写为{{ }}的形式 {{msg}} <!--这两...
    羊烊羴阅读 1,469评论 0 0
  • 注意: 1、所谓指令,其实就是元素的属性 2、所有的指令,前提是在js中声明了是Vue对象 3、参数 1、静态参数...
    张浩琦阅读 314评论 0 0
  • 什么是指令 官方解释: 指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 att...
    仰望_IT阅读 297评论 0 0
  • 1.文本渲染 v-text:更新元素的innerTextv-html:更新元素的innerHTMLv-once:静...
    John_Phil阅读 520评论 0 0
  • VM: vm是指MVVM中的viewmodel层.主要用来监听同步model层data中数据,将数据放在元素内容区...
    asdf2333阅读 171评论 0 0