第十九节:带你梳理Vue2: 父组件向子组件传参(props传参)

1. 组件嵌套

1.1 组件的嵌套使用

之前有说过,Vue组件跟Vue实例是一样的,因此在Vue中一个组件中也可以定义并使用自己的局部组件,这就是组件的嵌套使用

例如:示例代码如下:

<div id="app">
     <!-- 3. 使用组件 -->
    <my-component></my-component>
</div>

<script>
    // 子组件选项
    let sonComponent = {
        template:`
            <span>我是子组件</span>
        `,
    }

    //  父组件选项对象
    let MyComponent = {
        template: `
            <div>
                <h2>我是父组件</h2>
                <my-son></my-son>
                <my-son />
            </div>
        `,
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }
   
    // 2. 注册局部组件
    const vm = new Vue({
        el:"#app",
        
        components: {
            "MyComponent": MyComponent
        }
    })
</script>

显示结果:

组件的嵌套使用.png

通过示例我们就了解到,组件可以嵌套使用,那么我们就不得不思考一个问题,他们各自之间的数据关系如何?能否相互使用对方的数据呢?

1.2 组件间的数据关系

组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。

示例代码如下

<div id="app">
     <!-- 3. 使用组件 -->
    <my-component></my-component>
</div>

<script>
    // 子组件选项
    let sonComponent = {
        template:`
            <span>我是子组件{{msg}}</span>
        `,
    }
  

    //  父组件选项对象
    let MyComponent = {
        template: `
            <div>
                <h2>我是父组件</h2>
                <h3>父组件中使用子组件</h3>
                <my-son></my-son>
                <my-son />

                <h3>父组件中使用父组件数据</h3>
                {{ msg }}
            </div>
        `,
        data(){
            return {
                msg: "哈哈,我是父组件数据"
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }
   
    // 2. 注册局部组件
    const vm = new Vue({
        el:"#app",
        
        components: {
            "MyComponent": MyComponent
        }

    })
  
  
</script>

显示结果:

子组件中错误的使用父组件数据.png

如果在子组件中强行使用父组件的数据 ,就会报错,
那么子组件如何才能获取父组件的数据呢?


2. props 属性

父组件可以使用 props 把数据传给子组件。

2.1 props基本使用

父组件在使用子组件时, 可以将父组件的数据绑定到子组件的自定义标签上,

子组件在选项中添加一个props属性来接收数据

示例代码如下:

<div id="app">
    <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <div>
        <table border="1">
            <tr colspan="3">子组件数据</tr>
            <tr>
                <td>my name</td>
                <td>{{ myName }}</td>
            </tr>
            <tr>
                <td>my age</td>
                <td>{{ myAge }}</td>
            </tr>
        </table>
    </div>
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <h2>显示父组件传给子组件的数据</h2>
        <!-- 通过两个组件的契合点,父组件通过自定义属性将数据传递给子组件 -->
        <!-- 在属性传输数据的时候使用连字符语法 -->
        <my-son :my-name="name" :my-age="age"></my-son>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        // 数组里放父组件中自定义属性的名字
        // props 里面使用驼峰写法
        props:["myName","myAge"],
        template:`#son`,
    }


    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                name:"wuwei",
                age:18
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }

    //  实例中注册组件
    const vm = new Vue({
        el:"#app",

        components: {
            "MyComponent": MyComponent
        }

    })

</script>

显示结果:

父组件通过props向子组件传值.png


2.2 数据传递分类

都知道在JS中数据分为两大类,基本数据类型和引用数据类型

因此在父组件向子组件传递数据时也分为两种:为传值和传引用

传值:String Number Boolean

传引用: Array Object

那么接下来我们好好研究研究两者的不同


2.2.1 传递的是基本类型

基本类型,顾名思义,就是传递JS基本数据类型的数据

示例代码如下:

<div id="app">
  <conter :count="3"></conter>
  <conter :count="4"></conter>
</div>

<script>
  var conter = {
    props: ['count'],
    template:'<div @click="handleClick">{{count}}</div>',
    methods:{
      handleClick(){
        //  console.log(this.count)
        this.count++
      }
    }
  }
  var app = new Vue({
    el:'#app',
    components:{
      conter
    }
  })
</script>

props传递数字.png

