vue2.0+vue3.0资料(三)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: vue2.0+vue3.0资料(三)

11-2、v-if 和v-show


条件渲染:
1.v-if
写法:
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。v-if是通过控制dom节点的存在与否来控制元素的显隐。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。


2.v-show
写法:v-show="表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是通过设置DOM元素的display样式设置显隐。(display中block为显示,none为隐藏)
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>条件渲染</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>当前的n值是:{{n}}</h2>
   <button @click="n++">点我n+1</button>
   <!-- 使用v-show做条件渲染 -->
   <!-- <h2 v-show="false">欢迎来到{{name}}</h2> -->
   <!-- <h2 v-show="1 === 1">欢迎来到{{name}}</h2> -->
   <!-- 使用v-if做条件渲染 -->
   <!-- <h2 v-if="false">欢迎来到{{name}}</h2> -->
   <!-- <h2 v-if="1 === 1">欢迎来到{{name}}</h2> -->
   <!-- v-else和v-else-if -->
   <!-- <div v-if="n === 1">Angular</div>
   <div v-else-if="n === 2">React</div>
   <div v-else-if="n === 3">Vue</div>
   <div v-else>哈哈</div> -->
   <!-- template只能与v-if配合使用,不能和v-show配合 ,template不影响结构,把template改为div影响结构-->
   <template v-if="n === 1">
    <h2>你好</h2>
    <h2>111</h2>
    <h2>北京</h2>
   </template>
  </div>
 </body>
 <script type="text/javascript">
  const vm = new Vue({
   el:'#app',
   data:{
    name:'111',
    n:0
   }
  })
 </script>
</html>


12、列表渲染


12-1、基本列表


v-for指令:
1.用于展示列表数据
2.语法:v-for="(item, index) in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)


案例:


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>基本列表</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <!-- 遍历数组 -->
   <h2>人员列表(遍历数组)</h2>
   <ul>
    <!-- <li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</li> -->
    <li v-for="(p,index) of persons" :key="index">
    {{p.name}}-{{p.age}}
    </li>
   </ul>
   <!-- 遍历对象 -->
   <h2>汽车信息(遍历对象)</h2>
   <ul>
    <li v-for="(value,k) of car" :key='k'>
    {{k}}-{{value}}
    </li>
   </ul>
   <!-- 遍历字符串 -->
   <h2>测试遍历字符串(用得少)</h2>
   <ul>
    <li v-for="(char,index) of str" :key="index">
    {{char}}-{{index}}
    </li>
   </ul>
   <!-- 遍历指定次数 -->
   <h2>测试遍历指定次数(用得少)</h2>
   <ul>
    <li v-for="(number,index) of 5" :key="index">
    {{index}}-{{number}}
    </li>
   </ul>
  </div>
  <script type="text/javascript">
   new Vue({
    el:'#app',
    data:{
     persons:[
      {id:'001',name:'张三',age:18},
      {id:'002',name:'李四',age:19},
      {id:'003',name:'王五',age:20},
     ],
     car:{
      name:'奥迪A8',
      price:'70万',
      color:'黑色'
     },
     str:'hello'
    }
   })
  </script>
</html>


12-2、key的原理


网络异常,图片无法展示
|


面试题:react、vue中的key有什么作用?(key的内部原理)


1、虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:


