这些vue基本语法,你掌握了吗

news2024/9/23 15:24:11

文章目录

    • 一、 vue 项目重点概念介绍
      • 1. 单页面应用程序
      • 2. 单文件组件
      • 3.数据驱动视图
    • 二、 vue 基本结构
      • 1、template
      • 2、script
      • 3、style
    • 三、 vue 常用指令介绍
      • 1、内容渲染指令
        • (1)插值表达式 {{xxx}} —常用方式
        • (2)v-text
        • (3)v-html
        • 2、属性绑定指令v-bind
        • 3、重点说下class和style绑定
          • (1)绑定class
          • (2)绑定内联样式style
        • 3、事件绑定指令v-on
            • 事件修饰符列表:
            • 按键修饰符列表:
        • 4、双向数据绑定指令v-model
        • 5、条件渲染指令
            • (1)v-show
            • (2)v-if
            • (3)v-show与v-if的区别
            • (4)v-else-if
          • 6.列表渲染指令v-for
    • 四、计算属性(computed)
    • 五、监听器(watch)
    • 六、过滤器(filter)
    • 七、组件
      • 1、组件的使用
      • 2 . 组件通信
      • 3 . 插槽的使用

一、 vue 项目重点概念介绍

1. 单页面应用程序

  • 单页面应用程序指的是一个应用程序中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。
  • 单页面应用程序将所有的功能局限在一个HTML页面中,仅在该HTML页面初始化时加载相应的资源(HTML、JavaScript、CSS)。一旦页面加载完成了,单页面应用程序不会因为用户的操作而进行页面间的重新加载或跳转。
  • 因为只有一个 html 页面,不需要页面间的跳转,而是利用JavaScript动态的变换HTML的内容,从而实现页面与用户的交互。

2. 单文件组件

vue的单文件组件是一种以.vue 结尾的特殊的文件格式,vue 工程化项目中不再有html的页面的概
念,一切皆为一个vue的单文件组件。它是不能被浏览器独立运行的,需要通过编译工具,编译为能被
浏览器解析的 js 文件执行。

3.数据驱动视图

数据的变化驱动视图的自动更新,是vue的一个特性。以前要想修改视图的数据,是通过js或者
jquery 操作 dom,改变dom 中的内容实现。现在只修改数据,数据改变,vue 会自动渲染 dom 更新,而不用我们再来操作 dom

所以我们在vue 项目中相比以前的jquery 项目中要有思想上的改变:从以前操作 dom的思想转换为操作数据。

二、 vue 基本结构

参考 vue 官网 https://v2.cn.vuejs.org/v2/guide/

标准的 vue 文件结构分为三个部分,模板(template)js(script)样式(style)

基本结构如下:

<template>
<!-- 有且只有一个根节点 -->
   <div></div>
</template>
<script>
export default {
 // 数据
data() {
return {
    obj: '',
    arr: []
    };
  },
 // 生命周期
created() {
   this.init();
},
mounted() {
    
},
// 方法
methods: {
  init() {
   //...
   }
  }
};
</script>
<!-- scoped 声明私有样式:只在该组件下起作用 -->
<!-- lang="scss" 声明css扩展语言 -->
<style lang="scss" scoped></style>

1、template

其中模板只能包含一个父节点,即模板内部有且只有一个根结点。这是 vue 单文件组件规范。
template类似于html部分。

2、script

vue通常用 es6 来写,用export default导出,其下面可以包含数据data,生命周期(mounted等)方法(methods)等。

  • data:模版中用到的数据都来自data,数据驱动视图也就代表修改data中的数据,会引起视图的
    更新。
  • created:在模板渲染成 html 前调用,即通常初始化某些属性值,然后再渲染成视图,调用method中的方法。
  • mouted:在模板渲染成 html 后调用,通常是初始化页面完成后,再对 html 的 dom 节点进行一些需要的操作,调用method中的方法。
  • method:用来定义 js 方法、事件等实现某些功能。
script标签内部结构顺序:
mixin > components > props > data > computed > watch > filter >生命周期钩子函数 >
errorCaptured > methods
生命周期钩子函数按其执行顺序书写:
beforeCreate > created > beforeMount > mounted
> beforeUpdate > updated > activated > deactivated > beforeDestroy > destroyed

3、style

样式通过style标签包裹,默认是影响全局的,如需定义作用域只在该组件下起作用,需在标签上加
scoped,,也可使用css扩展语言 scss,默认 css ,使用扩展语言需要声明lang属性,使用scss语言

