前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue 组件实战

Vue 组件实战

作者头像
HammerZe
发布2022-05-09 18:48:42
8870
发布2022-05-09 18:48:42
举报
文章被收录于专栏:Hammer随笔

目录

Vue 组件

axios实现数据请求

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

</head>
<body>
<div id="app">
    <ul>
        <li v-for="film in films_list">
            <p>电影名字是:{{film.name}}</p>
            <img :src="film.poster" alt="" width="100px" height="150px">
            <p>电影介绍:{{film.synopsis}}</p>
        </li>
    </ul>

</div>

</body>
<script>

    var vm = new Vue({
        el: '#app',
        data: {
            films_list:[]
        },
        created() {
            axios.get('http://127.0.0.1:5000/films').then(res => {
                console.log(res.data)
                this.films_list=res.data.data.films
            })

        }
    })
</script>
</html>
代码语言:javascript
复制
from flask import Flask,make_response,jsonify

app=Flask(__name__)
@app.route('/films')
def films():
    import json
    with open('./movie.json','r',encoding='utf-8') as f:
        res=json.load(f)
    obj = make_response(jsonify(res))
    obj.headers['Access-Control-Allow-Origin']='*'
    return obj

if __name__ == '__main__':
    app.run()

计算属性

我们可以通过计算属性computed来缓存计算,什么意思呢?

在Vue中我们可以使用插值来展示数据,插值的普通函数,只要页面一刷新,函数就会重新运算,不管和函数有关没关的值都会变,函数也会重新计算,导致运行效率降低;

那么我们可以将自定义函数写在computed中来控制,把函数当成属性来用,调用不需要加括号,只有这个函数使用的属性(变量)发生变化,函数才重新运算,这样做可以减轻压力,减少资源浪费

案例一:首字母大写

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <div style="font-size: 20px">
        输入内容:<input type="text" v-model="mytext"> ----》 {{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}}
        <br><br>
        <p>函数绑定(会刷新页面,也不推荐):<input type="text" :value="getName()"></p>
        <p>计算属性(推荐):<input type="text" :value="getName1"></p>
    </div>

    <hr>
    <div style="font-size: 20px">
         <p>输入内容:<input type="text" v-model="mytext1"> -----》{{mytext1}}</p>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytext: '',
            mytext1:''
        },
        methods:{
            getName(){
                console.log('函数方式,我执行了')
                return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
            }
        },
        //计算属性
        computed:{
            getName1(){
                console.log('计算属性,我执行了')
                return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
            }

        }
    })
</script>
</html>

我们可以发现只有和属性相关的才会打印,如果下面输入内容只是打印了普通函数,就算函数内和mytext1不相关

案例二:过滤案例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤案例</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <p><input type="text" v-model="myText"  placeholder="请输入要筛选的内容:"></p>
    <ul>
        <li v-for="data in newList">{{data}}</li>
    </ul>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },

        computed:{

            newList(){
                var _this = this
                console.log('执行了',_this)
                 var datalist2 = _this.dataList.filter(function(item){
                    console.log(_this)
                     return item.indexOf(_this.myText) > -1

                })
                return datalist2

            }
        }
    })
</script>
</html>

监听属性

watch来设置监听属性,当mytext发生变化,就会执行和mytext绑定的函数方法

代码语言:javascript
复制
<!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}}


</div>

</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytext: '',
        },
        watch: {
            // 只要mytext发生变化,就会执行该函数
            mytext: function () {
                console.log('我变化了,执行')

            }
        }


    })
</script>
</html>

局部组件

写在components里的是局部组件,位置被限制,只能再局部使用

比如如下例子中,Top组件只能在只能再id为app的标签(div)内使用, Top组件内如果想再定义子组件,只能在该组件内的template中的div内使用

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <Top></Top>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <Bottom></Bottom>
</div>

</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        // 定义再这里面的叫局部组件,只能再局部使用,只能再id为app的标签内使用
        components: {
            'Top': {
                //写在一个div里
                template: `
                    <div>
                        <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
                        <hr>
                        <button @click="handleC">点我看美女</button>
                    </div>
                `,
                //data是函数,可以设置返回值
                data() {
                    return {
                        name: "我是头部"
                    }
                },
                methods: {
                    handleC() {
                        alert('美女')
                    }
                },
            },
            'Bottom': {
                template: `
                    <div>
                        <hr>
                        <h1 style="background: green;font-size: 60px;text-align: center">{{name}}</h1>

                    </div>
                `,
                data() {
                    return {
                        name: "我是尾部"
                    }
                },

            },

        },


    })