对比规则
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。


 (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。


2、用index作为key或者不声明key的时候(此时默认key的value值为index时)可能会引发的问题:


   (1).若对数据进行:逆序添加、逆序删除等破坏顺序操作:
    会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。


   (2).如果结构中还包含输入类的DOM:
    会产生错误DOM更新 ==> 界面有问题。


3、开发中如何选择key?:
(1).最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
(2).如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>key的原理</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <!-- 遍历数组 -->
   <h2>人员列表(遍历数组)</h2>
   <button type="button" @click.once="add">添加一个老刘</button>
   <ul>
    <li v-for="(p,index) of persons" :key="index">
    {{p.name}}-{{p.age}}
    </li>
   </ul>
  </div>
  <script type="text/javascript">
   new Vue({
    el:'#app',
    data:{
     persons:[
      {id:'001',name:'张三',age:18},
      {id:'002',name:'李四',age:19},
      {id:'003',name:'王五',age:20},
     ],
    },
    methods:{
     add(){
      const p={
       id:'004',
       name:'老刘',
       age:40
      }
      this.persons.unshift(p)
     }
    }
   })
  </script>
</html>


12-3、列表过滤


filter():用于把Array中的某些元素过滤掉,然后返回剩下的元素


'abc'.indexOf(a)   判断字符出现的索引位置,没有就返回-1


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>列表过滤</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>人员列表</h2>
   <input type="text" placeholder="请输入名字" v-model="keyWord">
   <ul>
    <li v-for="(p,index) of filPerons" :key="index">
     {{p.name}}-{{p.age}}-{{p.sex}}
    </li>
   </ul>
  </div>
  <script type="text/javascript">
   Vue.config.productionTip = false
   //用watch实现
   //#region 
   /* new Vue({
    el:'#app',
    data:{
     keyWord:'',
     persons:[
      {id:'001',name:'马冬梅',age:19,sex:'女'},
      {id:'002',name:'周冬雨',age:20,sex:'女'},
      {id:'003',name:'周杰伦',age:21,sex:'男'},
      {id:'004',name:'温兆伦',age:22,sex:'男'}
     ],
     filPerons:[]
    },
    watch:{
     keyWord:{
      immediate:true,
      handler(val){
       this.filPerons = this.persons.filter((p)=>{
        return p.name.indexOf(val) !== -1
       })
      }
     }
    }
   }) */
   //#endregion
   //用computed实现
   new Vue({
    el:'#app',
    data:{
     keyWord:'',
     persons:[
      {id:'001',name:'马冬梅',age:19,sex:'女'},
      {id:'002',name:'周冬雨',age:20,sex:'女'},
      {id:'003',name:'周杰伦',age:21,sex:'男'},
      {id:'004',name:'温兆伦',age:22,sex:'男'}
     ]
    },
    computed:{
     filPerons(){
      return this.persons.filter((p)=>{
       return p.name.indexOf(this.keyWord) !== -1
      })
     }
    }
   }) 
  </script>
</html>


12-4、列表排序


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>列表排序</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>人员列表</h2>
   <input type="text" placeholder="请输入名字" v-model="keyWord">
   <button @click="sortType = 2">年龄升序</button>
   <button @click="sortType = 1">年龄降序</button>
   <button @click="sortType = 0">原顺序</button>
   <ul>
    <li v-for="(p,index) of filPerons" :key="p.id">
     {{p.name}}-{{p.age}}-{{p.sex}}
     <input type="text">
    </li>
   </ul>
  </div>
  <script type="text/javascript">
   new Vue({
    el:'#app',
    data:{
     keyWord:'',
     sortType:0, //0原顺序 1降序 2升序
     persons:[
      {id:'001',name:'马冬梅',age:30,sex:'女'},
      {id:'002',name:'周冬雨',age:31,sex:'女'},
      {id:'003',name:'周杰伦',age:18,sex:'男'},
      {id:'004',name:'温兆伦',age:19,sex:'男'}
     ]
    },
    computed:{
     filPerons(){
      const arr = this.persons.filter((p)=>{
       return p.name.indexOf(this.keyWord) !== -1
      })
      //判断一下是否需要排序
      if(this.sortType){
       arr.sort((p1,p2)=>{
        return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
       })
      }
      return arr
     }
    }
   }) 
  </script>
</html>

12-5、更新时的一个问题


Vue里面原本就有一个watch,而侦听属性的watch是给程序员用的。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>更新时的一个问题</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>人员列表</h2>
   <button @click="updateMei">更新马冬梅的信息</button>
   <ul>
    <li v-for="(p,index) of persons" :key="p.id">
     {{p.name}}-{{p.age}}-{{p.sex}}
    </li>
   </ul>
  </div>
  <script type="text/javascript">
   Vue.config.productionTip = false
   const vm = new Vue({
    el:'#app',
    data:{
     persons:[
      {id:'001',name:'马冬梅',age:30,sex:'女'},
      {id:'002',name:'周冬雨',age:31,sex:'女'},
      {id:'003',name:'周杰伦',age:18,sex:'男'},
      {id:'004',name:'温兆伦',age:19,sex:'男'}
     ]
    },
    methods: {
     updateMei(){
      // this.persons[0].name = '马老师' //奏效
      // this.persons[0].age = 50 //奏效
      // this.persons[0].sex = '男' //奏效
      // this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效
      this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:'男'})//这是最后得出的结论
     }
    }
   }) 
  </script>