三、 vue 常用指令介绍

1、内容渲染指令

(1)插值表达式 {{xxx}} —常用方式

用于解析标签体内容。{{xxx}}xxx js 表达式,且可以直接读取到data中的所有属性。

例子:

<template>
    <!-- 插值表达式 -->
    <div>{{ msg }}</div>
    <!-- 插值表达式{{}}对JavaScript 表达式支持,例如: -->
    <!-- 运算 -->
    {{ number + 1 }}
    <!-- 字符串拼接 -->
    {{ str + 'suffi'}}
    <!-- 三元表达式 -->
    {{ gender === '0' ? '男' : '女' }}
    <!-- js的字符串操作 -->
    {{ msg.substring(0,2) }}
</template>
export default { 
   data() {
   return {
    //属性名
      msg: '这是一段文字',
      number:0,
      str:'字符串',
      gender:'0'
    };
  }
};
</script>

(2)v-text

原样输出,替换标签内原有内容, 本质是innerText属性的修改

<template>
 <div>
<!-- v-text: 原样输出 替换标签内原有内容, 本质是 innerText 属性的修改 -->
  <div v-text="msg">msg:</div>
 </div>
</template>
<script>
export default {
   data() {
   return {
      msg: '<h1>Hello Vue</h1>'
    };
  }
};
</script>
<style lang="scss" scoped>
 //样式
</style>

输出:

<h1>Hello Vue</h1>

(3)v-html

更新元素的innerHTML,本质是innerHTML属性的修改。 注意:内容按普通 HTML 插入 - 不会作为
Vue模板进行编译。

例:

<template>
<div>
<!-- v-html: 把内容解析成HTML元素, 覆盖原有内容。 -->
<div v-html="msg">msg:</div>
</div>
</template>
<script>
export default {
data() {
return {
   msg: '<h1>Hello Vue</h1>'
   };
  }
};
</script>

输出:

Hello Vue

2、属性绑定指令v-bind

v-bind 可简写为 : 动态地绑定一个或多个 属性。在绑定 ``class style ```属性 时,支持其它类型的值,如数组或对象。
例:

<!-- 绑定属性名imageSrc -->
<img v-bind:src="imageSrc">
<!-- 简写 -->
<img :src="imageSrc">

3、重点说下class和style绑定

(1)绑定class
  • 对象语法: v-bind:class 设置一个对象,可以动态地切换class。

例:

isActive或者 hasError 变化时,class列表将相应地更新。例如,如果 hasError 的值为
trueclass列表将变为"static active text-danger" 。

<template>
<!-- 动态:class可以与普通class共存 -->
<div class="static" :class="{ active: isActive, 'text-danger': hasError }">一段
文字</div>
</template>
<script>
export default {
   data() {
     return {
       isActive: true,
       hasError: false
    };
  } 
};
</script>

渲染结果为:

<div class="static active">一段文字</div>
  • 数组语法:当需要应用多个 class 时,可以使用数组语法,给 :class 绑定一个数组,应用一个
    class 列表

例:

<template>
    <!-- :class绑定一个数组 -->
    <div :class="[activeClass, errorClass]">一段文字</div>
</template>

<script>
export default {
  data() {
    return {
    activeClass: 'active',
    errorClass: 'text-danger'
   };
  }
};
</script>

渲染结果为:

<div class="active text-danger"></div>

如果你也想根据条件切换列表中的 class,可以用三元表达式:

<!-- 当数据isActive为真时,样式activeClass才会被应用。这样将始终添加 errorClass -->

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

class有多个条件时,这样写有些繁琐。所以在数组语法中也可以使用对象语法:

<div v-bind:class="[{ activeClass: isActive }, errorClass]"></div>
(2)绑定内联样式style

对象语法:

v-bind:style的对象语法十分直观—看着非常像CSS,但其实是一个JavaScript对象。 CSS 名可以用驼峰式 或短横线分隔 (kebab-case,短横线分隔要用引号括起来) 来命名:

例子:

<template>
   <!-- 绑定属性activeColor值和fontSize值,渲染样式-->
   <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
</template>
<script>
export default {
   data() {
      return {
        activeColor: 'red',
        fontSize: '20'
     };
   }
};
</script>

直接绑定到一个样式对象通常更好,这会让模板更清晰:

<template>
   <!-- 绑定styleObject对象,渲染样式-->
   <div :style="styleObject"></div>
</template>
<script>
export default {
   data() {
      return {
        styleObject: {
           color: 'red',
           fontSize: '14px'
      },
      styleObjecttwo: {
      background: '#ccc'
     }
   };
 }
};
</script>
  • 数组语法:将多个对象放入数组中绑定
<div v-bind:style="[styleObject,styleObjecttwo]"></div>

3、事件绑定指令v-on

  • v-on为元素绑定监听事件
  • 语法:v-on:事件名=“函数名”,简写:@事件名=“函数名”
  • 语法的"函数名"代表了在方法methods中定义的回调函数,v-on绑定的事件触发后, vue会去实例
    对象的 methods 中找对应的回调函数可以使用修饰符,如 v-on:事件名.once="函数名"
  • 也可以使用@事件名='函数名($event)' 来获取事件对象
用在普通元素上时,用于监听原生Dom事件。用在自定义元素组件上时,也可以监听子组件触发
的自定义事件。
事件修饰符列表:
事件修饰符示例示例说明
.stop```@click.stop``阻止单击事件冒泡
.prvent@submit.prevent阻止事件的默认行为
.once@click.once规定该事件只会触发一次
按键修饰符列表:
事件修饰符示例说明
.enter@click.enter回车键
.delete@click.deletedelete键和退格键
.esc@click.escesc键
.space@click.space空格键

