Vue插槽、ref和$refs用法

1.vue插槽

1.插槽的作用:以局部组件为例

  插槽就是Vue实现的一套内容分发的API,将<slot></slot>元素作为承载分发内容的出口。插槽内可以是任意内容。

(1)不带插槽的情况:

        <div id="app">
            <vue>
                <h2>我是里面的内容</h2></vue>
        </div>

        <script>
            var Child = {
                template: ‘<div><h1>自定义组件!</h1></div>‘
            }

            // 创建根实例
            new Vue({
                el: ‘#app‘,
                components: {
                    // <vue> 将只在父模板可用
                    ‘vue‘: Child
                }
            })
        </script>

结果:组件标签内的元素不会显示

(2)带插槽的情况:标签内部的元素会被置于<slot></slot>的位置

        <div id="app">
            <vue>
                <h2>我是里面的内容</h2></vue>
        </div>

        <script>
            var Child = {
                template: ‘<div><h1>自定义组件!</h1><slot></slot></div>‘
            }

            // 创建根实例
            new Vue({
                el: ‘#app‘,
                components: {
                    // <vue> 将只在父模板可用
                    ‘vue‘: Child
                }
            })
        </script>

结果:

2.编译作用域

  父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

  插槽跟模板的其它地方一样可以访问相同的实例属性 (也就是相同的“作用域”),而不能访问 插槽上的属性。

如下:slot内部可以访问到vue实例的msg属性,访问不到组件的message属性。

        <div id="app">
            <vue message="message123">
                <h2>{{msg}}</h2>
                <h2 v-if="typeof  message != ‘undefined‘">{{message}}</h2>
                <h2 v-else>访问不到message属性</h2>
            </vue>
        </div>

        <script>
            var Child = {
                template: ‘<div><h1>自定义组件!</h1><h2>{{message}}</h2><br/><slot></slot></div>‘,
                // 声明 props属性
                props: [‘message‘],
            }

            // 创建根实例
            new Vue({
                el: ‘#app‘,
                components: {
                    // <vue> 将只在父模板可用
                    ‘vue‘: Child
                },
                data: {
                    msg: ‘这是msg‘
                }
            })
        </script>

结果:

3.带有 slot-scope 特性的作用域插槽

  在组件上的属性,可以在组件元素内使用!

(1)  在 <template> 上使用特殊的 slot-scope 特性,可以接收传递给插槽的 prop

        <div id="app">
            <child>
                <template slot-scope="a">
                    {{a}}
                    <br /> {{a.username}}
                </template>
            </child>
        </div>
        <script>
            Vue.component(‘child‘, {
                template: `
            <div>
                <slot username="张三"></slot>
            </div>
        `

            })

            let vm = new Vue({
                el: ‘#app‘
            })
        </script>

结果:

解释:

(1)组件中的<slot username="张三"></slot>定义了一个属性,

(2)slot-scope 声明了被接收的 a 对象会作为 a 变量存在于 <template> 作用域中。你可以像命名 JavaScript 函数参数一样随意命名 a

(3)slot-scope 特性也可以直接用于非 <template> 元素 (包括组件):

            <child>
                <h3 slot-scope="a">{{a}}=={{a.username}}</h3>
            </child>

结果:

(2)获取组件上值

        <div id="app">
            <child componentmsg="123456">
                <h3 slot-scope="a">{{a}}</h3>
            </child>
        </div>
        <script>
            Vue.component(‘child‘, {
                props: [‘componentmsg‘],
                template: `
            <div>
                <slot :slotmsg="componentmsg"></slot>
            </div>
        `
            })

            let vm = new Vue({
                el: ‘#app‘
            })
        </script>

结果:

(3)获取vue实例属性:(组件的属性动态获取实例的属性)

        <div id="app">
            <child :componentmsg="vueMsg">
                <h3 slot-scope="a">{{a}}</h3>
            </child>
        </div>
        <script>
            Vue.component(‘child‘, {
                props: [‘componentmsg‘],
                template: `
            <div>
                <slot :slotmsg="componentmsg"></slot>
            </div>
        `
            })

            let vm = new Vue({
                el: ‘#app‘,
                data: {
                    vueMsg: ‘这是实例属性‘
                }
            })
        </script>

结果:

补充:自 2.6.0 起有所更新。上面使用 slot-scope 特性的语法已经废弃。2.6以后做法如下:绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

        <div id="app">
            <child :user="user">
                <template v-slot:default="slotProps"> {{ slotProps.user.firstName }}</template>
            </child>
        </div>
        <script>
            Vue.component(‘child‘, {
                props: [‘user‘],
                template: `
            <div>
                <slot v-bind:user="user"></slot>
            </div>
        `
            })

            let vm = new Vue({
                el: ‘#app‘,
                data: {
                    user: {
                        lastname: ‘张‘,
                        firstName: ‘三‘
                    }
                }
            })
        </script>

结果:

4..具名插槽

  有时候我们可能需要多个插槽。slot有一个特殊的属性,name可以用于定义额外的插槽。

例如:不带名称的默认都会被放在无名称的slot内。

        <div id="app">
            <vue>
                <template slot="h1s">
                    <p>这里是h1的内容</p>
                </template>
                <template slot="h2s">
                    <b><p>这里是h2的内容</p></b>
                </template>
                <p slot="h1s">这里是其他内容</p>
                <p>这里是其他内容</p>
            </vue>
        </div>

        <script>
            var Child = {
                template: ‘<div><h1><slot name="h1s"></slot></h1><h2><slot name="h2s"></slot></h2><br/><hr/><slot></slot></div>‘
            }

            // 创建根实例
            new Vue({
                el: ‘#app‘,
                components: {
                    // <vue> 将只在父模板可用
                    ‘vue‘: Child
                },
                data: {
                    msg: ‘这是msg‘
                }
            })
        </script>