其实这个时候我们发现在使用子组件传递数据时并没有使用父组件data中的数据,但仍然使用了v-bind动态绑定指令
为什么呢? 不用v-bind指令就不能传递数据了吗?


答案当然不是啦, 之前有讲过, 属性如果不使用v-bind指令绑定,那么属性值将是字符串,如果使用v-bind指令绑定, 属性值虽然还是引号,但是引号中确是JavaScript表达式

因此上面的示例中我们希望的是传递数据过去,那么引号中的3 只有在JavaScript表达式中才表示数字的字面量, 因此需要v-bind指令

我们也可以尝试一下,不是用v-bind的情况

<div id="app">
    <!-- 不使用v-bind 指令-->
    <conter count="3"></conter>
    <conter count="4"></conter>
</div>

<script>
    var conter = {
        props: ['count'],
        template:'<div @click="handleClick">{{count}}</div>',
        methods:{
            handleClick(){
                //  console.log(this.count)
                this.count++
            }
        }
    }
    var app = new Vue({
        el:'#app',
        components:{
            conter
        }
    })
</script>

显示结果:

不使用v-bind指令传递数据.png

此时通过两个案例的对比,我们就可以发现, 使用和不使用v-bind指令的区别

也就是说不使用指令, 传递给子组件的数据将永远是字符串, 不管你写成什么样子

使用v-bind指令, 属性值引号中的内容将变成表达式,那么你就可以传递任何JS数据类型的数据

这既是Vue官网中关于props 静态传输和动态传输.

接下来我们再来看看父组件给字符串传递引用值的情况


2.2.2 传递的是引用类型的值

传引用就是传递引用类型的数据,
其实我们最想关注的是,传递引用类型的数据是数据的拷贝,还是内存地址的拷贝
因为这涉及到在子组件中是否可以通过props修改父组件中的数据

示例代码如下:

<div id="app">
    <child1 :aa="obj"></child1>
    <child2 :bb="obj"></child2>
</div>

<script>
    var child1 = {
        props:['aa'],
        template:`<div>{{aa}}</div>`,
        mounted(){
            console.log(this.aa)
        }
    }
    var child2 = {
        props:['bb'],
        template:`
            <div>
                <div>{{this.bb}}</div>
                <button @click="handleClick">点击</button>
            </div>
        `,
        methods: {
            handleClick(){
                this.bb.name="haha"
            }
        }
    }

    new Vue({
        el:'#app',
        data: {
            obj:{
                name: 'wuwei'
            }
        },
        components: {
            child1,child2
        }
    })
</script>

向子组件传递引用类型.png

通过示例我们发现父组件向两个不同的子组件传递了同一个引用数据类型,

两个子组件都拿到了相同的数据,也显示相同的内容,


可是在child2子组件中定义了一个按钮用于改变child2这个子组件通过props从父组件获取过来的数据

var child2 = {
    props:['bb'],
    template:`
    <div>
        <div>{{this.bb}}</div>
        <button @click="handleClick">点击</button>
    </div>
    `,
    methods: {
        handleClick(){
            this.bb.name="haha"
        }
    }
}

点击后显示的结果:

子组件修改父组件传递的数据.png

通过示例我们就了解到,父组件向子组件传递数据时,子组件通过props 属性接受,
但请不要随意的更改props属性中的数据, 因为可能会有你意向不到的问题,

那么怎么解决这类问题呢, 接着往下看.


2.3 单向数据流

vue默认是单向数据流,所谓的单向数据流,就是数据传递是单向的

既然父组件将数据传递给了子组件,那么子组件中如果对于数据进行改变就有可能影响其他使用这数据的组件

注意:

这个只限传递基本数据类型的值,传递引用数据类型的问题上例中已经处理过

示例代码如下:

<div id="app">
    <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <table border="1">
        <tr>
            <th  colspan="3">子组件数据</th>
        </tr>
        <tr>
            <td>my name</td>
            <td>{{ myName }}</td>
            <td>
                <input type="text" v-model="myName">
            </td>
        </tr>
        <tr>
            <td>my age</td>
            <td>{{ myAge }}</td>
            <td>
                <input type="text" v-model="myAge">
            </td>
        </tr>
    </table>
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <table border="1">
            <tr>
                <th  colspan="3">父组件数据</th>
            </tr>
            <tr>
                <td>name</td>
                <td>{{ name }}</td>
                <td>
                    <input type="text" v-model="name">
                </td>
            </tr>
            <tr>
                <td>age</td>
                <td>{{ age }}</td>
                <td>
                    <input type="text" v-model="age">
                </td>
            </tr>
        </table>
        <!-- 通过两个组件的契合点,父组件通过自定义属性将数据传递给子组件 -->
        <!-- 在属性传输数据的时候使用连字符语法 -->
        <my-son :my-name="name" :my-age="age"></my-son>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        // 数组里放父组件中自定义属性的名字
        // props 里面使用驼峰写法
        props:["myName","myAge"],
        template:`#son`,
    }


    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                name:"wuwei",
                age:18
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }

    //  实例中注册组件
    const vm = new Vue({
        el:"#app",

        components: {
            "MyComponent": MyComponent
        }

    })

</script>

修改父组件数据:

父组件数据改变.png

修改子组件中数据,

子组件直接修改props中数据.png

通过示例测试,我们发现

  1. 当父组件数据更新时,传递给子组件的props也会更新,
  2. 当子组件修改了props的数据, 父组件不会有任何变化(基本数据类型报错,引用类型直接替换引用地址也报错, 但是直接修改属性不报错,但是不建议这么用)

这就是所谓的单项下行数据流

这么做的目的是为了防止子组件无意修改了父组件的状态


总结:

  1. 子组件不能(也不要)直接修改父组件传递过来的值,否则就会报错
  2. 修改父组件传递过来引入类型的属性不会报错,但是会导致,其他使用了这个数据的子组件里面的数据也会发生变化(这也是很大的entity)

2.4 prop响应式

通过上一个例子,我们发现父组件的数据发生变化, 子组件也会随着发生变化, 也就是,父组件在使用子组件时,给子组件prop传递的数组无论何时发生改变, 在子组件内任何使用该prop的地方都会发生更新
这就是props响应式

示例代码如下:

<div id="app">
    <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <div>
        被点击了{{ num }}次
    </div>
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <my-son  :num="num"></my-son>
        <!-- 
			每次点击更改父组件data中的数据, 子组件prop关联的数据也会跟随发生改变
		-->
        <button @click="handleClick">点击+1</button>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        props:["num"],
        template:`#son`,
    }


    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                num: 1
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        },
        methods:{
            handleClick(){
                this.num++
            }
        }
    }

    //  实例中注册组件
    const vm = new Vue({
        el:"#app",
        components: {
            "MyComponent": MyComponent
        }
    })
</script>

点击结果

props的响应式.png


3. 如何修改数据

上一小节学习我们已经知道了:

  1. 父组件可以向子组件传递基本数据类型引用数据类型的数据
  2. 子组件如果直接修改props中的基本数据类型数据和引用类型数据的内存地址就报错
  3. 如果修改引用类型数据里的值虽然不会报错,但是这样非常不友好
  4. 因此不推荐在子组件直接修改props数据中的数据

可是有的是需要修改传递过来的数据,那么如何解决这样的需求呢?

其实我们可以将父组件传递过来的值赋值给组件自己的数据,这样我们就可以修改自己的数据了


3.1 子组件修改基本数据

示例代码如下:

var conter = {
  props: ['count'],
  data(){
    return {
      num: this.count
    }
  },
  template:'<div @click="handleClick">{{num}}</div>',
  methods:{
    handleClick(){
      //  console.log(this.num)
      this.num++
    }
  }
}

3.2 子组件修改引用类型

如果父组件向子组件传递的引用数据类型的数据,我们按照基本数据类型那种直接将数据赋值给子组件自己的数据就行不同了,因为赋值给自己的数据也是内存地址的赋值,因此直接赋值,修改还是会改变父组件的数据. 那么要怎么办嗯?

其实我们可以在子组件内的data属性中浅拷贝一份父组件传递过来的引用数据类型,子组件如果想修改自己的显示,就修改自己data中的数据

将上面例子中child2子组件修改为如下代码

var child2 = {
    props:['bb'],
    // 在自己的data数据中浅拷贝一份父组件传过来的引用数据
    data(){
        return {
            cc: JSON.parse(JSON.stringify(this.bb))
        }
    },
    // 在自己的视图中显示自己的数据
    template:`
    <div>
        <div>{{cc}}</div>
        <button @click="handleClick">点击</button>
    </div>
    `,
    // 如果有修改就修改自己data中的数据
    methods: {
        handleClick(){
            this.cc.name="haha"
        }
    }
}

