Vue学习 is特性的使用 text/x - template 类型应用 父子组件的定义及使用 组件作用域 props选项

is特性的使用

当模板为某种标签的子元素 比如table的tr ul的li

<body>
    <div id="app">
        <component-tr></component-tr>
    </div>
    <script>
        var componentTr = {
    
    
            template: "<tr><td>学号</td><td>姓名</td></tr>"
        }

        var vm = new Vue({
    
    
            el: "#app",
            data: {
    
    
                msg: "hello"
            },
            components: {
    
    
                "component-tr": componentTr
            }
        })
    </script>
</body>

在这里插入图片描述

渲染出来的页面tr没有在table标签内包裹 ,虽然还是能够渲染出页面,但这并不符合w3c标准

如果要解决这个问题需要用到is属性的特性

<div id="app">
        <table>
            <tr is='component-tr'></tr>
        </table>
    </div>

在这里插入图片描述
这样的话就符合w3c标准了。
注意:外面的table标签一定要加上,然后把自定义组件名作为is的属性值再次运行

text/x - template 类型应用

之前写过的定义模板的方式都是为模板设置模板字符串,也称之为内联模板字符串
这种写法的缺点就是如果模板字符串中的HTML代码很多,那么写起来就非常的不方便并且不好换行。
Vue中还有另一种自定义模板的方式,也就是写在script元素中,并为其带上text/x-template的类型,通过一个id对模板进行引用。其实就是相当于前面全局组件中内置template的写法。

注意:x-template模板需要定义在Vue所属的DOM元素外,与DOM元素并列

<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <table>
            <tr is='component-tr'></tr>
        </table>
    </div>
    <script type="text/x-template" id="tmp1">
        <tr>
            <td>学号</td>
            <td>姓名</td>
        </tr>
    </script>
    <script>
        var componentTr = {
    
    
            template: "#tmp1"
        }

        var vm = new Vue({
    
    
            el: "#app",
            data: {
    
    
                msg: "hello"
            },
            components: {
    
    
                "component-tr": componentTr
            }
        })
    </script>
</body>

</html>

在script标签的属性中写进type=“text/x-template” ,就可以在其中写组件的模板,注册组件的时候就只需要在template选项中引用这个模板的id就可以了(注意要加引号)。

在注册组件时,还可以添加data属性,然后就可以引用data属性的数据:

<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <table>
            <tr is='component-tr'></tr>
        </table>
    </div>
    <script type="text/x-template" id="tmp1">
        <tr>
            <td>{
    
    {
    
    num}}</td>
            <td>{
    
    {
    
    name}}</td>
        </tr>
    </script>
    <script>
        var componentTr = {
    
    
            template: "#tmp1",
            data: function () {
    
    
                return {
    
    
                    num: 12,
                    name: "xiaoming",
                }
            }
        }

        var vm = new Vue({
    
    
            el: "#app",
            data: {
    
    
                msg: "hello"
            },
            components: {
    
    
                "component-tr": componentTr
            }
        })
    </script>
</body>

</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>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <table>
            <tr is='component-tr'></tr>
        </table>
    </div>
    <script type="text/x-template" id="tmp1">
        <div>  
            <tr v-for="item in stulist">
                <td>{
    
    {
    
    item.num}}</td>
                <td>{
    
    {
    
    item.name}}</td>
            </tr>
        </div>      
    </script>
    <script>
        var componentTr = {
    
    
            template: "#tmp1",
            data: function () {
    
    
                return {
    
    
                    stulist: [
                        {
    
     id: 12, name: 'xiaoming' },
                        {
    
     id: 13, name: 'xiaozhang' },
                        {
    
     id: 14, name: 'xiaoli' },
                    ]
                }
            }
        }

        var vm = new Vue({
    
    
            el: "#app",
            data: {
    
    
                msg: "hello"
            },
            components: {
    
    
                "component-tr": componentTr
            }
        })
    </script>
</body>

</html>

在这里插入图片描述

父子组件的定义及使用

1、什么是父子组件?
在一个组件内部定义了另一个组件,称为父子组件。子组件只能在父组件的内部使用。

<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <my-comp1></my-comp1>
        <!-- 在这里直接使用my-comp2这个子组件会报错,因为他是在my-comp1这个组件里面,也就是没有在根组件下注册 -->
    </div>

    <script type="text/x-template" id="comp1">
        <div>
            <h3>我是comp1父组件</h3>
            <hr>
            <my-comp2></my-comp2>
        </div>

    </script>

    <template id="comp2">
        <div>
            <h3>我是comp2子组件</h3>
        </div>
    </template>

    <script>
        var vm = new Vue({
    
      //根组件
            el: "#app",
            data: {
    
    

            },
            components: {
    
     //父组件
                'my-comp1': {
    
    
                    data() {
    
    
                        return {
    
    
                            msg: "123456",
                            name: "zhangsan",
                            age: 19,
                            user: {
    
     id: 11, username: "zhangsan" }
                        }
                    },

                    template: "#comp1",
                    components: {
    
                       //子组件
                        'my-comp2': {
    
    
                            template: "#comp2"
                        }

                    }
                },



            }
        })
    </script>