@click.once修饰符事件只会触发一次:

<template>
  <div>
    <el-button type="primary" @click="clickOnFn">我是按钮-简写</el-button>
    <el-button type="primary" @click.once="clickOneFn">我是按钮-.once</el-button>
   </div>
</template>
<script>
export default {
      data() {
        return {
           msg: ''
      };
 },
      methods: {
      //绑定事件
        clickOnFn() {
          this.$message({
           message: '按钮',
           type: 'success'
         });
  },
       //绑定事件,只调用一次
        clickOneFn() {
          this.$message({
            message: '只调用一次',
            type: 'success'
            });
     }
   }
};
</script>

4、双向数据绑定指令v-model

在表单控件或者组件上创建双向绑定。

例:

<template>
<div>
<!-- 视图发生改变→对应的数据发生改变:用户在输入框里输入的内容会被msg变量接下来,同时也将
动态更新在p标签的内容里。-->
<input v-model="msg" />
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
     data() {
       return {
       msg: ''
      };
    }
};
</script>

5、条件渲染指令

(1)v-show

根据表达式的真假值,切换元素的 display 的 CSS属性。即控制显示隐藏

例子:

<template>
   <!-- 绑定v-show指令,控制div的显示隐藏-->
   <div v-show="show">v-show指令</div>
</template>
<script>
export default {
    data() {
       return {
         show: true //tue显示;false隐藏
       };
    }
};
</script>
(2)v-if

v-if根据表达式的值的是否为真,来有条件地渲染元素。本质是通过操作dom 元素来切换显示状态。

v-for优先级比v-if高,不建议两者一起使用。

例子:

<template>
<!-- 绑定v-if指令,控制div的显示隐藏-->
<div v-if="show">v-if指令</div>
</template>
<script>
export default {
   data() {
     return {
       show: true //tue显示;false隐藏
     };
   }
};
</script>
(3)v-show与v-if的区别
  • v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销
    毁和重建。
  • v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做—直到条件第一次变为真时,才会
    开始渲染条件块。
  • 相比之下,v-show就简单得多—不管初始条件是什么,元素总是会被渲染,并且只是简单地基于
    CSS 进行切换。
  • 一般来说,v-if 有更高的切换开销,而 v-show有更高的初始渲染开销。因此,如果需要非常频
    繁地切换,则使用 v-show较好;如果在运行时条件很少改变,或控制的是一个组件,需要重新编译,则使用v-if 较好。
(4)v-else-if

为 v-if 或者 v-else-if 添加“else 块”。

v-else和v-else-if的前一兄弟元素必须有 v-if 或 v-else-if
  <div v-if="type === 'a'">
    a
  </div>
  <div v-else-if="type === 'b'">
    b
  </div>
  <div v-else-if="type === 'c'">
    c
  </div>
  <div v-else>
    not a/b/c
  </div>
6.列表渲染指令v-for

v-for基于源数据多次渲染元素或模板块,v-for指令中可以使用数组、对象。
数组语法: (item, index) in items其中items为源数据数组,item 为数组元素别名,index 为索引具有唯一性

例子:

    <div>
      <!-- 遍历对象 -->
      <div v-for="(val, key, index) in object" :key="index">{{ val }}{{ key }}{{
          index }}</div>
    </div>
  </template>
  <script>
    export default {
      data() {
        return {
          object: {
            name: '张三',
            age: '20'
          }
        };
      }
    };
  </script>