</html>

12-6、模拟一个Vue数据监测


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>Document</title>
 </head>
 <body>
  <script type="text/javascript" >
   let data = {
    name:'111',
    address:'222',
   }
   //创建一个监视的实例对象,用于监视data中属性的变化
   const obs = new Observer(data)  
   console.log(obs) 
   //准备一个vm实例对象
   let vm = {}
   vm._data = data = obs
   function Observer(obj){
    //汇总对象中所有的属性形成一个数组
    const keys = Object.keys(obj)
    //遍历
    keys.forEach((k)=>{
     Object.defineProperty(this,k,{
      get(){
       return obj[k]
      },
      set(val){
       console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
       obj[k] = val
      }
     })
    })
   }
  </script>
 </body>
</html>


12-7、Vue监测数据改变的原理__对象


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>Vue监测数据改变的原理</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>学校名称:{{name}}</h2>
   <h2>学校地址:{{address}}</h2>
  </div>
 </body>
 <script type="text/javascript">
  const vm = new Vue({
   el:'#app',
   data:{
    name:'111',
    address:'222',
    student:{
     name:'tom',
     age:{
      rAge:40,
      sAge:29,
     },
     friends:[
      {name:'jerry',age:35}
     ]
    }
   }
  })
 </script>
</html>

12-8、Vue.set()方法


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>Vue.set()使用方法</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h1>学校信息</h1>
   <h2>学校名称:{{school.name}}</h2>
   <h2>学校地址:{{school.address}}</h2>
   <h2>校长是:{{school.leader}}</h2>
   <hr/>
   <h1>学生信息</h1>
   <button @click="addSex">添加一个性别属性,默认值是男</button>
   <h2>姓名:{{student.name}}</h2>
   <h2 v-if="student.sex">性别:{{student.sex}}</h2>
   <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
   <h2>朋友们</h2>
   <ul>
    <li v-for="(f,index) in student.friends" :key="index">
     {{f.name}}--{{f.age}}
    </li>
   </ul>
  </div>
 </body>
 <script type="text/javascript">
  const vm = new Vue({
   el:'#app',
   data:{
    school:{
     name:'111',
     address:'222',
    },
    student:{
     name:'tom',
     age:{
      rAge:40,
      sAge:29,
     },
     friends:[
      {name:'jerry',age:35},
      {name:'tony',age:36}
     ]
    }
   },
   methods: {
    addSex(){
     // Vue.set(this.student,'sex','男')
     this.$set(this.student,'sex','男')
    }
   }
  })
 </script>
</html>

12-9、Vue监测数据改变的原理__数组


在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set()


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>Vue监测数据改变的原理_数组</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h1>学生信息</h1>
   <h2>爱好</h2>
   <ul>
    <li v-for="(h,index) in student.hobby" :key="index">
     {{h}}
    </li>
   </ul>
  </div>
 </body>
 <script type="text/javascript">
  const vm = new Vue({
   el:'#app',
   data:{
    student:{
     hobby:['抽烟','喝酒','烫头'],
    }
   },
  })
 </script>
</html>

12-10、总结Vue数据监测


Vue监视数据的原理:


1.vue会监视data中所有层次的数据。


2.如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:

Vue.set(target,propertyName/index,value)
      vm.$set(target,propertyName/index,value)

3.如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。


4.在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.

