9月6日vue学习笔记

标签

vue

前端

html

css

javascript

发布时间:

本文字数:1,401 字 阅读完需:约 5 分钟

api接口

alt alt

示例:通过refs获取对象

<body>
    <div id="app">
        <div ref="nb">宁波</div>
        <input type="text" v-model="msg"><button @click="get">获取</button>
    </div>
    <script>
        new Vue({
            el:"#app",
            data() {
                return {
                    msg:'hello'
                }
            },
            methods: {
                get(){
                    console.info(this.$refs.nb)
                }
            },
        })
    </script>
</body>

结果:控制台输出

<div>宁波</div>

组件的通信

发布订阅者模式

用于定义发布者对象与订阅者对象的一对一或一对多的关系,当发布者对象状态发生改变时,所有依赖于它的订阅者对象都会得到通知。

特点:

  1. 支持广播通信
  2. 发布者和订阅者低耦合

应用场景:微信公众号

父子通信

(见9月5日笔记)

子父通信

子组件通过$emit触发自定义事件,第一个参数为事件名,第二个参数为要传递的参数。
示例1:子组件点击"发送"按钮,父组件触发控制台输出消息

        let child1 = {
            template:/*html*/`<div>我是子组件1,<button @click="send">发送</button></div>`,
            data() {
                return {
                    
                }
            },
            methods: {
                send(){
                    this.$emit('msg','来自子组件1')
                }
            },
        };
        let parent = {
            template: /*html*/`
            <div>我是父组件<child1 @msg="f"></child1><child2></child2></div>
            `,
            data() {
                return {
                    
                }
            },
            methods: {
                f(data){
                    console.log(data)
                }
            },
            components:{
                'child1': child1
            }
        };
        new Vue({
            el:"#app",
            data() {
                return {}
            },
            methods: {
            },
            components:{
                'parent':parent
            }
        });

非父子通信

创建一个Vue实例作为中央事件总线,通过它来监听($on)和触发($emit)事件。适用于组件间全部通信方式。

       let bus = new Vue();//bus当成事件总线
        let child1 = {
            template:/*html*/`<div>我是子组件1,<button @click="send()" >发送</button></div>`,
            data() {
                return {
                }
            },
            methods: {
                send(){
                    bus.$emit('data-child1','来自子组件1')
                }
            },
        };
        let child2 = {
            template:`<div>我是子组件2</div>`,
            data() {
                return {
                    
                }
            },
            methods: {
                
            },
            mounted() {
                bus.$on('data-child1',function(value){
                    console.info(value)
                })
            },
        };
        let parent = {
            template: /*html*/`
            <div>我是父组件<child1 ></child1><child2></child2></div>
            `,
            data() {
                return {
                    
                }
            },
            methods: {
             
            },
            components:{
                'child1': child1,
                'child2': child2
            }
        };
        new Vue({
            el:"#app",
            data() {
                return {}
            },
            methods: {
            },
            components:{
                'parent':parent
            }
        });

slot组件

slot组件插槽:将父组件中的<child1></child1>标签内插入的代码插入到子组件的任意位置,用法见以下示例:

        let child1 = {
            //插槽:slot
            template:/*html*/`<div>我是<slot></slot>子组件</div>`,
           
        };
      
        let parent = {
            template: /*html*/`
            <div>我是父组件<child1 ><span style="color: red">OK</span></child1></div>
            `,
          
            
            components:{
                'child1': child1,
            }
        };
        new Vue({
            el:"#app",
            data() {
                return {}
            },
        
            components:{
                'parent':parent
            }
        });

插槽的分类

插槽分为默认插槽、具名插槽和作用域插槽

示例

         let child1 = {
            //插槽:slot
            template:/*html*/`<div><slot name="one" :message="msg"></slot><slot></slot>子组<slot name="two"></slot></div>`,
            data() {
                return {
                    msg : 'CHILD'
                }
            },
        };
      
        let parent = {
            template: /*html*/`
            <div>我是父组件<child1 >
                //默认插槽
                <template v-slot:default><span style="color: red">OK</span></template>
                //作用域插槽
                <template v-slot:one="prop"><span style="color: red">One插槽,{{prop}}</span></template>
                //具名插槽
                <template v-slot:two><span style="color: red">Two插槽</span></template>
            </child1></div>
            `,
          
            
            components:{
                'child1': child1,
            }
        };
        new Vue({
            el:"#app",
            data() {
                return {}
            },
        
            components:{
                'parent':parent
            }
        });

注意示例中的<template>标签,以及标签中的v-slot属性,和插槽的用法。

效果:

我是父组件
One插槽,{ "message": "CHILD" }OK子组Two插槽

ES6语法

var 和 let 的区别

  1. let 声明变量和 const 声明常量都有块级作用域,var s声明变量是全局作用域
  2. var 声明变量可以重复声明,let不可以重复声明