结果:

补充:上面是vue2.6之前的写法,vue2.6之后有所区别:

(1)一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

(2)在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称

(3)任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。

(4)注意 v-slot 只能添加在 <template> 上

        <div id="app">
            <vue>
                <template v-slot:h1s>
                    <p>这里是h1的内容</p>
                </template>
                <template v-slot:h2s>
                    <b><p>这里是h2的内容</p></b>
                </template>
                <!--v-slot:default可以不写,默认都是default插槽的-->
                <template v-slot:default>
                    <b><p>这里是其他内容</p></b>
                </template>
            </vue>
        </div>

结果:

缩写:2.6.0 新增

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:h1s 可以被重写为 #h1s:

            <vue>
                <template #h1s>
                    <p>这里是h1的内容</p>
                </template>
                <template #h2s>
                    <b><p>这里是h2的内容</p></b>
                </template>
                <!--v-slot:default可以不写,默认都是default插槽的-->
                <template #default>
                    <b><p>这里是其他内容</p></b>
                </template>
            </vue>

5.动态插槽名

  vue2.6新增了动态参数,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数。

例如:

<a v-on:[eventName]="doSomething"> ... </a>

  在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus。

动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout><base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>

2.ref和$ref的使用

  ref被用来给组件或子元素注册引用信息,引用信息将会注册在父组件的$ref属性上。

  如果在普通的dom上使用,引用指向的就是DOM对象 ,$refs相对document.getElementById的方法,会减少获取dom节点的消耗。;如果用在子组件上,引用指向组件实例。

例如:

        <div id="app">
            <p ref="pref">p内容</p>
            <child ref="child">
                <template>插槽内容</template>
            </child>
        </div>
        <script>
            Vue.component(‘child‘, {
                template: `
            <div>
                <p ref="pref1">p1内容</p>
                <slot></slot>
            </div>
        `
            })

            let vm = new Vue({
                el: ‘#app‘,
            })

            console.log(vm.$refs.pref)
            console.log(vm.$refs.child)
            console.log(vm.$refs.child.$refs.pref1)
        </script>

结果:

原文地址:https://www.cnblogs.com/qlqwjy/p/12106565.html

时间: 2024-10-08 01:08:31

Vue插槽、ref和$refs用法的相关文章

vue的ref与$refs

一. ref使用在父组件上 父组件html: <information ref='information'></information> import information from './information' components:{information,bill,means}, 在父组件上使用子组件的值,js :this.$refs.information.isAdd;   isAdd是information组件的data的属性. 二.ref使用在元素上 例如本组件ht

关于vue中ref的使用方法

之前在项目中会通过ref在父子组件传递一些数据,但是具体ref的其他用法并没有深究,所以来了解一下ref的具体使用方法 first: <div ref="hello"> <!-- 绑定了data里面的值并渲染到页面--> <h1 v-model="msg">{{msg}}</h1> </div>//在方法或者生命周期的函数中获取数据 console.log(this.$refs.hello.innerTex

Vue 操作原生Dom refs

获取原生DOM 给标签或组件 添加ref属性 <div ref='alex'></div> <p ref='a'></p> <Home ref='b'></Home> this.$refs.alex // 获取原生的Dom对象 this.$refs.b // 获取的是组件的实例化对象 refs属性集合 console.log(this.$refs.input); // 获取原生DOM // 返回值 <input type=&qu

vue通过ref获取dom节点

HTML在任意节点上添加属性"ref" <span ref="span_01">span_01</span> <button @click="consoleDOM()">consoleDOM</button> SCRIPT vue里通过 this.$refs.xxx 获取 consoleDOM() { window.console.log(this.$refs.span_01) } 原文地址:htt

c# out ref parames的用法

out ref parames的用法(将值传递转换成引用传递) Out 一般用于返回多个值,在方法体中会清空out变量,侧重于一个方法有多个返回值得时候使用 Ref有进有出,可以在方法体外必须赋初值,侧重于将方法体外部的值传到方法体中计算,并将计算结果,带到方法体外面. Parames 作为形参,必须是形参列表中的左后一个参数,用法:getC(string name,parames int[] score) 在调用这个方法的时候后面被parames修饰的参数可以传一个与int[]类型相同的元素进

详解Vue中watch的高级用法

我们通过实例代码给大家分享了Vue中watch的高级用法,对此知识点有需要的朋友可以跟着学习下. 假设有如下代码: 上面的代码的效果是,当我们输入firstName后,wacth监听每次修改变化的新值,然后计算输出fullName. handler方法和immediate属性 这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算.那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 wa

vue里ref ($refs)用法

ref 有三种用法: 1.ref 加在普通的元素上,用this.ref.name 获取到的是dom元素 2.ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法. 3.如何利用 v-for 和 ref 获取一组数组或者dom 节点 注意: 1.ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成.比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用. 2.如果ref 是循环出

Vue组件传值、refs、插槽

一.组件传值 1.父组件向子组件传值 因为子组件本身不能拿到父组件的data数据来用,所以在子组件里用props接收,props是一个数组 父组件向子组件传值 <div id="app"> <com1 :parent="msg" :parentarr="arr"></com1> </div> <template id="com"> <div> {{pare

vue中的ref 及$refs

原文地址:https://www.cnblogs.com/huangqiao/p/9753919.html