点击结果:

子组件拷贝父组件数据.png

这样就可以在子组件中使用自己的数据,修改自己的数据, 进而解决问题


4. Prop 验证

我们可以为组件的 prop 指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。这对于开发给他人使用的组件非常有用。

要指定验证规则,需要用对象的形式来定义 prop,而不能用字符串数组:


4.1 验证父组件传递过来的数据类型

// 子组件选项
let sonComponent = {
    // props 验证数据类型
    props:{
        myName:String,
        myAge: Number
    },
    template:`#son`,
}

如果数据类型验证通过, 则正常运行,如果验证不通过,则报错


4.2 允许数据传递多种数据类型

如果一个数据可以接受多种数据类型,则使用数组将所有允许的类型罗列在一起

// 子组件选项
let sonComponent = {
    // props 验证数据类型
    props:{
        myName:String,
        myAge: [Number,String]
    },
    template:`#son`,
}

这样myAge 在接受的数据是Number 类型或String 都不会报错


注意:

这两种验证数据的类型,只验证父组件传递过来数据的类型是否符合, 并不关心用户是否传数据过来, 不传也不会报错,

那么type属性都可以指定哪些类型呢?


4.3 type类型

验证类型的type属性的值就是原生的构造器(构造函数)

  • String
  • Number
  • Boolean
  • Function
  • Object
  • Array
  • Symbol

4.4 必须传递的数据

有的时候我们需要指定一些数据为必须传递的, 如果不传递就会报错, 这个时候,数据的只是一个对象

对象就是对于props传递数据的配置对象

验证的配置对象中

  1. type: 验证数据类型
  2. required: 验证数据是否为必须传递,true,是必须传递,不传就报错
// 子组件选项
let sonComponent = {
    props:{
        myName:String,
        myAge: {
            type:Number,   // type为验证数据类型
            required: true  // required为数据是否必须传递,true是false 否
        }
    },
    template:`#son`,
}

4.5 指定默认值

如果父组件未传递数据过来,则使用默认值

注意:

配置对象中required 必传选项 和 default 默认值选项,不能同时使用

默认是就是父组件在未传递数据的时候使用, 如果你还需要父组件必须传递数据, 默认值就不没有意义了吗

// 子组件选项
let sonComponent = {
    props:{
        myName:{
            type: String,    // 验证类型
            default: '默认姓名'   // 默认值
        },
        myAge: {
            type:Number,   // type为验证数据类型
            required: true  // required为数据是否必须传递,true是false 否
        }
    },
    template:`#son`,
}

如果传递过来的是是引用类型, 那么在定义默认值的时候必须是一个函数,函数返回引用类型的数据
为什么是一个函数就不用在说吧,和组件数据data是函数同一个意思, 保存每次传递都是第一无二的数据

示例代码如下

let sonComponent = {
    props:{
        myName:{
            type: String,    // 验证类型
            default: '默认姓名'   // 可以赋予默认值,如果父组件没有传值,使用默认值
        },
        myAge: {
            type:Number,   // type为验证数据类型
            required: true  // required为数据是否必须传递,true是false 否
            				//  此属性表示必须传值,但是不能跟default同用
        },
        myLike:{
            type:Array,       // 限定的数据类型是引用类型的数组
            default: function(){   //如果传递过来的是一个引用类型的值,默认值是函数
                 return []   
            }
        }
    },
    template:`#son`,
}

4.6 自定义验证规则

自定义验证是一个函数,返回true则验证通过,返回false则验证不通过

示例代码如下:

let sonComponent = {
    // 子组件通过props接受数据并使用
    // 数组里放父组件中自定义属性的名字
    // props 里面使用驼峰写法
    props:{
        myName:{
            type: String,    // 验证类型
            default: '默认姓名'   // 默认值
        },
        myAge: {    
            validator:function(value){ //   自定义验证器
                return value > 16        // 返回true 验证通过, 返回false 验证不通过报错
            }
        }
    },
    template:`#son`,
}

注意

props 会在组件实例创建之前进行校验,

所以在 defaultvalidator 函数里,诸如 datacomputedmethods 等实例属性都还无法使用。

props特性就是父组件通过属性传值,子组件有对应的props接受,那么这个属性不会出现在网页的标签属性上


5. 非Props 特性