遍历对象渲染结果为:

张三name0
20age1

key 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需
要为每项提供一个唯一 key ,这个key 值必需要有且具有唯一性,通常建议使用id来作为key值,
不建议使用索引。

四、计算属性(computed)

计算属性可用于快速计算视图中显示的属性。这些计算将被缓存,并且只在需要时更新。所以,对于任 何复杂计算,都可以使用计算属性

  1. 定义在computed节点中,定义的时按照方法来定义,使用的时当做一个属性来使用。
  2. 可以提高代码复用性。
  3. 它计算的数据会被缓存,只有它所依赖的数据发生了变化才会重新计算,提升性能。

例计算数量的总数:

<template>
<div>
    <!-- 使用计算属性:当做一个属性来使用 -->
    <div>总数值:{{ count }}</div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                list: [
                    {
                        name: '数量01',
                        count: 10
                    },
                    {
                        name: '数量02',
                        count: 20
                    },
                    {
                        name: '数量03',
                        count: 30
                    }
                ]
            };
        },
        //在computed节点中定义方法count
        computed: {
            // 计算数量的总数
            count() {
                let countNum = 0;
                this.list.forEach(item => {
                    countNum += item.count;
                });
                return countNum;
            }
        },
        mounted() {
            console.log(this.count);
        }
    };
</script>

五、监听器(watch)

watch用于监听data里面的数据是否被修改,一旦修改就可以执行一些其他的操作。

  1. 监听data中的某个对象时,如果要实现对象中属性的改变能被监听到,需要使用 deep:true 属 性。
  2. 也可以直接监听data中对象的子属性的变化,则不需要加 deep:true ,可以使用’对象.属性’的方 式,注意一定要包裹一层引号,推荐使用单引号包裹。
  3. 如果需要首次进入页面就监听到数据,而不是等到数据改变才监听到,则需要添加 immediate:true 属性。
<template>
<div>
    <!-- 输入框num值改变,执行watch监听。改变numDouble变量-->
    <el-input v-model="num" placeholder="请输入内容"></el-input>
    <h2>监听num并*2:{{ numDouble }}</h2>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                num: 0,
                numDouble: 0,
                obj: {
                    a: 1,
                    b: 2
                }
            };
        },
        watch: {
            //监听num,函数第一个参数是变化后的新值,第二个参数是旧值
            num: function(newVal, oldVal) {
                this.numDouble = newVal*2;
            },
            //对象
            obj: {
                handler: function(newVal, oldVal) {
                    //...
                },
                deep: true //深度监听
            },
            //对象属性,使用单引号包裹
            'obj.a': {
                handler: function(newVal, oldVal) {
                    //...
                },
                immediate: true//控制侦听器是否自动触发,即首次进入页面就监听
            }
        },
        methods: {}
    };
</script>

六、过滤器(filter)

  1. 过滤器是 vue 中的一个特性,用于对文本进行格式化。在不改变原数据的前提下,对数据进行一定 程度的处理。
  2. 过滤器分为全局过滤器和局部过滤器,可以用在两个地方:{{ }}插值语法或 v-bind指令,用管道符 | 隔开。
<!-- 在{{ }}插值语法中, 格式:{{值 | 过滤器的名称}} -->
{{ message | capitalize }}
<!-- 在v-bind中, 格式:v-bind:id="值 | 过滤器的名称" -->
<div v-bind:id="rawId | formatId"></div>
<!-- 过滤器可以串联,管道符 | 隔开。 将filterA 的结果传递到 filterB 中-->
{{ message | filterA | filterB }}
<!-- 过滤器是 JavaScript 函数,因此可以接收参数 格式:{{ 值 | filter1(参数) |
fliter2(参数) }}-->
{{ message | filterA('arg1', arg2) }}

在开发中,需要用到过滤器的地方有很多,比如单位转换、数字打点、文本格式化、时间格式化之类的 等

例转换时间戳、个位补零:

<template>
<div>
    <!-- 局部过滤器 -->
    <!-- 要过滤的数据,永远是第一个参数;通过filter函数,传递的参数,依次排在后面 -->
    <div>日期转换:{{ startDate | dateFilter }}</div>
    <div>日期转换:{{ startDate | dateFilter('YYYY-MM-DD') }}</div>
    <!-- 全局过滤器 -->
    <p>个位补零</p>
    <p v-for="(num, index) in dateList" :key="index">{{ num | fillZero }}</p>
    </div>
