首页 > 其他分享 >vue-组件、ref属性、动态组件、计算属性、监听属性

vue-组件、ref属性、动态组件、计算属性、监听属性

时间:2023-02-17 22:33:23浏览次数:41  
标签:vue name 标签 var template 组件 data 属性

1.组件其他

根组件 和 组件 一些问题
-new Vew()---->管理div----》根组件
    -自己再定义的全局,局部是组件
   	-组件有自己的html,css,js ---》数据,事件,。。。。。
    -在组件中,this 代指当前组件
    -父子组件的data是无法共享的
    -data是1个函数,需要有返回值(return)

2.组件通信之父传子

我们本意是想定义一个组件,里面声明一个name,在全局声明一个age,用组件在页面显示name和age,但是却只能拿到数据name,无法拿到age,因为父子之间数据不共享。我们需要通过自定义自定义属性方式实现数据的子传父:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
  <h1>div标签</h1>
  <child></child>
</div>
<script>
  var child = {
        template: `
          <div>
          <h2>姓名:{{ name }}</h2>
          <h2>年龄:{{ age }}</h2>
          </div>
        `,
        data() {
            return {
                name: 'max'
            }
        }  // 子标签的数据
    }
    var vm = new Vue({
      el:'#app',
      data:{
        age:18
      },
      components:{
        child
      }
    })
</script>

<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
  <h1>div标签</h1>
  <child :myage="age"></child>  <!--在child标签中拿到age,并且赋值给变量myage(这个变量不能用驼峰体)-->
</div>
<script>
  var child = {
        template: `
          <div>
          <h2>姓名:{{ name }}</h2>
          <h2>年龄:{{ myage }}</h2>  <!--用声明过的变量名来拿到div标签中的数据-->
          </div>
        `,
        data() {
            return {
                name: 'max'
            }
        },  // 子标签的数据
        props:['myage']  // 在组件中用关键字props注册刚才声明的变量名,
    }
    var vm = new Vue({
      el:'#app',
      data:{
        age:18
      },
      components:{
        child
      }
    })
</script>

"""
<child age="age"></child>  在页面上会显示age:age,传的是字符串
<child age="19"></child>  不加:相当于传了固定的值,是一个字符串,和上面由于 
<child :age="19"></child> 加了age显示在页面上的是19,但是加:是一个数字,并且加:可以写简单的表达式
"""
如果我们想控制父传子的数据类型,可以将props写成一个字典,键是接收到的数据,值是数据类型。如果接收到的数据类型和控制的不一样,也可以正常在前端页面显示,但是会有提示:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
  <h1>div标签</h1>
  <child :myage="age"></child>  <
</div>
<script>
  var child = {
        template: `
          <div>
          <h2>姓名:{{ name }}</h2>
          <h2>年龄:{{ myage }}</h2>  
          </div>
        `,
        data() {
            return {
                name: 'max'
            }
        },  // 子标签的数据
        props: {myage: Number}  // 接收类型为数值类型
    }
    var vm = new Vue({
      el:'#app',
      data:{
        age:'18'  // 父标签传递给子组件的是一个字符串
      },
      components:{
        child  // child是一个局部组件
      }
    })
</script>

3.组件通信之子传父

父组件也无法直接拿到字组件中的内容,需要通过自定义事件来拿到。数据子传父需要借助$emit,该方法可以触发子组件中的方法
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    <h2>父组件中的myText:{{myText}}</h2>  <!--1.在父组件中定义好要接收的myText-->
    <hr>
    <child @myevent="handEvent"></child>  <!--5.编辑触发事件,该事件将子组件的值赋值给父组件。触发该事件的方法写在子组件中,该事件绑定的函数写在父组件methods中-->
  </div>
</body>

<script>
  var child = {
    template:`
      <div>
        <h2>子组件中的myText:<input type="text" v-model="myText"></h2>
        <button @click="handSend">点我将子组件数据传递给父组件</button>  <!--2.定义好子组件,在子组件button中加入点击事件,该事件绑定的函数不需要传形参-->
      </div>
    `,
    data(){
      return {
        myText: ''
      }},
    methods:{
      handSend(){
        this.$emit('myevent',this.myText)  // 3.点击事件绑定$emit,$emit绑定会触发的事件,第二个参数是要传递给父组件的参数
      }
    }
  }
  var vm = new Vue({
    el:'#app',
    data:{
      myText:''
    },
    methods:{
      handEvent(myText){
        this.myText=myText  // 6.将子组件中的myText值赋值给父组件中的myText,在通过插值语法传递到前段页面
      }
    },
    components:{
      child  // 4.app标签内加入child 子组件
    }
  })