5.1 非prop 属性的了解

尽管为组件定义明确的 props是推荐的传参方式,组件的作者却并不总能预见到组件被使用的场景。
所以,组件可以接收任意传入的特性,这些特性都会被添加到组件的根元素上。

简单的说就是父组件可以在使用子组件的时候给子组件传递n多的属性, 只有子组件使用props接受的才会成为子组件的参数, 没有通过props声明的属性就是非props, 这些属性会自动添加为子组件根标签的属性

通过示例了解:

<div id="app">
    <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <div>
        {{msg}}
    </div>
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <!-- msg因为子组件prop定义了所以会成为子组件的参数 -->
        <!-- title属性因为子组件没有在props声明,所以是非prop, 会自动添加为 子组件根标签的属性-->
        <my-son  :msg="msg" :title="title"></my-son>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        props:["msg"],
        template:`#son`,
    }

    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                msg:"我想说一句话",
                title:"标题"
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }

    //  实例中注册组件
    const vm = new Vue({
        el:"#app",
        components: {
            "MyComponent": MyComponent
        }
    })
</script>

显示结果

非props.png

在总结一下:

非props就是子组件并没有明确props来接受父组件的传值,那么在网页中子组件传值的属性将会成为标签的私有属性


上面一个例子,了解到如果父组件给子组件传递非prop属性,会自动成为子组件模板中根标签的标签属性, 适用于任何HTML属性或特性,

可是如果父组件传递的非prop属性与子组件的根标签的属性重名了怎么办呢?

会发生两种情况, 一,替换,二合并, 先来看看替换的情况


5.2 非prop属性的替换

如果父组件传递的prop属性与子组件的根标签的属性重名,大部分情况会覆盖子组件根标签上的同名属性. 即替换效果

示例代码如下:

<div id="app">
     <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <!-- 子组件根标签的type属性值text 被父组件传递过了的非prop type属性值 radio替换了 -->
    <input type="text" />
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <!-- 父组件向子组件传递非prop属性 type 值为radio -->
        <my-son  :type="type"></my-son>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        props:["num"],
        template:`#son`,
    }
  
 
    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                type: "radio"
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }
   
    //  实例中注册组件
    const vm = new Vue({
        el:"#app",
        
        components: {
            "MyComponent": MyComponent
        }

    })
</script>

显示结果

非props属性替换.png

通过示例.发现: 子组件根标签的type属性值text 被父组件传递过了的非props type属性值 radio替换了

这样的效果非常不好,可能会破坏子组件. 所以一定要注意.


5.3 非prop属性的合并

当然了大部分会发生替换, 但是也有两个特殊的属性,会发生合并的效果,这两个属性就是classstyle属性

示例:

<div id="app">
    <!-- 使用组件 -->
    <my-component></my-component>
</div>

<!-- 子组件模板 -->
<template id="son">
    <div class="box" style="background:skyblue;">
        我是子组件 
    </div>
</template>

<!-- 父组件模板 -->
<template id="MyComponent">
    <div>
        <my-son  :class="className" :style="style"></my-son>
    </div>
</template>

<script>
    // 子组件选项
    let sonComponent = {
        // 子组件通过props接受数据并使用
        props:["num"],
        template:`#son`,
    }


    //  父组件选项对象
    let MyComponent = {
        template: `#MyComponent`,
        data(){
            return {
                className: "wrap",
                style: {
                    width: '100px',
                    height: '100px'
                }
            }
        },
        // 将子组件定义为父组件的局部组件
        components: {
            mySon: sonComponent
        }
    }

    //  实例中注册组件
    const vm = new Vue({
        el:"#app",

        components: {
            "MyComponent": MyComponent
        }

    })


</script>

非props属性合并.png

示例中,父组件通过非prop传递过去的class 和style属性 与子组件根标签的class 和 style 属性发生合并.


6. 遍历传值,

利用v-for循环指令. 多次使用组件.

在配合使用 v-bind 指令将数据传到每个组件中:

<div id="app">
    <ol>
        <!--
            现在我们为每个 todo-item 传递了数据,即其内容可以是动态的。
            我们也需要为每个组件提供一个“key”,稍后再
            作详细解释。
        -->
        <todo-item
                   v-for="item in groceryList"
                   v-bind:text="item.text"
                   v-bind:key="item.id">
        </todo-item>
    </ol>
