• Vue 组件实战


    Vue 组件

    Vue 生命周期钩子

    axios实现数据请求

    <!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>
    
    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()
    

    image


    计算属性

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

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

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

    案例一:首字母大写#

    <!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不相关

    案例二:过滤案例#

    <!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>
    

    计算属性2



    监听属性

    watch来设置监听属性,当mytext发生变化,就会执行和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">
    
        <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内使用

    <!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范围内

    <!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自定义属性来实现,比如如下例子:

    <!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('自定义事件',参数)来实现

    <!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进行操作设置等,如下示例:

    <!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属性1

    组件使用ref属性#

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

    <!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>
    
    

    ref属性2

    事件总线(不常用)

    <!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标签实现组件不销毁,保留原来输入的内容

    <!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>
    

    动态组件

  • 相关阅读:
    MATLAB与Excel的数据交互
    2021年全球企业家论坛暨区块链高峰论坛
    HTTP协议的请求协议和响应协议的组成,HTTP常见的状态信息
    【会议征稿通知】第三届密码学、网络安全和通信技术国际会议(CNSCT 2024)
    前端面经 在地址栏输入URL,到页面呈现,中间会发生
    论文笔记:多标签学习——BP-MLL算法
    聊聊DevOps制品管理-不止是存储制品这么简单
    云扩RPA携手中联教育引领财务机器人教学创新
    动态规划--完全背包问题详解2
    hive安装部署
  • 原文地址:https://www.cnblogs.com/48xz/p/16156543.html