</body>

</html>

渲染结果如下:

在这里插入图片描述

结论:子组件只能在其父组件中使用,这里id为app 的div 就是根组件,同时也是comp1的父组件
同时comp1也是comp2的父组件, 子组件只能够在父组件中去使用

  • 每个组件的作用域是独立的

在上面例子斜体代码下面增加如下代码(在自己的组件中访问自己的数据):

<h3>访问自己组件中的数据:{
    
    {
    
    msg}} {
    
    {
    
    name}} {
    
    {
    
    age}}</h3>

在这里插入图片描述
可以看到在父组件中访问到了父组件data属性储存的数据

如果在子组件中输入这样的代码则会产生报错,这是因为正常情况下子组件无法访问到父组件中的数据。当然父组件也无法访问子组件中的数据,每个组件实例的作用域是相互独立的

子组件访问父组件中的数据

子组件访问父组件中的数据的步骤如下:
1、在调用子组件时,绑定想要获取的父组件的数据
2、在子组件的内部,使用props选项声明获取的数据,即接收来自父组件的数据。

经过上面两个步骤,子组件访问父组件的数据就变成了获取自己组件中的数据,因为父组件中的数据已经传给了子组件。

<!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>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <my-comp1></my-comp1>
        <!-- 在这里直接使用my-comp2这个子组件会报错,因为他是在my-comp1这个组件里面,也就是没有在根组件下注册 -->
    </div>

    <script type="text/x-template" id="comp1">
        <div>
            <h3>我是comp1父组件</h3>
            <h3>访问自己组件中的数据:{
    
    {
    
    msg}} {
    
    {
    
    name}} {
    
    {
    
    age}}</h3>
            <hr>
            //调用子组件时,绑定想要获取的父组件的数据,这里绑定的message是自己取得名称,这里为了区分先取名为message
            <my-comp2 :message='msg'></my-comp2>
            
        </div>

    </script>

    <template id="comp2">
        <div>
            <h3>我是comp2子组件</h3>
            <h4>访问父组件的数据{
    
    {
    
    message}}</h4>
        </div>
    </template>

    <script>
        var vm = new Vue({
    
      //根组件
            el: "#app",
            data: {
    
    

            },
            components: {
    
     //父组件
                'my-comp1': {
    
    
                    data() {
    
    
                        return {
    
    
                            msg: "123456",
                            name: "zhangsan",
                            age: 19,
                            user: {
    
     id: 11, username: "zhangsan" }
                        }
                    },

                    template: "#comp1",
                    components: {
    
                       //子组件
                        'my-comp2': {
    
    
                            template: "#comp2",
                            //在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据 采用字符串数组形式
                            props: ['message']
                        }

                    }
                },



            }
        })
    </script>
</body>

</html>

注意:在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据 采用字符串数组形式

调用子组件时,绑定想要获取的父组件的数据,这里绑定的message是自己取得名称,这里为了区分先取名为message

组件中props选项用法深入

props接收父组件中的选项的数据采用的是简单的方式,即采用字符串数组的形式。
props可以是简单的数组,或者使用对象作为替代,对象允许配置最高级的选项,如类型检测、自定义验证和设置默认值。props对象可以有以下选项:

  • type:x
  • default:any
  • required:Boolean
  • validator:Function

第一种中的x可以是原生构造函数中的一种,也可以是自定义构造函数或以上内容组成的数组。设置prop就会检查prop是否为给定的类型,否则会抛出警告

第二种中的选项是为prop指定一个默认值,如果该prop没有被传入,则换用这个值。对象或数组的默认值必须从一个工厂函数返回。

第三种中的是定义prop是否为必填项。在非生产环境中,如果这个值为true且该prop没有被传入,则会报出警告

自定义验证函数会将该prop的值作为唯一的参数代入。在非生产环境下,如果该函数返回了一个false值,就会出警告

父组件访问子组件中的数据

子组件通过props选项可以接收父组件中的数据,父组件同样也可以访问子组件中的数据

父组件访问子组件中的数据基本用法

父组件访问子组件数据的总体思路:把子组件中的数据发送到父组件中,主要有两个步骤:
1、在子组件中使用vm.$emit(事件名,要发送的数据)触发一个自定义事件,事件名自定义。要发送多个数据,直接用逗号隔开
2、父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法获取数据。

猜你喜欢

转载自blog.csdn.net/fuhao6363/article/details/129618091
今日推荐