</div>

    <script>
        // 定义子组件
        let todoItem = {
            props:["text"],
            template:`
            	<li>{{text}}</li>
            `
        }
        
        // Vue实例
        var vm = new Vue({
            el: '#app',
            data: {
                groceryList: [
                    { id: 0, text: '蔬菜' },
                    { id: 1, text: '奶酪' },
                    { id: 2, text: '随便其它什么人吃的东西' }
                ]
            },
            components:{
                todoItem
            }
        })
    </script>

显示结果

循环组件配合props使用.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/660477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

教学基本功包括什么技能有哪些

教师的工作不仅仅是传授知识&#xff0c;更多是引导学生探索&#xff0c;激发他们的创造力。要做到这一点&#xff0c;需要具备一些基本技能。 扎实的专业知识。这是教师的根基&#xff0c;如果教师自己对所教的科目都不熟悉&#xff0c;那么教学就会失去方向。不断学习更新自己…

告别虚拟机,在Windows10启动Linux子系统

背景 如果要在自己的windows电脑安装一个Linux系统,一般是用虚拟机软件例如VMware软件来创建。但是这种方式显得非常的笨重。而Windows10自带的Linux子系统则非常的方便。 分析 在Windows10中启用子系统的方式来安装Linux,用于学习和开发是非常方便的。子系统的实用就和一个…

基于深度学习的中文情感分析系统python flask

基于python的毕业设计 基于深度学习的中文情感分析系统(flask)(源码说明文档演示) 毕业设计课程设计期末大作业、课程设计、高分必看&#xff0c;下载下来&#xff0c;简单部署&#xff0c;就可以使用。 包含&#xff1a;项目源码、数据库脚本、软件工具等&#xff0c;该项目…

3D模型三角面转四角面操作指南---模大狮模型网

在3D建模的过程中&#xff0c;三角面(Triangles)和四角面(Quads)是两种常见的多边形类型。虽然三角面在渲染速度和计算效率上有其优势&#xff0c;但四角面在模型编辑和纹理映射上通常更为方便。因此&#xff0c;将三角面转换为四角面是建模过程中常见的需求。 一、选择合适的建…

py黑帽子学习笔记_scapy

简介 代码简洁&#xff1a;相比于前两个博客总结&#xff0c;很多socket操作&#xff0c;如果使用scapy仅需几行代码即可实现 获取邮箱身份凭证 编写基础嗅探器&#xff0c;脚本可显示任何收到的一个包的详细情况 直接运行 尝试监听邮件收发&#xff0c;监听指定端口&#x…

高性价比、超强功能的开源工单解决方案

在企业日常运营中&#xff0c;工单管理系统是不可或缺的工具。高效的工单管理不仅能提升工作效率&#xff0c;还能显著提高客户满意度。今天&#xff0c;我们为您推荐搭贝工单派单系统——一款超高性价比、功能齐全的开源工单管理系统。 &#x1f50d; 为什么选择搭贝工单派单…

通过vlan实现同一网段下的网络隔离

现有两个电脑通过交换机直接连接在一起 pc1&#xff1a; pc2&#xff1a; 正常状态下是可以ping成功的 现在先进入交换机命令行界面&#xff0c;创建两个vlan <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]vlan 10 [Huawei-vlan10…

Python面向对象学习笔记

Python面向对象编程 记录人&#xff1a; 李思成 时间&#xff1a; 2024/05/01至2024/05/23 课程来源&#xff1a; B站Python面向对象 1.面向对象编程概述 官方概述 程序是指令的集合&#xff0c;运行程序时&#xff0c;程序中的语句会变成一条或多条指令&#xff0c;然后…

数组-给出最大容量,求能获得的最大值

一、问题描述 二、解题思路 这个题目其实是求给出数组中&#xff0c;子数组和不大于M中&#xff0c;和最大值的子数组。 求子数组使用双指针就可以解决问题&#xff0c;相对比较简单。&#xff08;如果是子序列&#xff0c;则等价于0-1背包问题&#xff0c;看题目扩展中的问题…

Node性能如何进行监控以及优化?

一、 是什么 Node作为一门服务端语言&#xff0c;性能方面尤为重要&#xff0c;其衡量指标一般有如下&#xff1a; CPU内存I/O网络 CPU 主要分成了两部分&#xff1a; CPU负载&#xff1a;在某个时间段内&#xff0c;占用以及等待CPU的进程总数CPU使用率&#xff1a;CPU时…

