ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue---计算属性和监听属性,组件化开发之局部和全局组件和组件通信,ref属性,数据总线,动态组件和slot插槽

2022-06-29 20:34:46  阅读:125  来源: 互联网

标签:slot Vue name myText 组件 data 属性


计算属性和监听属性


计算属性

computed 对象写函数,函数就可以当属性使用。

计算属性只有在它的相关依赖发生改变时才会重新求值。

<!DOCTYPE html>
<html lang="en">
<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" >  {{myText.substr(0,1).toUpperCase()+myText.substr(1)}}
    <br>
    <input type="text" v-model="myText2" >  {{getname()}}  // 函数
    <br>
    <input type="text" v-model="myText3"> {{getName}}  // 计算属性
</div>
</body>
<script>
    var vm=new Vue({
        el:'#app',
        data:{
            myText:'',
            myText2:'',
            myText3:'',
        },
        methods:{
            getname(){
               return this.myText2.substr(0,1).toUpperCase()+this.myText2.substr(1)
            }
        },
        computed:{
            getName() {
                return this.myText3.substr(0,1).toUpperCase()+this.myText3.substr(1)
                // 返回什么,属性就得到什么
            }
        }
    })

</script>
</html>

监听属性

watch对象中写函数,函数名就是data中得变量名,只要这个变量发生变化,就会触发该函数的执行。

<!DOCTYPE html>
<html lang="en">
<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">  --->{{myText}}
    <hr>

</div>
</body>

<script>

    var vm = new Vue({
        el: '#app',
        data: {
            myText: '',
        },
        watch:{
            myText(val){
                console.log('执行了',val)
            }
        }
    })

</script>
</html>

组件化开发之局部和全局组件


组件是什么?有什么用

扩展 HTML 元素,封装可重用的代码,目的是复用。例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html。组件把js,css,html放到一起,有逻辑,有样式,有html。

定义全局组件

Vue.component('Child', {
        template: `
          <div>
          <button @click="handleClick" v-model="myText">点我看美女</button>
          </div>`,
        data() {
            return {
                myText: ''
            }
        },
        methods: {
            handleClick() {
                alert('美女')
            }
        }
    })

定义局部组件

写在Vue实例或者组件实例中。

 components:{
            zaoan:{
                template:`<div>
          <h1>我是局部组件</h1>
          <button @click="handleClick" >点我看美女</button>
          </div>`,
                methods: {
            handleClick(){
                alert("我是局部组件 看美女!")
            }
        },
            }
        }

注意

​ -1. 自定义组件需要有一个root element,一般包裹在一个div中

​ -2. 父子组件的data,methods是无法共享

​ -3. 组件可以有data,methods,computed....,但是data 必须是一个函数

组件间通信之父传子---自定义属性


第一步:在子组件上定义一个属性例如:myname=""

第二步:给属性添加一个变量,把变量存放在父组件data里,:myname="name"

第三步:在组件加上props:['添加的属性名',],然后就可以在子组件里调用属性了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    自定义属性:   myname
    <Child :myname="name"></Child>

</div>
</body>

<script>

    //全局组件
    Vue.component('Child', {
        template: `
          <div>
          <h1>我是一个组件--{{ myText }}--{{myname}}</h1>
          <button @click="handleClick">点我看美女</button>
          <br>
          <input type="text" v-model="myText">
          </div>`,
        data() {
            return {
                myText: '',
            }
        },
        methods: {
            handleClick() {
                alert('美女')
            }
        },
        props:['myname',]
    })


    // 局部组件只能在局部使用
    var vm = new Vue({
        el: '#app',
        data: {
            name:'lqz'
        },


    })

</script>
</html>

属性验证:

可以验证自定义的属性传入值的类型,如果类型对不上虽然还会显示,但报错了。

props: {
            'myname': String,
            myage: Number
        }

组件间通信之子传父(自定义事件)


第一步:在子组件里自定义一个事件,绑定一个函数,函数是写在父组件的methods里。eg:@myevent="handleEvent"

第二步:在子组件内部创建一个可以触发通信事件的函数,在函数体里写上触发自定义事件的方法,携带上要传递的信息。eg: this.$emit('myevent', this.myText)

第三步:把要传递的信息当参数传给父组件里的自定义事件对应的函数,然后执行需要的操作即可。eg:handleEvent(myText) { this.name=myText}。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>子组件中myText的数据是:{{name}}</h1>
    <hr>
    <Child @myevent="handleEvent"></Child>
</div>
</body>