网络异常,图片无法展示
|
set() 不能给vm 或 vm的根数据对象 添加属性!!!


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>总结数据监视</title>
  <style>
   button{
    margin-top: 10px;
   }
  </style>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h1>学生信息</h1>
   <button @click="student.age++">年龄+1岁</button> <br/>
   <button @click="addSex">添加性别属性,默认值:男</button> <br/>
   <button @click="student.sex = '未知' ">修改性别</button> <br/>
   <button @click="addFriend">在列表首位添加一个朋友</button> <br/>
   <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
   <button @click="addHobby">添加一个爱好</button> <br/>
   <button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
   <button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
   <h3>姓名:{{student.name}}</h3>
   <h3>年龄:{{student.age}}</h3>
   <h3 v-if="student.sex">性别:{{student.sex}}</h3>
   <h3>爱好:</h3>
   <ul>
    <li v-for="(h,index) in student.hobby" :key="index">
     {{h}}
    </li>
   </ul>
   <h3>朋友们:</h3>
   <ul>
    <li v-for="(f,index) in student.friends" :key="index">
     {{f.name}}--{{f.age}}
    </li>
   </ul>
  </div>
 </body>
 <script type="text/javascript">
  Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  const vm = new Vue({
   el:'#app',
   data:{
    student:{
     name:'tom',
     age:18,
     hobby:['抽烟','喝酒','烫头'],
     friends:[
      {name:'jerry',age:35},
      {name:'tony',age:36}
     ]
    }
   },
   methods: {
    addSex(){
     // Vue.set(this.student,'sex','男')
     this.$set(this.student,'sex','男')
    },
    addFriend(){
     this.student.friends.unshift({name:'jack',age:70})
    },
    updateFirstFriendName(){
     this.student.friends[0].name = '张三'
    },
    addHobby(){
     this.student.hobby.push('学习')
    },
    updateHobby(){
     // this.student.hobby.splice(0,1,'开车')
     // Vue.set(this.student.hobby,0,'开车')
     this.$set(this.student.hobby,0,'开车')
    },
    removeSmoke(){
     this.student.hobby = this.student.hobby.filter((h)=>{
      return h !== '抽烟'
     })
    }
   }
  })
 </script>
</html>


12-11、数据劫持


数据劫持:
指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。比较典型的是Object.defineProperty()和 ES2016 中新增的Proxy对象。数据劫持最著名的应用当属双向绑定,这也是一个已经被讨论烂了的面试必考题。例如 Vue 2.x 使用的是Object.defineProperty()(Vue 在 3.x 版本之后改用 Proxy 进行实现)。


Vue的双向绑定就是利用 Object.defineProperty(),并且把内部解耦为 Observer, Dep, 并使用 Watcher 相连。


数组的以下几个方法不会触发 set:(push、pop、shift、unshift、splice、sort、reverse   )


Vue 把这些方法定义为变异方法 ,指的是会修改原来数组的方法。与之对应则是非变异方法 ,例如 filter, concat, slice 等,它们都不会修改原始数组,而会返回一个新的数组。




13、收集表单数据


收集表单数据:


若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。


若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。

若:<input type="checkbox"/>

  1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)

  2.配置input的value属性:

  (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

  (2)v-model的初始值是数组,那么收集的的就是value组成的数组


备注:v-model的三个修饰符:
 lazy:失去焦点再收集数据
  number:输入字符串转为有效的数字
 trim:输入首尾空格过滤


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>收集表单数据</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <form @submit.prevent="demo">
    账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
    密码:<input type="password" v-model="userInfo.password"> <br/><br/>
    年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
    性别:
    男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
    女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
    爱好:
    学习<input type="checkbox" v-model="userInfo.hobby" value="study">
    打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
    吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
    <br/><br/>
    所属校区
    <select v-model="userInfo.city">
     <option value="">请选择校区</option>
     <option value="beijing">北京</option>
     <option value="shanghai">上海</option>
     <option value="shenzhen">深圳</option>
     <option value="wuhan">武汉</option>
    </select>
    <br/><br/>
    其他信息:
    <textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
    <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="###">《用户协议》</a>
    <button>提交</button>
   </form>
  </div>
 </body>
 <script type="text/javascript">
  new Vue({
   el:'#app',
   data:{
    userInfo:{
     account:'',
     password:'',
     age:18,
     sex:'female',
     hobby:[],
     city:'beijing',
     other:'',
     agree:''
    }
   },
   methods: {
    demo(){
     console.log(JSON.stringify(this.userInfo))
    }
   }
  })
 </script>
</html>


14、过滤器


过滤器:(定义、语法、备注)
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据, 是产生新的对应的数据


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>过滤器</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
  <script type="text/javascript" src="Vue/js/dayjs.min.js"></script>
 </head>
 <body>
  <div id="app">
   <h2>显示格式化后的时间</h2>
   <!-- 计算属性实现 -->
   <h3>现在是:{{fmtTime}}</h3>
   <!-- methods实现 -->
   <h3>现在是:{{getFmtTime()}}</h3>
   <!-- 过滤器实现 -->
   <h3>现在是:{{time | timeFormater}}</h3>
   <!-- 过滤器实现(传参) -->
   <h3>现在是:{{time | timeFormater('YYYY_MM_DD')}}</h3>
   <!-- 多个过滤器的串联 -->
   <h3>现在是1:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
   <h3 :x="msg | mySlice">学校名字</h3>
  </div>
  <div id="app2">
   <h2>{{msg | mySlice}}</h2>
  </div>
 </body>
 <script type="text/javascript">
  //全局过滤器
  Vue.filter('mySlice',function(value){
   return value.slice(0,4)
  })
  new Vue({
   el:'#app',
   data:{
    time:1621561377603, //时间戳
    msg:'你好,111'
   },
   computed: {
    fmtTime(){
     return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
    }
   },
   methods: {
    getFmtTime(){
     return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
    }
   },
   //局部过滤器
   filters:{
    timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){//如果str有值使用str传的,如果没有则使用这里的''里面默认的值
     // console.log('@',value)
     return dayjs(value).format(str)
    }
   }
  })
  new Vue({
   el:'#app2',
   data:{
    msg:'hello,222!'
   }
  })
 </script>