</template>
<script>
    import moment from 'moment';
    export default {
        data() {
            return {
                startDate: new Date(),
                dateList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
            };
        },
        filters: {
            //处理日期格式
            dateFilter: function(time, pattern) {
                if (!pattern) {
                    pattern = 'YYYY-MM-DD HH:mm:ss';//默认格式
                }
                return moment(time).format(pattern);
            }
        }
    };
</script>

全局过滤器经常用在数据修饰上,通常我们把处理函数给抽离出去,统一放在一个 .js 文件中。

  1. 新建 filter.js 文件
//个位补零
function fillZero(num) {
return num < 10 ? `0${num}` : num;
}
//导出过滤器方法
export default {fillZero};
  1. main.js 中 引入注册 filter.js 文件
//引入过滤器
import filters from './utils/filter.js'
//注册过滤器,导入的是一个对象,所以使用Object.keys()方法,得到一个由key组成的数组,遍历数据
让key作为全局过滤器的名字
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key]);
});

七、组件

Vue 在实际开发过程中会存在重复使用的 UI 结构,我们可以将类似的 UI 结构提取出来封装成组件。

1、组件的使用

新建一个 vue 文件做为子组件。

1)import 导入

<script>
import ChildPage from './child-page';
</script>

2)components中注册

<script>
    import ChildPage from './child-page';
export default {
    components: {
        ChildPage
    }
}
</script>

3)template中以标签形式使用

<template>
    <div>
    <!-- 把组件名转换为中划线分割的方式使用,与前端开发规范保持一致 -->
    <child-page></child-page>
</div>
</template>
<script>
    import ChildPage from './child-page';
export default {
    components: {
        ChildPage
    }
    </script>

2 . 组件通信

1)父组件传值给子组件

1.通过 props传递

props 可以是数组或对象,用于接收来自父组件的数据。对象允许配置高级选项,如类型检测、自定义 验证和设置默认值。

实际工作开发中,我们都要求统一使用对象的形式。在传递的数值类型不正确时, vue 会报错方便我们 定位错误。 以对象形式接收参数的配置选项:
在这里插入图片描述

例父组件传递年龄age变量到子组件,其中age为子组件接收的名称:

<template>
<div>
    <!-- 我是父组件 -->
    <child-page :age="10"></child-page>
    </div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        }
    }
</script>

子组件通过props接收age并渲染:

<template>
<div>
    <!-- 我是子组件 -->
    <div>{{ age }}</div>
    </div>
</template>
<script>
    export default {
        props: {
            // 检测类型 + 验证
            age: {
                type: [String, Number],//支持多种type类型
                default: 0,//默认值和类型保持一致
                required: true,//必填项
                validator: function(value) {//自定义验证函数
                    return value >= 0;
                }
            },
            propA: {
                type: Number,//单个type类型
                default: 0
            },
            propB: {
                type: String,
                default: ''
            },
            propC: {
                type: Array,
                default() {
                    return [];
                }
            },
            propD: {
                type: Object,
                default() {
                    return {};
                }
            },
            propE: {
                type: Boolean,
                default: false
            }
        }
    };
</script>

传递静态Prop,可以像这样给 prop 传入一个静态的值:

<blog-post title="My journey with Vue"></blog-post>
  • 单向数据流概念

所有的 prop 都使其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件 中,但是反过来则不行(子组件不能直接修改父组件传过来的值)。这样会防止从子组件意外变更父级 组件的状态,从而导致你的应用的数据流向难以理解。

每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一 个子组件内部改变 prop。如果你这样做了, Vue 会在浏览器的控制台中发出警告。

例 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个 计算属性:

父组件

<template>
<div>
    <!-- 我是父组件 -->
    <child-page :size="size"></child-page>
    </div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        },
        data() {
            return {
                size: 'M'
            };
        }
    };
</script>

子组件

<template>
<div>
    <!-- 插值表达式使用normalizedSize属性渲染 -->
    <div>{{ normalizedSize }}</div>
    </div>
</template>
<script>
    export default {
        //props接收
        props: {
            size: {
                type: String,
                default: null
            }
        },
        //在computed节点中定义方法normalizedSize
        computed: {
            normalizedSize: function() {
                return this.size.toLowerCase(); //转换成小写
            }
        }
    };
</script>

2、父组件通过ref调用子组件方法传值 this.$refs

例父组件:

<template>
<div>
    <!-- 在子组件上绑定ref -->
    <child-page ref="childRef"></child-page>
    <el-button type="primary" @click="getChildInit()">点击按钮调用子组件方法</elbutton>
    </div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        },
        data() {
            return {};
        },
        created() {},
        mounted() {},
        methods: {
            //调用子组件initDate方法
            getChildInit() {
                let val = "父组件传递值";
                this.$refs.childRef.initDate(val);
            }
        }
    };
</script>

子组件

<template>
<!-- 我是子组件 -->
  <div></div>
</template>
<script>
    export default {
        data() {
            return {};
        },
        created() {},
        mounted() {},
        methods: {
            //父组件调用
            initDate(val) {
                //val是:父组件传递值
                this.$message({
                    message: '我是子组件的方法',
                    type: 'success'
                });
            }
        }
    };
</script>

2)子组件传值给父组件

这里需要用到 vue 的一个实例方法** e m i t ∗ ∗ , ∗ ∗ emit**,** emitemit**通常用于子组件调用父组件方法,实现子组件主动与 父组件进行通讯传值。

语法:[vm.$emit( eventName, …args)]

参数: {string} eventName 事件名 […args] 参数 触发当前实例上的事件。附加参数都会传给监听器回调。

<template>
<div>
    <!-- 我是子组件 -->
    <button type="default" @click="toParentData">触发事件传值给父组件</button>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                title: '我是子组件'
            };
        },
        methods: {
            // 子组件调用vm.$emit方法
            // 注意:这里的getData是父组件中绑定的事件名
            toParentData() {
                this.$emit('getData', this.title);
            }
        }
    };
</script>

<template>
<div>
    <!-- 父组件,通过@绑定了一个getChildData事件来监听子组件的触发事件 -->
    <child-page @getData="getChildrenData"></child-page>
    </div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        },
        data() {
            return {
                title: ''
            };
        },
        methods: {
            // 用自定义事件来接收子组件传的值
            getChildrenData(e) {
                this.title = e;
            }
        }
    };
</script>

3 . 插槽的使用

插槽是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板 代码,如 HTML、组件等,填充的内容会替换子组件的标签。

1)默认插槽:在子组件内使用 slot 标签占位,在slot标签内的内容为默认内容,如果不传值,则显示默 认内容。

例:父组件默认展示子组件的内容,填充内容后替换默认内容

<!-- 我是父组件 -->
<template>
<!-- 展示子组件默认内容 -->
	<child-page></child-page>
<!-- 展示父组件填充内容 -->
	<child-page>我替换了myslot</child-page>
</template>
<!-- 我是子组件 -->
<template>
	<div>
    	<slot>默认显示我</slot>
    </div>
</template>

2)具名插槽:一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据 这个名字把内容填充到对应插槽中。

  1. 在子组件的slot标签上设置name属性
  2. 父组件的template上结合 v-slot:子组件的name值 ,来指定对应的插槽 例:一个上中下布局,父组件填充到对应位置
<!-- 具名插槽子组件 -->
<template>
<div class="container">
    <header>
        <!-- 我们希望把页头放这里 -->
        <slot name="header"></slot>
    </header>
    <main>
        <!-- 我们希望把主要内容放这里 -->
        <slot></slot>
    </main>
    <footer>
        <!-- 我们希望把页脚放这里 -->
        <slot name="footer"></slot>
    </footer>
    </div>
</template>
<!-- 我是父组件 -->
<template>
<child-page>
    <!-- v-slot:子组件的name值,指定对应的插槽 -->
    <template v-slot:header>
</template>
<p>主要内容</p>
<template v-slot:footer>
<p>页脚</p>
</template>
</child-page>
</template>

3)作用域插槽:子组件往插槽上绑定数据,父组件使用时可接收

  1. 在子组件slot标签使用v-bind绑定数据
  2. 使用组件时父组件在 template 标签上使用 v-slot=“变量名” 来接收子组件传递过来的数据 例:一个列表组件,在父组件触发点击按钮并获取参数
<!-- 列表子组件 -->
<template>
<div>
    <ul>
        <li v-for="(item,index) in list" :key="item.id">
            <!-- v-bind绑定数据 -->
            <slot :item='item'></slot>
    </li>
    </ul>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                list:[
                    {
                        name:'作用域插槽1',
                        id:1
                    },
                    {
                        name:'作用域插槽2',
                        id:2
                    },
                    {
                        name:'作用域插槽3',
                        id:3
                    }
                ]
            }
        }
    }