<script>

    //全局组件
    Vue.component('Child', {
        template: `
          <div>
          <input type="text" v-model="myText">
          <button @click="handleClick">点我把数据传给父亲</button>
          <br>

          </div>`,
        data() {
            return {
                myText: '',
            }
        },
        methods: {
            handleClick() {
                // 触发自定义事件myevent,后面有几个参数,就传几个参数,这样就会执行myevent绑定的函数,handleEvent
                this.$emit('myevent', this.myText)
            }
        },
    })

    // 局部组件只能在局部使用
    var vm = new Vue({
        el: '#app',
        data: {
            name:''
        },
        methods: {
            handleEvent(myText) {
                this.name=myText
            }
        }


    })

</script>
</html>

ref属性


ref放在普通标签上,拿到的是原生节点,原生dom操作

ref放在组件上,拿到的是组件对象

​ -通过这种方式实现子传父(this.$refs.mychild.text)
​ -通过这种方式实现父传子(调用子组件方法传参数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

<!--    <input type="text" ref="pp">-->
    <p ref="pp">我是个p</p>
    <button @click="handleClick">点我执行函数</button>

    <hr>

    <Child ref="cc"></Child>

</div>
</body>

<script>
    Vue.component('Child',{
        template:`<div>
                    <h1>我是组件</h1>
                    名字:{{name}}
                    <br>
                    年龄:{{age}}
                </div>`,
        data(){
            return {
                name:'彭于晏',
                age:37
            }
        },
        methods:{
            handleClick(aaa){
                console.log(this.name,this.age)
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
        },
        methods:{
            handleClick(){
                console.log(this.$refs)
                // this.$refs['pp'].value='lqz is handsome'
                // this.$refs['pp'].innerText='xxxx'

                // alert(this.$refs['cc'].name)
                // alert(this.$refs['cc'].age)

                //调用子组件的方法
                this.$refs['cc'].handleClick('asdfasdfasdfasdf')
            }
        }


    })

</script>
</html>

数据总线


可以实现不同层级的不通的组件通信

用法:

// 1 定义一个数据总线----》本质就是一个vue对象
var bus = new Vue()  //new一个vue的实例,就是中央事件总线
// 2 定义两个全局组件
// 其中之1
handleClick() {
                // 触发被监听的事件,有值传值
                bus.$emit('suibian',this.myText)
            }
// 另一个
mounted(){
            // 等着,监听,如果谁触发我,我就执行
            bus.$on('suibian',(name)=>{
                this.myText=name
            })
        }

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <child1></child1>
    <hr>
    <child2></child2>


</div>
</body>
<script>

    // 1 定义一个数据总线----》本质就是一个vue对象
    var bus = new Vue()  //new一个vue的实例,就是中央事件总线
    // 2 定义两个全局组件
    Vue.component('child1', {
        template: `
          <div>
          <input type="text" v-model="myText">
          <button @click="handleClick">点我</button>
          </div>`,
        data() {
            return {
                myText: ''
            }
        },
        methods: {
            handleClick() {
                // 触发被监听的事件,有值传值
                bus.$emit('suibian',this.myText)
            }
        }
    })

    Vue.component('child2', {
        template: `
          <div>
          接受到的数据是:{{ myText }}
          </div>`,
        data() {
            return {
                myText: ''
            }
        },
        mounted(){
            // 等着,监听,如果谁触发我,我就执行
            bus.$on('suibian',(name)=>{
                this.myText=name
            })
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {},

    })

</script>
</html>

动态组件


通过component配合is属性,决定显示的组件是哪个

keep-alive 保证组件切换走后不被销毁

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <ul>
        <li @click="who='home'">首页</li>
        <li @click="who='goods'">商品</li>
        <li @click="who='order'">订单</li>
    </ul>
    <keep-alive>
        <component :is="who">

        </component>
    </keep-alive>

</div>
</body>
<script>

    Vue.component('home', {
        template: `
          <div>
          首页
          </div>`,
    })
    Vue.component('goods', {
        template: `
          <div>
          商品
          <input type="text">
          </div>`,
    })
    Vue.component('order', {
        template: `
          <div>
          订单
          </div>`,
    })


    var vm = new Vue({
        el: '#app',
        data: {
            who: 'home'
        },


    })

</script>
</html>

slot插槽


可以通过slot往组件里插内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<home>
    // 如果只是插单个伪装可以不用指定name 
    <div slot="a">我是div</div>
    <img src="https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg" alt="" slot="b">

</home>

</div>
</body>
<script>

    Vue.component('home', {
        template: `
          <div>
          <input type="text">
          <hr>
          <slot name="a"></slot>  
          navbar
          <slot name="b"></slot>
          <button>点我</button>

          </div>`,
    })


    var vm = new Vue({
        el: '#app',
        data: {
        },


    })

</script>
</html>

标签:slot,Vue,name,myText,组件,data,属性
来源: https://www.cnblogs.com/zaoan1207/p/16424822.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有