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

文章目录

    • 一、 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.mfbz.cn/a/15296.html

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

相关文章

912. 排序数组

1.题目&#xff1a; 2.我的代码&#xff1a; C语言&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ int* sortArray(int* nums, int numsSize, int* returnSize) {//希尔排序int gap numsSize;//多次预排while (gap > 1) {/…

Ansys Zemax | 如何模拟双折射偏振器件

这篇文章介绍了什么是双折射现象、如何在OpticStudio中模拟双折射 (birefringence)、如何模拟双晶体的双折射偏振器以及如何计算偏振器的消光比。&#xff08;联系我们获取文章附件&#xff09; 什么是双折射现象 一般的光学材料都是均匀的各向同性的&#xff0c;也就是说无论光…

STM32物联网实战开发(6)——PWM驱动LED灯

PWM驱动LED灯 之前是使用标准库函数配置引脚输出PWM控制呼吸灯&#xff0c;因为开发板上的蜂鸣器是有源的&#xff0c;所以这次还是用来确定LED灯&#xff0c;这次使用的是HAL库&#xff0c;用CubeMX软件初始化PWM功能 PWM输出原理 Period&#xff1a;周期&#xff0c;单位是秒…

语音处理加窗分帧

语音处理加窗分帧 一、分帧 语音数据和视频数据不同&#xff0c;本没有帧的概念&#xff0c;但是为了传输与存储&#xff0c;我们采集的音频数据都是一段一段 的。为了程序能够进行批量处理&#xff0c;会根据指定的长度(时间段或者采样数)进行分段&#xff0c;结构化为我们编程…

Javaweb | 转发、重定向

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 转发 转发与页面跳转 转发 转发的作用在服务器端&#xff0c;将请求发送给服务器上的其他资源&#xff0c;以共同完成一次请求的处理 页面跳转 使用forward跳转时&am…

拍卖小程序开发:从需求分析到设计实现

在当今数字时代&#xff0c;拍卖小程序已经成为了一个重要的销售和交易工具。拍卖小程序的开发不仅能够提供高效的销售渠道&#xff0c;还能够为用户提供全新的购物体验。因此&#xff0c;开发一个拍卖小程序成为了许多商家的首要任务。 拍卖小程序的开发可以帮助商家拓展销售…

Linux下实现共享内存的两种机制(附源码)

START Hello 大家好。 今天来讲一下Linux进程通信中重要的通信方式&#xff1a;共享内存作为Linux软件开发攻城狮&#xff0c;进程间通信是必须熟练掌握的重要技能&#xff0c;而共享内存是在程序开发中常用的也是重要的一种进程间通信方式。 下面我们就来聊一聊Linux下进程间…

pytest自动化框架之allure测试报告的用例描述设置

allure测试报告的用例描述相关方法&#xff1b;如下图 allure标记用例级别severity 在做自动化测试的过程中&#xff0c;测试用例越来越多的时候&#xff0c;如果执行一轮测试发现了几个测试不通过&#xff0c;我们也希望能快速统计出缺陷的等级。 pytest结合allure框架可以对…

每日学术速递4.26

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.AutoNeRF: Training Implicit Scene Representations with Autonomous Agents 标题&#xff1a;AutoNeRF&#xff1a;使用自主代理训练隐式场景表示 作者&#xff1a;Pierre Marz…

SaaS云HIS系统源码功能介绍

SaaS云HIS首页功能&#xff1a;包括工作计划、预警、主功能菜单、医院机构公告。 一、工作计划 1.值班概况&#xff1a;值班日期、值班时间、值班科室&#xff08;内科、外科等&#xff09; 2.待处理患者&#xff1a;内科人数、外科人数等 病历统计&#xff1a;入院病历、出…

华为面试题:1+4=5,2+5=12,3+6=21,问8+11=?网友:幼儿园级别

面试&#xff0c;一直都是职场人士绕不过去的坎&#xff0c;对于有的人来说&#xff0c;或许更擅长日常的工作&#xff0c;在面试环节可谓是自己的薄弱环节&#xff0c;但对于有的人来说&#xff0c;相比于工作&#xff0c;更擅长应付面试&#xff01; 最近&#xff0c;有一位…

《面向基于人工智能的学习健康系统,使用心电图进行人群水平的死亡率预测》阅读笔记

目录 一、摘要 二、十个问题 Q1论文试图解决什么问题&#xff1f; Q2这是否是一个新的问题&#xff1f; Q3这篇文章要验证一个什么科学假设&#xff1f; Q4有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课题在领域内值得关注的研究员&#xff1f; Q5论文中提到…

过来人转本考试后的感悟和经验,真的很受用

过来人转本考试后的感悟和经验&#xff0c;真的很受用&#xff01;转本不仅是分数的较量&#xff0c;也是信息收集、时间管理、学习能力、毅力等等的较量。同学们在转本中难免会遇见一些困难&#xff0c;为了避免走弯路&#xff0c;一起来看看过来人的感悟和经验吧&#xff01;…

项目范围控制:如何控制项目范围的变化?

一个成功的项目需要在进度、成本和质量之间取得平衡。控制项目交付范围是实现这个平衡的关键。然而&#xff0c;项目范围是会变化的&#xff0c;因此控制项目范围变化是必要的。 如何控制项目范围的变化&#xff1f; 1、了解项目的交付范围 项目经理、团队成员、利益相关者和…

verilog手撕代码3——序列检测和序列发生器

文章目录 前言一、序列检测器1.1 重复序列检测1.1.1 序列缓存对比/移位寄存器法1.1.2 状态机法 1.2 非重复序列检测 二、序列发生器2.1 移位寄存器法2.2 反馈法2.3 计数器法 前言 2023.4.25 2023.4.26 学习打卡&#xff0c;天气转晴 一、序列检测器 1.1 重复序列检测 1.1.1 …

等级保护、风险评估和安全测评分别是什么?

2022-06-17 15:17 迈入“等保2.0时代”以后&#xff0c;我国对于等级保护的要求更为严格和具体。等级保护、风险评估和安全测评这三个词&#xff0c;也因此总是出现在人们的视野之中&#xff0c;还总是被混淆。那这三者究竟分别是什么呢&#xff1f;如何区分它们&#xff1f;它…

【Bus】编写一个Demo虚拟的总线-设备-驱动模型

文章目录 1. 前言2. 总线驱动模型三要素2.1 总线2.2 设备2.3 驱动 3. Demo Code3.1 virt_bus_core.c3.2 virt_device.c3.3 virt_driver.c 4. 工程代码下载地址5. 参考资料 1. 前言 Linux平台为了驱动的可重用性&#xff0c;虚拟了很多的虚拟总线。很经典的就是platform总线&am…

如何编写高质量代码、提高编程效率?

一、 前言 高质量代码是指在满足功能需求的基础上&#xff0c;具备高性能、安全、可扩展、易维护、可测试等特点的代码。它不仅可以提高开发效率和代码质量&#xff0c;更能有效减少代码维护成本&#xff0c;促进团队协作和项目成功。因此&#xff0c;编写高质量代码对程序员来…

【Java】什么是SOA架构?与微服务有什么关系?

文章目录 服务化架构微服务架构 我的一个微服务项目&#xff0c;有兴趣可以一起做 服务化架构 我们知道&#xff0c;早期的项目&#xff0c;我们都是把前后端的代码放在同一个项目中&#xff0c;然后直接打包运行这个项目&#xff0c;这种项目我们称之为单体项目&#xff0c;比…