</script>
<!-- 我是父组件 -->
<template>
<div>
    <child-page>
        <!-- v-slot="变量名" 来接收子组件传递过来的数据 -->
        <template v-slot="slotProps">
            <el-button type="primary" @click="slotFn(slotProps.item)">父组件按钮
                {{slotProps.item.id}}</el-button>
</template>
</child-page>
</div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        },
        data() {
            return {};
        },
        methods: {
            slotFn(row){
                this.$message({
                    message: row,
                    type: 'success'
                });
            }
        }
    };
</script>

() {
return {
list:[
{
name:‘作用域插槽1’,
id:1
},
{
name:‘作用域插槽2’,
id:2
},
{
name:‘作用域插槽3’,
id:3
}
]
}
}
}


```vue
<!-- 我是父组件 -->
<template>
<div>
    <child-page>
        <!-- v-slot="变量名" 来接收子组件传递过来的数据 -->
        <template v-slot="slotProps">
            <el-button type="primary" @click="slotFn(slotProps.item)">父组件按钮
                {{slotProps.item.id}}</el-button>
</template>
</child-page>
</div>
</template>
<script>
    import ChildPage from './child-page';
    export default {
        components: {
            ChildPage
        },
        data() {
            return {};
        },
        methods: {
            slotFn(row){
                this.$message({
                    message: row,
                    type: 'success'
                });
            }
        }
    };
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

session和JWT的应用及区别

文章目录 登录认证(node)一、session1.下载session2.全部配置session3.存储session4.获取session5.销毁session 二、JWT (Json web token)1.JWT 的工作原理2.JWT 的组成3.下载JWT4.生成token5.解密TOken6.配置全局错误中间件 登录认证(node) 一、session 一、在node中使用sess…

还不懂Redis?看完这个故事就明白了!

还不懂Redis?看完这个故事就明白了! 我是Redis 你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上。 说起我的诞生,跟关系数据库MySQL还挺有渊源的。 在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网发展的越来越快,它容纳的数据也越来越多,用户请求也…

全国独家专利药品有哪些品种?全国独家药品产品汇总查阅

独家药品一般是指某一家药企拥有生产和销售某种药品的独家权利&#xff0c;细分有活性成分独家&#xff08;通用名成分独家&#xff09;、品种独家&#xff08;同成分不同剂型&#xff09;、独家品规&#xff0c;通俗可以分成药品功能独家和产品独家。独家药品经常被人认为是具…

证件拍照扫描——基于C++与深度神经网络实现证件识别扫描并1比1还原证件到A4纸上

前言 数字化时代的到来&#xff0c;越来越多的证件需要进行电子化处理&#xff0c;例如身份证、驾驶证、护照等。在进行电子化处理时&#xff0c;最常见的需求就是将证件照片复制到A4纸上&#xff0c;以便于打印、存档或传输。同时&#xff0c;为了方便信息的录入和管理&#…

一条命令搭建HTTP服务器

文章目录 1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试 3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 转载自远程内网穿透的文章&#xff1a;【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透…

word自带公式编辑

快捷键&#xff1a; 公式编辑&#xff1a;alt“” 上标&#xff1a;x^i 空格 下标&#xff1a;x_i 空格 实数R&#xff1a;\doubleR 空格 偏微分算子&#xff1a;“\partial” 极限&#xff1a;“\limit”&#xff08;按空格后会显示一串很长的式子&#xff0c;再空格就变…

在Linux操作系统上部署wgcloud监控

1.wgcloud监控介绍 1.1 介绍 ​ 这是一款开源的主机监控系统&#xff0c;可以支持主机各种指标监测&#xff08;cpu使用率&#xff0c;cpu温度&#xff0c;内存使用率&#xff0c;磁盘容量空间&#xff0c;磁盘IO&#xff0c;硬盘SMART健康状态&#xff0c;系统负载&#xff…

starrocks基于prometheus实现监控告警

监控报警 本文介绍如何为 StarRocks 设置监控报警。 StarRocks 提供两种监控报警的方案。企业版用户可以使用内置的 StarRocksManager&#xff0c;其自带的 Agent 从各个 Host 采集监控信息&#xff0c;上报至 Center Service&#xff0c;然后做可视化展示。StarRocksManager …

[陇剑杯 2021]之Misc篇(NSSCTF)刷题记录⑤

NSSCTF-Misc篇-[陇剑杯 2021] 日志分析:[陇剑杯 2021]日志分析&#xff08;问1&#xff09;[陇剑杯 2021]日志分析&#xff08;问2&#xff09;[陇剑杯 2021]日志分析&#xff08;问3&#xff09; 简单日志分析&#xff1a;[陇剑杯 2021]简单日志分析&#xff08;问1&#xff0…

Python制作一个自动发送弹幕的工具,让你看直播不冷场

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 让我们先看看效果&#xff1a; 名字我就打码了&#xff0c;当然名字不是关键&#xff0c;我直接截图展示算了&#xff0c;GIF的话&#xff0c;太麻烦了。 环境使用: Python 3.8 / 编译器 Pycharm 2021.2版本 / 编辑器…

存在列排斥力的另一例证

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A中有5个1&#xff0c;B中全是0&#xff0c;排列组合A的所有可能&#xff0c;统计迭代次数的顺序。其中有12组数据 A-B 迭代次数 1 0 1 5*4*2*1…

Inception 深度卷积神经网络(CNN)架构

Inception是一种深度卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;由Google在2014年提出。它是一种基于多尺度卷积的网络结构&#xff0c;旨在解决传统CNN在处理不同大小的输入图像时存在的问题。 Inception的主要特点是使用了多个不同尺度的卷积核来提取不同尺度…

API测试| 了解API接口测试| API接口测试指南(一)

什么是API&#xff1f; API是一个缩写&#xff0c;它代表了一个 pplication P AGC软件覆盖整个房间。API是用于构建软件应用程序的一组例程&#xff0c;协议和工具。API指定一个软件程序应如何与其他软件程序进行交互。 例行程序&#xff1a;执行特定任务的程序。例程也称为过…

人脸检测和行人检测2:YOLOv5实现人脸检测和行人检测(含数据集和训练代码)

人脸检测和行人检测2&#xff1a;YOLOv5实现人脸检测和行人检测(含数据集和训练代码) 目录 人脸检测和行人检测2&#xff1a;YOLOv5实现人脸检测和行人检测(含数据集和训练代码) 1. 前言 2. 人脸检测和行人检测数据集说明 &#xff08;1&#xff09;人脸检测和行人检测数据…

初识C++之左值引用与右值引用

目录 一、左值引用与右值引用 1. 左值和右值的概念 1.1 左值 1.2 右值 1.3 左值与右值的区分 2. 左值引用与右值引用 2.1 左值引用与右值引用的使用方法 2.2 左值引用的可引用范围 2.3 右值引用的可引用范围 3. 右值引用的作用 3.1 减少传值返回的拷贝 3.2 插入时的…

2023北京新一代信息技术应用融合创新人才发展峰会暨鲲鹏开发者创享日·北京站成功举办

以技术创新促产业发展&#xff0c;以开放使能筑人才根基 4月25日&#xff0c;由北京市经济和信息化局、北京市朝阳区人民政府、国家工业信息安全发展研究中心与华为技术有限公司联合主办&#xff0c;北京鲲鹏联合创新中心、北京市中小企业公共服务平台、中国软件行业协会承办的…

字节超全学习流程图流出,100天涨薪10k,从功能测试到自动化测试

今年年初&#xff0c;由于经济压力让我下定决心进阶自动化测试&#xff0c;已经24的我做了3年功能测试&#xff0c;坐标广州薪资定格在8k&#xff0c;可能是生活过的太安逸&#xff0c;觉得8000的工资也够了。 但是生活总是多变的&#xff0c;女朋友的突然怀孕&#xff0c;让我…

软件测试面试一定要看的面试题和笔试题全套教程

1、什么是软件测试&#xff1f;2’ 【要点】 在规定条件下对程序进行操作&#xff0c;以发现错误&#xff0c;对软件质量进行评估&#xff0c;包括对软件形成过程的文档、数据以及程序进行测试。 【详解】 软件测试就是在软件投入运行前对软件需求分析、软件设计规格说明书…

ApplicationContextAware接口

一、ApplicationContextAware接口的基本介绍 public interface ApplicationContextAware extends Aware {void setApplicationContext(ApplicationContext applicationContext) throws BeansException;}在Spring/SpringMVC中&#xff0c;我们拿到IOC容器无非有三种方式&#x…

通达信结构紧凑形态选股公式编写思路

在威廉欧奈尔的《笑傲股市》、马克米勒维尼的《股票魔法师》等书籍中都有结构紧凑形态的相关描述&#xff0c;股票在形成基底时&#xff0c;价格波动幅度逐渐减小&#xff0c;量能逐步萎缩&#xff0c;同时价格相对强度较高。 结构紧凑的形态通过眼睛观察&#xff0c;一般可以…