</script>
</html>

全局组件

任意位置都可以使用但是也得是在vue实例托管的div范围内

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <top></top>


</div>

</body>
<script>
    // 定义全局组件,任意位置都可以用,局部内也可以使用
    Vue.component('top', {
            template: `
                <div>
                    <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
                    <hr>
                    <button @click="handleC">点我看美女</button>
                </div>
            `,
            data() {
                return {
                    name: "我是头部"
                }
            },
            methods: {
                handleC() {
                    alert('美女')
                }
            },

        },)

    var vm = new Vue({
        el: '#app',
    })
</script>
</html>

组件通信之父传子

组件间data数据不同享,数据传递,如果我们想从父组件传递到子组件数据通过props自定义属性来实现,比如如下例子:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    子组件显示:<top :value="handleName"></top>
    <hr>
    父组件输入内容:<input type="text" v-model="handleName">

</div>

</body>
<script>

    Vue.component('top', {
        template: ` <div>
                    <h1 style="background: tomato;font-size: 30px;text-align: center">{{value}}</h1>
                    </div>             `,
        // 必须叫props,数组内放自定义属性的名字
        props:{
            value: String,  // key是自定义属性名,value是类型名,如果是别的类型就报错
        },
        //props也可以写成数组的形式,不带验证功能
        // props:['value',]
    })
    var vm = new Vue({
        el: '#app',
        data: {
            handleName: ''
        }
    })
</script>
</html>

组件通信之子传父

ps:Vue内置的对象都以$xx出现

我们可以通过自定义事件来实现子组件向父组件传递数据,在子组件中使用$emit('自定义事件',参数)来实现

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<top @myevent="handleRecv"></top>
    <hr>
  <h1 style="background: green;font-size: 60px;text-align: center">父组件</h1>
 <p>接收子组件发送的数据:{{childText}}</p>
</div>

</body>
<script>

    Vue.component('top', {
        template: ` <div>
                        <h1 style="background: tomato;font-size: 60px;text-align: center">{{myheader}}</h1>
                        <p>子组件输入内容:<input type="text" v-model="text"></p>
                        <p><button class="btn-success"  @click="handleSend">向父组件发送数据</button></p>
                    </div>             `,
        data(){
            return {
                myheader:'子组件',
                text:''
            }
        },
        methods:{
            handleSend(){
                //myevent是自定义事件,代表将子组件的text交给myevent事件处理
                this.$emit('myevent',this.text)
            }
        }

    })
    var vm = new Vue({
        el: '#app',
        data: {
            //接收子组件的数据
            childText:''
        },
        methods: {
            handleRecv(data){
                // 接收参数,赋值给父组件的childText
                this.childText=data
            }
        }
    })
</script>
</html>

ref属性(组件间通信)

普通标签使用

普通标签使用ref属性,通过$refs获取到的就是ref属性所在的标签,获取到的是一个对象,如果多个标签写了ref属性,那么就将所有带ref属性的标签弄到一个对象中,可以对html进行操作设置等,如下示例:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1 style="align-content: center">普通标签使用ref</h1>
    <p><input type="text" ref="myinput"></p>
    <p><img src="" height="100px" width="100px" ref="myimg"></p>
    <p><button @click="handleC">点我</button>
</p>
</div>
</body>
<script>

    let vm = new Vue({
        el: '#app',
        data: {
             text:''
        },
        methods: {
            handleC(){
                console.log('我被点了')
                console.log(this.$refs)  // 是所有标签写了ref属性的对象{myinput:真正的标签,myimg:真正的标签}
                console.log(this.$refs.myinput.value)
                //设置值
                this.$refs.myinput.value='HammerZe'
                //设置src属性,显示图片
                this.$refs.myimg.src='https://img0.baidu.com/it/u=3608430476,1945954109&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=494'
            }
        }
    })
</script>
</html>

组件使用ref属性