</script>

4.ref属性

1.ref属性对的作用:拿到原生的html标签。
定义两个标签,都绑上ref属性。打印$refs属性,发现是一个对象,键是ref的值,值是标签名称。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    我是input标签<input type="text" ref="myinput">
    <div ref="mydiv">我是div标签</div>
    <button @click="handClick">点击</button>
  </div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{

    },
    methods:{
      handClick(){
        console.log(this.$refs)
      }
    }
  })
</script>

2.属性放在组件上,拿到的是组件对象,可以使用组件对象的属性和方法。两个标签和一个child组件都绑定了ref值:
<body>
  <div id="app">
    我是input标签<input type="text" ref="myinput" v-model="name">
    <div ref="mydiv">我是div标签</div>
    <button @click="handClick">点击</button>
    <child ref="mychild"></child>
  </div>
</body>
<script>
  var child = {
    template:`
    <div>
    <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
  </div>
    `,
    data(){
      return {
        name:'max',
        age:18
      }
    },
    methods: {
      handClick() {
        alert(this.name)
      }
    }
  }

  var vm = new Vue({
    el:'#app',
    data:{
      name:''
    },
    methods:{
      handClick(){
        console.log(this.$refs)
        // console.log(this.$refs.mychild)  拿到的就是组件对象
      }
    },
    components:{
      child
    }
  })
</script>

在父标签可以通过ref属性拿到子标签中的值,此后就不需要关注是子传父还是父传子,而且还可以
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    输入您的姓名<input type="text" ref="myinput" v-model="name">
    <div ref="mydiv">我是div标签</div>
    <button @click="handClick">点击</button>
    <child ref="mychild"></child>
</div>
</body>
<script>
    var child = {
        template: `
          <div>
          <h2>姓名:{{ name }}</h2>
          <h2>年龄:{{ age }}</h2>
          </div>
        `,
        data() {
            return {
                name: 'max',
                age: 18
            }
        }
    }

    var vm = new Vue({
        el: '#app',
        data: {
            name: ''
        },
        methods: {
            handClick() {
                this.name = this.$refs.mychild.name
            }  // this.$refs.mychild是组件对象,拿到子组件对象之后就可以点到子组件的属性和方法
        },
        components: {
            child
        }
    })
</script>

利用ref属性还可以拿到子标签中的方法:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="handClick">父标签按钮</button>
        <child ref="mychild"></child>
    </div>
</div>
</body>
<script>
    var child = {
        template: `
          <div>
          <button @click="handClick">子标签按钮</button>
          </div>
        `,
        data() {
            return {
                name: 'max',
                age: 18
            }
        },
        methods: {
            handClick(){
                alert('我是子标签中的handClick方法')
            }
        }
    }

    var vm = new Vue({
        el: '#app',
        data: {
            name: ''
        },
        methods: {
            handClick() {
                this.$refs.mychild.handClick()  // 将父标签的点击事件绑定为触发子标签handClick()方法
            }
        },
        components: {
            child
        }
    })
</script>

5.动态组件

需求:现需要搭建一个页面,有三个选择框:首页、商品订单、结算页面,每点击一个小标题跳到该页面(用字来模拟):
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <span @click="handClick('home')">首页</span>| <span @click="handClick('order')">商品订单</span>| <span
        @click="handClick('buy')">结算页面</span>
    <home v-if="type=='home'"></home>
    <order v-else-if="type=='order'"></order>
    <buy v-else></buy>  <!--v-if判断来决定显示哪个组件-->
</div>
</body>
<script>
    var home = {
        template: `
        <h1>
            <div>首页</div>
        </h1>
        `
    }

    var order = {
        template: `
        <h1>
            <div>订单页面</div>
        </h1>
        `
    }

    var buy = {
        template: `
        <h1>
            <div>结算页面</div>
        </h1>
        `
    }


    var vm = new Vue({
        el: '#app',
        data: {
            type: 'home'
        },
        methods: {
            handClick(type) {
                this.type = type
                console.log(this.type)
            }
        },
        components: {
            home,
            order,
            buy
        }
    })
</script>

用动态组件来写可以减少代码,动态组件每种方式和每个组件匹配得到原理是:component标签参数'who'需要和组件名称保持一致,也就是点击事件的handClick参数需要和组件名称保持一致:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <span @click="handClick('home')">首页</span>| <span @click="handClick('order')">商品订单</span>| <span
        @click="handClick('buy')">结算页面</span>
    <component :is="who"></component>
