vue CLI_4、本地存储、组件自定义事件

1、webStorage(js在浏览器的本地存储)

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)

  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。

  3. 相关API:

    ①. xxxxxStorage.setItem('key', 'value');
    该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

    ②. xxxxxStorage.getItem('person');

    ​ 该方法接受一个键名作为参数,返回键名对应的值。

    ③. xxxxxStorage.removeItem('key');

    ​ 该方法接受一个键名作为参数,并把该键名从存储中删除。

    ④. xxxxxStorage.clear()

    ​ 该方法会清空存储中的所有数据。

  4. 备注:

    ①. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
    ②. LocalStorage存储的内容,需要手动清除才会消失。
    ③. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
    ④. JSON.parse(null)的结果依然是null。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localStorage</title>
</head>
<body>
    <button onclick="saveData()">点我保存数据</button>
    <button onclick="readData()">点我读取数据</button>
    <button onclick="deleteData()">点我删除数据</button>
    <button onclick="deleteAllData()">点我删除所有数据</button>
    <script>

        let p={name:"张三",age:18}

        function saveData(){
            window.localStorage.setItem("msg","hello2");
            window.localStorage.setItem("p",JSON.stringify(p));
        }

        function readData(){
            console.log(localStorage.getItem("msg"));
            
            const p=JSON.parse(localStorage.getItem("p"));
            console.log(p);
        }

        function deleteData(){
            localStorage.removeItem("msg");
        }

        function deleteAllData(){
            localStorage.clear();
        }
    </script>
    
</body>
</html>

优化TodoList案例,用本地存储来存数据,只需要修改App里的配置对象的data配置项,和添加监视即可。

        data(){
            return{
                //从本地存储里读取数据,为null就创建一个空数组
                todos:JSON.parse(localStorage.getItem("todos"))||[],
            }
        },
        
        watch:{
          todos:{
            deep:true,//开启深度监视,避免修改了数组里对象的属性watch却没有监视到。
            handler(newVal,oldVal){
              localStorage.setItem("todos",JSON.stringify(newVal));
            }
          }
        },


2、组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:<Demo @atguigu="test"/><Demo v-on:atguigu="test"/>

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('atguigu',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('atguigu',数据)

  5. 解绑自定义事件this.$off('atguigu')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中要么用箭头函数,否则this指向会出问题!

src\App.vue


<template>
<div class="app">

  <h2>{{msg}}:{{studentName}}</h2>
  <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
  <School :getSchoolName="getSchoolName" />

   <!-- 通过父组件给子组件绑定自定义事件,实现:子给父传递数据(第一种写法,使用v-on绑定) -->
  <!-- <Student v-on:fhzm.once="getStudentName" /> -->

   <!-- 通过父组件给子组件绑定自定义事件,实现:子给父传递数据(第二种写法,使用ref绑定) -->
  <Student ref="student" @click.native="show" />

</div>
    
</template>

<script>

    //引入School组件
    import Student from "./components/Student.vue";

    import School from "./components/School.vue";

    export default {
        name:"App",
        components:{ 
          Student,
          School        
        },
        data(){
            return{
              msg:"你好啊",
              studentName:""
            }
        },
        methods:{
          getSchoolName(name){
            console.log("app收到了学校名:",name);
          },
          getStudentName(name,...p){
            console.log("app收到了学生名:",name,p);
            this.studentName=name;
          },
          show(){
            alert("我是组件绑定的原生的js事件");
          }
        },
        mounted(){
          //3秒钟后再给sdudent组件绑定事件
          setTimeout(() => {
            //this.$refs.student//:vc实例对象
            this.$refs.student.$on("fhzm",this.getStudentName); //后面一个参数如果是一个函数形式的话,那么函数里的this就是触发该事件的组件实例对象,除非写成箭头函数。
            //this.$refs.student.$once("fhzm",this.getStudentName); //只触发一次

          }, 0);
         
        }
    }

</script>

<style scoped>
.app{
  background-color:gray;
  padding: 5px;
}
</style>

src\components\School.vue

<template>
    <div class="school">
        <h3>学校名称:{{name}}</h3>
        <h3>地址:{{address}}</h3>
        <button @click="sendSchoolName">给app传学校名</button>
    </div>
    
</template>

<script>

    export default  {
        name:"School",
        data(){
            return{
                name:"家里蹲",
                address:"某国"
            }
        },
        props:["getSchoolName"],
        methods:{
            sendSchoolName(){
                this.getSchoolName(this.name);
            }
        }
    };

</script>

<style scoped>
.school{
    background-color:skyblue;
    padding:5px;
    margin-top:30px;
}
</style>

src\components\Student.vue

<template>
    <div class="student">
        <h3>学生姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
        <button @click="sendStudentName">给app传学生名</button>
        <button @click="unbind">解绑fhzm事件</button>
        <button @click="death">销毁当前Student组件的实例(vc)</button>

    </div>
    
</template>

<script>    

    export default  {
        name:"School",
        data(){
            return{
                name:"张三",
                age:18,
            }
        },
        methods:{
            sendStudentName(){
                //调用外面给student组件实例绑定的fhzm事件
                this.$emit("fhzm",this.name,this.age);
            },
            unbind(){
                this.$off("fhzm");//解绑一个自定义事件,也可以在父组件里通过this.$refs("student").$off()解绑

                //this.$off(['x','y']);//这样是解绑该组件实例身上的x和y自定义事件
                //this.$off();//这样是解绑该组件实例身上所有绑定的自定义事件
            },
            death(){
                
                this.$destroy();//销毁当前Student组件的实例,销毁后该组件实例身上所有自定义事件都无法使用了。
            }
        }
    };

</script>

<style scoped>
.student{
    background-color:pink;
    padding:5px;
}
</style>
posted @ 2022-04-10 15:08  青仙  阅读(54)  评论(0编辑  收藏  举报