</html>

15、内置指令


有哪些?


v-bind   : 单向绑定解析表达式, 可简写为 :xxx

v-model   : 双向数据绑定

v-for     : 遍历数组/对象/字符串

v-on      : 绑定事件监听, 可简写为@

v-if    : 条件渲染(动态控制节点是否存存在)

v-else    : 条件渲染(动态控制节点是否存存在)

v-show    : 条件渲染 (动态控制节点是否展示)

v-text指令 : 向其所在的节点中渲染文本内容。

v-html指令 : 向指定节点中渲染包含html结构的内容。

v-cloak指令: 解决网速慢时页面展示出{{xxx}}的问题

v-once指令 : 所在节点初次动态渲染后,就视为静态内容

v-pre指令  : 跳过其所在节点的编译过程


15-1、v-text指令


v-text指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>v-text指令</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <div>你好,{{name}}</div>
   <div v-text="name"></div>
   <div v-text="str"></div>
  </div>
 </body>
 <script type="text/javascript"> 
  new Vue({
   el:'#app',
   data:{
    name:'111',
    str:'<h3>你好啊!</h3>'
   }
  })
 </script>
</html>


15-2、v-html指令


v-html的安全性(cookie)


v-html指令:
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!



         

15-3、v-cloak指令


v-cloak指令(没有值):
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>v-cloak指令</title>
  <style>
   [v-cloak]{
    display:none;
   }
  </style>
 </head>
 <body>
  <div id="app">
   <h2 v-cloak>{{name}}</h2>
  </div>
  <!-- 这里可以调整延迟时间为5s -->
  <script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
 </body>
 <script type="text/javascript">
  console.log(1)
  new Vue({
   el:'#app',
   data:{
    name:'111'
   }
  })
 </script>
</html>

15-4、v-once指令


v-once指令:
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>v-once指令</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <!-- 这里只会渲染一次打开页面后就让值定格在1了-->
   <h2 v-once>初始化的n值是:{{n}}</h2>
   <h2>当前的n值是:{{n}}</h2>
   <button @click="n++">点我n+1</button>
  </div>
 </body>
 <script type="text/javascript">
  new Vue({
   el:'#app',
   data:{
    n:1
   }
  })
 </script>
</html>


15-5、v-pre指令


v-pre指令:
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>v-pre指令</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <div id="app">
   <h2 v-pre>Vue其实很简单</h2>
   <h2 >当前的n值是:{{n}}</h2>
   <button @click="n++">点我n+1</button>
  </div>
 </body>
 <script type="text/javascript">
  new Vue({
   el:'#app',
   data:{
    n:1
   }
  })
 </script>
</html>


16、自定义指令