</div>
</body>
<script>
    var home = {
        template: `
        <h1>
            <div>首页</div>
        </h1>
        `
    }

    var order = {
        template: `
        <h1>
            <div>订单页面</div>
        </h1>
        `
    }

    var buy = {
        template: `
        <h1>
            <div>结算页面</div>
        </h1>
        `
    }


    var vm = new Vue({
        el: '#app',
        data: {
            who: 'home'
        },
        methods: {
            handClick(type) {
                this.who = type
                console.log(this.who)
            }
        },
        components: {
            home,
            order,
            buy
        }
    })
</script>

6. keep-alive保持组件不销毁

在每个组件上设置一个input输入框,但是当我们跳转到另一个组件再回去时,input输入框内的内容会被清空,在component组件上套上keep-alive组件,就可以保持input输入框不会被清除掉。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <span @click="handClick('home')">首页</span>| <span @click="handClick('order')">商品订单</span>| <span
        @click="handClick('buy')">结算页面</span>
    <keep-alive>
        <component :is="who"></component>
    </keep-alive>
</div>
</body>
<script>
    var home = {
        template: `
        <h1>
            <div>首页</div>
            搜索商品:<input type="text">
        </h1>
        `
    }

    var order = {
        template: `
        <h1>
            <div>订单页面</div>
            搜索商品:<input type="text">
        </h1>
        `
    }

    var buy = {
        template: `
        <div>
            <h1>
                <div>结算页面</div>
            </h1>
            搜索商品:<input type="text">
        </div>
        `
    }


    var vm = new Vue({
        el: '#app',
        data: {
            who: 'home'
        },
        methods: {
            handClick(type) {
                this.who = type
            }
        },
        components: {
            home,
            order,
            buy
        }
    })
</script>
"""
报错提示:outside root element will be ignored.
这个代码表示我们在父组件或者子组件中都要用一个大的标签(div或者其他任意都可以)包起来,否则会报错:
"""

7.插槽

7.1 匿名插槽

1.匿名插槽就是将标签<slot></slot>插在组件中后期可能扩展内容的地方,在body标签中直接在组件名标签中插入内容即可:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
      <home>
        <h2>
          通过插槽插入的数据
        </h2>
      </home>
  </div>
</body>
<script>
  var home = {
    template:`
       <div>
        <h1>home页面</h1>
        <slot></slot>
        <h1>home结束了</h1>
      </div>
   `
  }
  var vm = new Vue({
    el:'#app',
    data:{},
    components:{
      home
    }
  })
</script>
插入前后对比:

7.2 匿名插槽

给每个插槽加入name属性,插入数据时直接在标签中插入slot="slot名"来指定插入位置:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
      <home>
        <div slot="s2">我是s2插槽得到内容</div>
        <div slot="s1">我是s1插槽得到内容</div>
      </home>
  </div>
</body>
<script>
  var home = {
    template:`
       <div>
        <h1>home页面</h1>
        <slot name="s1"></slot>
        <h1>home结束了</h1>
        <slot name="s2"></slot>
      </div>
   `
  }
  var vm = new Vue({
    el:'#app',
    data:{},
    components:{
      home
    }
  })
</script>

8.计算属性

8.1计算属性基本使用

需求:建立一个将输入内容首字母大写输入框,再建立一个数字输入框,我们在输入字符的时候会一直执行getUpper()函数,因为会随时监测字符的编号。但是当我们不输入字符,只输入数字时,发现console.log('getUpper()执行了')也在一直执行,说明getUpper()只要页面上任何一个地方刷新,都会重新执行:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    字符输入框<input type="text" v-model="myText">{{getUpper()}}
    数字输入框<input type="number" v-model="myNum">
  </div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      myText:'',
      myNum:''
    },
    methods:{
      getUpper(){
        console.log('getUpper()执行了')
        return this.myText.slice(0,1).toUpperCase()+this.myText.slice(1)
      }
    }
  })
</script>

为了效率起见,我们需要与之无关的函数不再执行,也就是字符框不输入内容时,getUpper()函数不再执行。因此我们再建立一个函数,返回值和getUpper()一样,但是这个函数写在computed内,调用该函数不需要加括号,当成属性用,并且要有返回值。可以看出与之无关的页面在刷新时,newText()函数不再执行:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
  <div id="app">
    字符输入框<input type="text" v-model="myText">{{newText}}
    数字输入框<input type="number" v-model="myNum">
  </div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      myText:'',
      myNum:''
    },
    methods:{
      getUpper(){
        console.log('getUpper()执行了')
        return this.myText.slice(0,1).toUpperCase()+this.myText.slice(1)
      }
    },
    computed:{
      newText(){
        console.log('getUpper()执行了')
        return this.myText.slice(0,1).toUpperCase()+this.myText.slice(1)
      }
    }
  })