Vue 3 教程:核心知识

Vue 3 教程&#xff1a;核心知识 1. Vue3简介1.1. 【性能的提升】1.2.【 源码的升级】1.3. 【拥抱TypeScript】1.4. 【新的特性】 2. 创建Vue3工程2.1. 【基于 vue-cli 创建】2.2. 【基于 vite 创建】(推荐)2.3. 【一个简单的效果】 3. Vue3核心语法3.1. 【OptionsAPI 与 Compo…

JDK8新特性之lambda表达式

大家好&#xff0c;这里是教授.F 目录 引入&#xff1a; 什么情况下使用/使用前提&#xff1a; 标准格式&#xff1a; 实现原理&#xff1a; 省略格式&#xff1a; 引入&#xff1a; lambda表达式就是简介的书写我们的匿名内部类。Lambda相当于对接口的抽象方法的重写。 什…

盐化行业数字化转型规划详细方案(124页PPT)

方案介绍&#xff1a; 本项目旨在通过引入先进的信息技术和数字化手段&#xff0c;对盐化行业的生产、管理、销售等各个环节进行全面优化和升级&#xff0c;实现生产效率提升、成本降低、产品质量提升、市场竞争力增强等目标。此外环保水平得到提升&#xff0c;降低企业的环保…

Opencv图像处理技术(图像轮廓)

1图像轮廓概念&#xff1a; 图像轮廓是指图像中连续的像素边界&#xff0c;这些边界通常代表了图像中的物体或者物体的边缘。在数字图像处理中&#xff0c;轮廓是由相同像素值组成的曲线&#xff0c;它们连接相同的颜色或灰度值&#xff0c;并且具有连续性。轮廓可以用来描述和…

滴滴一季度营收同比增长14.9%至491亿元 经调整EBITA盈利9亿元

【头部财经】5月29日&#xff0c;滴滴在其官网发布2024年一季度业绩报告。一季度滴滴实现总收入491亿元&#xff0c;同比增长14.9%&#xff1b;经调整EBITA&#xff08;非公认会计准则口径&#xff09;盈利9亿元。其中&#xff0c;中国出行一季度实现收入445亿元&#xff0c;同…

VSCode小技巧,忽略不想格式化的代码行

零&#xff0e;格式化工具文档 1 . Black Ignoring sections功能 2 . autopep8 disabling-line-by-line功能&#xff1b;&#xff1b;–line-range选项 3 . Prettier prettier-ignore功能(例&#xff1a;适用于JS的// prettier-ignore&#xff0c;适用于CSS的/* prettier-igno…

02_变量提升与函数提升及其优先级(JS高级)

目录 一、 变量提升与函数提升 为什么要进行变量提升和函数提升 1.1 变量提升 1.2 函数提升 1.3 变量提升与函数提升的优先级 二、执行上下文 三、执行上下文栈 四、习题 一、 变量提升与函数提升 为什么要进行变量提升和函数提升 JS引擎在读取js代码的过程中&#xf…

Dinky MySQLCDC 整库同步到 Doris

资源&#xff1a;flink 1.17.0、dinky 1.0.2、doris-2.0.1-rc04 问题&#xff1a;Cannot deserialize value of type int from String &#xff0c;detailMessageunknowndatabases &#xff0c;not a valid int value 2024-05-29 16:52:20.136 ERROR org.apache.doris.flink.…

OpenAI开始训练新的前沿模型——但GPT-5至少在90天内不会推出

ChatGPT 制造商 OpenAI 今早宣布&#xff0c;已开始训练其新的“前沿模型”&#xff0c;并成立了一个新的安全委员会&#xff0c;由现任董事会成员 Bret Taylor&#xff08;OpenAI 董事会主席兼客户服务初创公司 Sierra AI 联合创始人、前谷歌地图负责人和前 Facebook 首席技术…

DNSlog环境搭建

阿里云域名公网VPS地址 购买阿里云域名后设置“自定义DNSHOST” DNS服务器填写ns1和ns2 如&#xff1a;ns1.aaa.com IP地址填写你的VPS地址 如&#xff1a;1.1.1.1 填写解析记录&#xff0c;一个A记录、一个NS记录 NS记录就是*.域名指向记录值ns1.域名 如&#xff1a;*.aaa…