ref属性,如果放在组件上,就是当前组件对象

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 组件使用ref属性   -->
<top ref="top"></top>
<p>通信:<input type="text" v-model="text"></p>
<p>父组件按钮:<button @click="handleC">点我</button></p>
</p>
</div>
</body>
<script>
   Vue.component('top', {
        template: `
            <div>
                <h1>{{myheader}}</h1>
                <p>子组件按钮:<button @click="handleC">点我看美女</button></p>
                <hr>
            </div>
        `,
        data() {
            return {
                myheader: "头部",
            }
        },
        methods:{
            handleC(){
                alert("美女")
            }
        }



    },)
    let vm = new Vue({
        el: '#app',
        data: {
             text:''
        },
        methods: {
        //放在组件上
        handleC() {
             console.log(this.$refs.top) //VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
            /*子传父*/
            // 父组件拿子组件的值
            console.log(this.$refs.top.myheader)
            // this.text=this.$refs.top.myheader
            // 父组件调用子组件的方法
            this.$refs.top.handleC()

            /*父传子*/
            this.$refs.top.myheader=this.text
        }
        }
    })
</script>
</html>

事件总线(不常用)

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
    <child1></child1>
    <child2></child2>
</div>
</body>
<script>
    var bus=new Vue() //new一个vue的实例,就是中央事件总线
    Vue.component('child1', {
        template: `<div>
            <input type="text" ref="mytext">
            <button @click="handleClick">点我</button>
        </div>`,
        methods:{
            handleClick(){
                bus.$emit('suibian',this.$refs.mytext.value) //发布消息,名字跟订阅消息名一致
            }
        }
    })
    Vue.component('child2', {
        template: `<div>
                    <div>收到的消息 {{msg}}</div>
                    </div>`,
        data(){
            return {msg:''}
        },
        mounted(){
            //生命周期,当前组件dom创建完后悔执行
            console.log('当前组件dom创建完后悔执行')
            //订阅消息
            bus.$on('suibian',(item)=>{
                console.log('收到了',item)
                this.msg=item
            })
        }
    })
    var vm = new Vue({
        el: '#box',
        data: {},
        methods: {
            handleClick() {
                console.log(this)
                //this.$refs.mytext 获取到input控件,取出value值
                console.log(this.$refs.mytext.value)
                console.log(this.$refs.mychild.text)
                // this.$refs.mychild.add()
                this.$refs.mychild.add('传递参数')

            }
        }

    })
</script>
</html>

动态组件和keep-alive

动态组件:实现点击不同的连接显示不同的页面,实现跳转,使用component标签,用is属性绑定,指定哪个显示哪个

keep-alive:通过keep-alive标签实现组件不销毁,保留原来输入的内容

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<style>
    #menu {
        font-size: 18px;
        font-weight: bold;
    }

    #menu li {
        text-decoration: none; /*去掉前面的圆点*/
        list-style: none;
        float: left;
        margin-right: 20px;

    }

</style>
<body>
<div id="app">
    <ul id="menu">
        <li @click="changeC('index')">首页</li> &nbsp;
        <li @click="changeC('order')" >订单</li>
        <li @click="changeC('good')">商品</li>
    </ul>


    <keep-alive>
        <component :is='who'></component>
    </keep-alive>


</div>

</body>
<script>
    //三个组件
    Vue.component('index', {
        template: `
            <div style="overflow:hidden;">
                <h1>首页内容</h1>
            </div>
        `,
    },)
    //保留输入的订单信息
    Vue.component('order', {
        template: `
            <div>
                <h1>订单内容</h1>
                请输入要查询的订单:<input type="text">
            </div>
        `,
    },)
    Vue.component('good', {
        template: `
            <div>
                <h1>商品内容</h1>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {
            //默认显示index
            who: 'index'

        },
        methods: {
            changeC(data) {
                this.who = data
            }
        }

    })
</script>
</html>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Vue 组件
    • axios实现数据请求
      • 计算属性
        • 案例一:首字母大写
        • 案例二:过滤案例
      • 监听属性
        • 局部组件
          • 全局组件
            • 组件通信之父传子
              • 组件通信之子传父
                • ref属性(组件间通信)
                  • 普通标签使用
                  • 组件使用ref属性
                • 事件总线(不常用)
                  • 动态组件和keep-alive
                  相关产品与服务
                  事件总线
                  腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档