</script>

8.2 改良版过滤案例

<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="d1">
    <p>请输入您要查询的单词:<input type="text" v-model="text"></p>
    <ul>
        <li v-for="item in newdataList">{{item}}</li>
    </ul>

</div>
</body>
<script>
    var vm = new Vue({
        el: '#d1',
        data:{
            text:'',
            dataList:['accustomed','suddenly','altogether','arrange','knowledge'],
        },
        computed:{
                newdataList(){
                    return this.dataList.filter(
                        item=>item.indexOf(this.text)>=0
                    )  // 将newdataList包装成一个属性,可以对其进行for循环,与之无关的页面局部刷新也不会使其刷新
                }
            }
    })
</script>

9.监听属性

当我们检测data中的某个值是否变化时,我们可以用一个watch()方法,该方法和methods平级,里面的函数名必须和data中的数据保持一致,当该数据发生变化时,就会触发watch()中的方法:
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <span @click="handClick('python')">python</span>| <span @click="handClick('linux')">linux</span>
    <component :is="who"></component>
</div>
<script>
    var python = {
        template: `
        <h1>
            <div>python</div>
        </h1>
        `
    }

    var linux = {
        template: `
        <h1>
            <div>linux</div>
        </h1>
        `
    }

    var vm = new Vue({
        el: '#app',
        data: {
            who: 0
        },
        methods: {
            handClick(type) {
                this.who = type
            }
        },
        components:{
            python,
            linux
        },
        watch:{
            who(){
                console.log('who变了')
            }
        }
    })
</script>
</body>

标签:vue,name,标签,var,template,组件,data,属性
From: https://www.cnblogs.com/ERROR404Notfound/p/17131660.html

相关文章

  • vue5
    今日内容概要组件的补充知识组件间通信之父传子ref属性动态组件插槽计算属性监听属性node环境搭建今日内容详细组件的补充知识newVue()对象后管理的标签叫......
  • Vue组件
     一、组件化开发介绍1.组件是什么?有什么用?组件就是:扩展HTML元素,封装可重用的代码,目的是复用例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html组件把js,cs......
  • 组件,组件间通信之父传子,组件间通信之子传父,ref属性,动态组件,插槽, 计算属性,监听属性, nod
    组件,组件间通信之父传子,组件间通信之子传父,ref属性,动态组件,插槽,计算属性,监听属性,node环境搭建组件<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8......
  • Vue急速入门-4
    组件其他根组件和组件的一些问题归总: 1.newVue()el:'xx'管理的Div就算根组件 2.父子组件的数据是无法共享的 3.组件有自己的html,css,js 4.在组件中,this代指当......
  • vue
    今日内容1.组件其它2.组件间通信之父传子3.组件间通信之子传父4.ref属性5.动态组件6.插槽7.计算属性8.监听属性9.node环境搭建1.组件其它根组件和组件一些问......
  • Kafka的注解KafkaListener,属性:containerFactory
     kafka的2个topic,如果2个 ConsumerConfig配置不一样。@KafkaListener(id="${groupId}",topics={"TOPIC"},containerFactory="DefinekafkaListenerContainerFacto......
  • Vue生命周期钩子
     一:生命周期图官网原图我理解的图二、生命周期钩子函数描述beforeCreate创建Vue实例之前调用created创建Vue实例成功后调用(可以在此处发送异步请求后......
  • VUE组件相关知识
    目录VUE组件/组件数据传递组件间数据传递父传子组件间数据传递子传父更方便的父子组件数据-ref(推荐)基础方法实现导航栏动态组件实现导航/和keep_alive方法keep_alive方......
  • vue 购物车案例,v-model进阶,与后端交互,vue生命周期,vue组件
    昨日内容回顾#1v-for可以循环的类型#2js的循环方式-基于索引的循环(i=0;i<10;i++)-in循环出来的是索引-of基于迭代的,循环出来就是值-数组.......
  • Vue对象常用属性
    Vue对象常用属性数据属性data数据属性的基本用法newVue({data:{'带引号的键':值,url:"www.baidu.com"//带引号的键}})在Vue实例中,我......