16-1、回顾一个DOM操作


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>Document</title>
  <style>
   .demo{
    background-color: orange;
   }
  </style>
 </head>
 <body>
  <button id="btn">点我创建一个输入框</button>
  <script type="text/javascript" >
   const btn = document.getElementById('btn')
   btn.onclick = ()=>{
    const input = document.createElement('input')
    input.className = 'demo'
    input.value = 99
    input.onclick = ()=>{alert(1)}
    document.body.appendChild(input)
    input.focus()
    // input.parentElement.style.backgroundColor = 'skyblue'
    console.log(input.parentElement)
   }
  </script>
 </body>
</html>


16-2、自定义指令操作


自定义指令总结:
一、定义语法:


(1).局部指令


new Vue({ 
 directives:{指令名:配置对象}         
}) 
new Vue({
 directives{指令名:回调函数}
})

(2).全局指令


Vue.directive(指令名,配置对象)

Vue.directive(指令名,回调函数)


二、配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用。


三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。                  (user-name式命名)


案例如下:


<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>自定义指令</title>
  <script type="text/javascript" src="Vue/js/vue.js"></script>
 </head>
 <body>
  <!-- 
    需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
    需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
  -->
  <div id="app">
   <h2>{{name}}</h2>
   <h2>当前的n值是:<span v-text="n"></span> </h2>
   <!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
   <h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
   <button @click="n++">点我n+1</button>
   <hr/>
   <input type="text" v-fbind:value="n">
  </div>
 </body>
 <script type="text/javascript">
  //定义全局指令
  /* Vue.directive('fbind',{
   //指令与元素成功绑定时(一上来)
   bind(element,binding){
    element.value = binding.value
   },
   //指令所在元素被插入页面时
   inserted(element,binding){
    element.focus()
   },
   //指令所在的模板被重新解析时
   update(element,binding){
    element.value = binding.value
   }
  }) */
  /* Vue.directive('big',function(element,binding){
   console.log('big',this)//注意此处的this是window
   // console.log('big')
   element.innerText=binding.value*10
  }) */
  new Vue({
   el:'#app',
   data:{
    name:'尚硅谷',
    n:1
   },
   directives:{
    //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
    /* 'big-number'(element,binding){
     // console.log('big')
     element.innerText = binding.value * 10
    }, */
    big(element,binding){  //element表示为元素,binding表示为指令与元素的一个关系绑定
     console.log('big',this) //注意(directives)此处的this是window
     // console.log('big')
     // console.dir(a)//console.dir(i) 表示输出(i)这个值到控制台
     // console.log(a instanceof HTMLElement)//instanceof是判断a是不是HTMLElement(网页元素)的实例
     element.innerText = binding.value * 10
    },
    fbind:{
     //指令与元素成功绑定时(一上来)
     bind(element,binding){
      element.value = binding.value
     },
     //指令所在元素被插入页面时
     inserted(element,binding){
      element.focus()
     },
     //指令所在的模板被重新解析时
     update(element,binding){
      element.value = binding.value
      // element.focus()//点击按钮后焦点依旧在这里
     }
    }
   }
  })
 </script>
</html>


目录
相关文章
|
3月前
|
JavaScript
Vue——mergeOptions【四】
Vue——mergeOptions【四】
27 4
|
6月前
|
Web App开发 缓存 JavaScript
Vue3 五天速成(上)
Vue3 五天速成(上)
83 2
|
6月前
|
JavaScript 前端开发 开发者
Vue
Vue.js是一个开源的JavaScript框架,用于构建用户界面。它采用了组件化的开发方式,让开发者可以将复杂的UI界面拆分成独立的可重用组件,并通过组合这些组件来构建整个应用程序。
49 1
Vue
|
6月前
|
JavaScript 前端开发 开发工具
new Vue() 发生了什么?
new Vue() 发生了什么?
52 1
|
6月前
|
JavaScript 前端开发 编译器
Vue3 究竟好在哪里?
Vue3 究竟好在哪里?
119 0
|
6月前
|
JavaScript 前端开发 开发者
new Vue() 发生了什么
new Vue() 发生了什么
53 0
|
6月前
|
JavaScript
vue
vue
64 0
|
设计模式 缓存 JavaScript
|
JavaScript
Vue中,$forceUpdate()的使用
Vue中,$forceUpdate()的使用
88 0
|
JavaScript 前端开发 算法
Vue3详细讲解
Vue3详细讲解
84 0