var i = 10;
var i = 20;
let j = 10;
// let j = 20; //错误:重复声明
  1. var 会和 window 映射, let 不会

const 声明常量

const 声明常量,声明常量必须赋值,常量不可更改,不会和window映射

const y = 20;
// y=30 //报错,不可更改

`的用法

``内可以用$引用其他变量,如下所示

let name = '李雷';
let str = `我的名字叫${name}`;
console.info(str);

解构

let print = [1, 2, 3];
let [x, y, z] = print;//将数组print的1,2,3赋给x,y,z
console.info(x, y ,z); 

let user = {
    name : '李雷',
    age : 20
}
let {name, age} = user; //将对象属性解构
console.info(name, age);

let name = '李雷';
let age = 20;
let user = {name, age, run(){
    console.info('run');
}} //只要key和value相同,就可以结构,此时user对象里面的name和age已经被赋值,匿名函数fun:function(){}可以写为run(){};
console.info(user);

循环

// 以下三种循环效果都是输出数组里的所有值
let x = [1,2,3,4,5];
for(let i = 0; i < x.length; i++){
    console.info(x[i]);
}
for(let i in x){
    console.log(x[i]);
}
for(let i of x){
    console.log(i);//相当于java中的加强for
}

可变参数

关键字:function 函数名(...数组名)

        function add(...arg) //可变参数
        {
            for(let x of arg){
                console.info(x);
            }
        }
        add(1,2,3,4,5,6,7)

箭头函数

在箭头函数中,this 指的是父作用域对象

//ES6箭头函数
let add = (x, y) => x + y; //无花括号,省略return关键字,函数返回x+y
console.log(add(1,2));

let add2 = (x, y) => {
    return x + y; //有花括号,必须加return
}

console.log(add2(1,2));

类是语法糖(可以理解为假的,需要编译)
示例:

class student{
    constructor(name, age){ //构造函数
        this.name = name;
        this.age = age;
    }
    run(){
        console.info('run');
    }
}
let stu = new student ('李雷', 20);
console.info(stu.name, stu.age);
stu.run();

ES6的模块化编程

模块化编程:按需加载

示例
js/es6.js

let name = '李雷';
let user = {
    name: '韩梅梅',
    age: 18
};
let func = function(){
    console.info('func函数')
};
export {name, user, func} //导出三个对象

es6.html

<!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>es6</title>
    <script type="module"> //此处必须加 module
        import {user} from './js/es6.js' //导入user对象
        console.info(name); //此时会报错,因为name对象未被导入
        console.info(user.name);

    </script>
</head>

<body>

</body>

</html>

ES6异步的实现

简单的Promise函数

let p = new Promise((resolve, reject)=>{
        setTimeout(()=>{
            console.info("异步执行完毕");
            resolve('任何需要的数据'); //执行成功函数
        },3000)
})

then函数

function runAsync() {
            let p = new Promise(
                (resolve, reject) => {
                    setTimeout(() => {
                        console.info("异步执行完毕");
                        resolve('任何需要的数据');
                    }, 3000)
                }
            )
            return p;
        }

        runAsync().then((data)=>{
            console.info(data)
        })
        

在上述示例中,setTimeoutconsole.info执行后,then执行,执行参数datasetTimeoutresolve函数传过来的值。

链式调用

     function runAsync1() {
            let p = new Promise(
                (resolve, reject) => {
                    setTimeout(() => {
                        console.info("异步执行完毕1");
                        resolve('任何需要的数据1');
                    }, 3000)
                }
            )
            return p;
        }
        function runAsync2() {
            let p = new Promise(
                (resolve, reject) => {
                    setTimeout(() => {
                        console.info("异步执行完毕2");
                        resolve('任何需要的数据2');
                    }, 3000)
                }
            )
            return p;
        }
        function runAsync3() {
            let p = new Promise(
                (resolve, reject) => {
                    setTimeout(() => {
                        console.info("异步执行完毕3");
                        resolve('任何需要的数据3');
                    }, 3000)
                }
            )
            return p;
        }

        runAsync1().then((data) => {
            console.info(data)
            return runAsync2(); //此时执行下一个函数,作为return值
        }).then((data)=> {
            console.info(data);
            return runAsync3();
        }).then((data)=>{
            console.info(data+" 执行完毕!");
        })

结果是依次执行输出异步执行完毕1、任意所需要的数据1。。。

reject 的用法

       function runAsync1() {
            let p = new Promise(
                (resolve, reject) => {
                    setTimeout(() => {
                        let num = Math.random();
                        if(num > 0.5){
                            resolve('数字正好');
                        }else{
                            reject('数字太小了');
                        }
                    }, 1000)
                }
            )
            return p;
        }
        

        runAsync1().then((data) => {
            console.info(data)
        },(err)=>{
            console.info(err)
        })

        //利用catch的另外一种写法
        runAsync1().then((data) => {
            console.info(data)
        }).catch((err)=>{
            console.info(err)
        })