• VUE学习笔记--动态组件


    让多个组件使用同一个挂载点,并动态切换,这就是动态组件。通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动态组件。它的应用场景往往应用在路由控制或者 tab 切换中。
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8"/>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <button @click="change">切换页面</button>
        <component :is="currentView"></component>
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
                index:0,
                arr:[
                    {template:'<div>我是主页</div>'},
                    {template:'<div>我是提交页</div>'},
                    {template:'<div>我是存档页</div>'}
                ],
        },
            computed:{
                currentView(){
                    return this.arr[this.index];
                }
            },
            methods:{
                change(){
                    this.index = (++this.index)%3;
                }
            }
        })
    </script>
    </body>
    </html>
    component 标签中 is 属性决定了当前采用的子组件,:is 是 v-bind 的简写,绑定了父组 件中 data 的 currentView 属性。点击按钮时,会更改数组 arr 的索引值,同时也修改了子组 件的内容。
    keep-alive
    
    <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,以便提高提取效率。和 <transition> 相似,<keep-alive> 是一个抽象组件,它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8"/>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <button @click="change">切换页面</button>
        <keep-alive>
            <component :is="currentView"></component>
        </keep-alive>
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
                index:0,
                arr:[
                    {template:'<div>我是主页</div>'},
                    {template:'<div>我是提交页</div>'},
                    {template:'<div>我是存档页</div>'}
                ],
            },
            computed:{
                currentView(){
                    return this.arr[this.index];
                }
            },
            methods:{
                change(){
                    /*es6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。*/
                    let len = this.arr.length;
                    this.index = (++this.index)% len;
                }
            }
            })
    </script>
    </body>
    </html>
    activated 钩子函数
    
    Vue给组件提供了activated钩子函数,作用于动态组件切换或者静态组件初始化的过程中。activated是和template、data等属性平级的一个属性,形式是一个函数,函数里默认有一个参数,而这个参数是一个函数,执行这个函数时,才会切换组件,即可以延迟执行当前的组件。
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8"/>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <button @click='toShow'>点击显示子组件</button>
        <!----或者<component v-bind:is="which_to_show" keep-alive></component>也行----->
        <keep-alive>
            <component v-bind:is="which_to_show" ></component>
        </keep-alive>
    </div>
    <script>
        // 创建根实例
        var vm = new Vue({
            el: '#app',
            data: {
                which_to_show: "first"
            },
            methods: {
                toShow: function () {   //切换组件显示
                    var arr = ["first", "second", "third", ""];
                    var index = arr.indexOf(this.which_to_show);
                    if (index < 2) {
                        this.which_to_show = arr[index + 1];
                    } else {
                        this.which_to_show = arr[0];
                    }
                    console.log(this.$children);
                }
            },
            components: {
                first: { //第一个子组件
                    template: "<div>这里是子组件1</div>"
                },
                second: { //第二个子组件
                    template: "<div>这里是子组件2,这里是延迟后的内容:{{hello}}</div>",
                    data: function () {
                        return {
                            hello: ""
                        }
                    },
                    activated: function (done) { //执行这个参数时,才会切换组件
                        console.log('beixi')
                        var self = this;
                        var startTime = new Date().getTime(); // get the current time
                        //两秒后执行
                        while (new Date().getTime() < startTime + 2000){
                            self.hello='我是延迟后的内容';
                        }
                    }
                },
                third: { //第三个子组件
                    template: "<div>这里是子组件3</div>"
                }
            }
        });
    </script>
    </body>
    </html>
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8"/>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <button @click="change">切换页面</button>
        <keep-alive>
            <home v-if="index===0"></home>
            <posts v-else-if="index===1"></posts>
            <archive v-else></archive>
        </keep-alive>
    </div>
    <script>
        new Vue({
            el: '#app',
            components:{
                home:{template:'<div>我是主页</div>'},
                    posts:{template:'<div>我是提交页</div>'},
                        archive:{template:'<div>我是存档页</div>'},
                        },
            data:{
                index:0,
            },
            methods:{
                change(){
                    //  在data外面定义的属性和方法通过$options可以获取和调用
                    let len = Object.keys(this.$options.components).length;
                    this.index = (++this.index)%len;
                }
            }
                    })
    </script>
    </body>
    </html>
     异步组件
    在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从 服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个 工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染,代码如下:
    
    <div id="app">
            <async-example></async-example>
        </div>
        <script>
                Vue.component ( 'async-example ', function (resolve, reject){
                    setTimeout (function (){
                        //向resolve 回调传递组件定义
                    resolve ( {
                        template:  '<div>这是异步渲染的内容!</div>'
                    })
                },1000)
            })
            new vue ( {
                el : '#app'
            })
        </script>
    这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到 组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是 为了演示异步,如何获取组件取决于你自己。比如把组件配置成一个对象配置,通过 Ajax 来请求,然后调用 reslove 传入配置选项。
    在 Vue 中一般很少会用到直接操作 DOM,但不可避免有时候需要用到,这时我们可以 通过 ref 和$refs 来实现:
          ref: ref 被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件 的 $refs 对象上,如果是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,如果是 在子组件上,引用就指向组件的实例。 
     $refs:$refs 是一个对象,持有已注册过 ref 的所有的子组件。
    普通获取 DOM 的方式 
    先通过 getElementById 方法来获取,代码如下:
    
    <div id="app">
            <input type="button" value="获取h3的值"@click="getElement"><h3 id="myh3">我是h3</ h3>
        </div>
        <script>
            var vm=new vue ( {
                el : "#app" ,
                data : { } ,
                methods : {
                    getElement ( ) {
                        //通过getElementById方式获取DOM对象
                         console.log (document. getElementById ( "myh3" ) .innerHTML) ;
                    }
                }
            })
        </script>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <!--引入vue-->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <input type="button" value="获取h3的值" @click="getElement">
        <h3 id="myh3" ref="myh3">我是h3</h3>
        <hr>
        <login ref="mylogin"></login>
    </div>
    <script>
        var login = {
            template: "<h3>我是login子组件</h3>",
            data(){
            return {
                msg: "ok"
            }
        },
            methods:{
                show(){
                    console.log("show方法执行了...")
                }
            }
        }
        var vm=new Vue({
            el:"#app",
            data:{},
            methods:{
                getElement(){
                    //通过getElementById方式获取DOM对象
                    // console.log(this.$refs.myh3.innerHTML);
                    console.log(this.$refs.mylogin.msg);
                    this.$refs.mylogin.show();
                }
            },
         components:{
             login
         }
        })
    </script>
    </body>
    </html>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <!--引入vue-->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <!--引入bootstrap-->
        <link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
    </head>
    <body>
    <div id="app">
        <cmt-box @func="loadComments"></cmt-box>
        <ul class="list-group">
            <li class="list-group-item" v-for="item in list" :key="item.id">
                <span class="badge">评论人: {{ item.user }}</span>
                {{ item.content }}
            </li>
        </ul>
    </div>
    <template id="tmpl">
        <div>
            <div class="form-group">
                <label>评论人:</label>
                <input type="text" class="form-control" v-model="user">
            </div>
            <div class="form-group">
                <label>评论内容:</label>
                <textarea class="form-control" v-model="content"></textarea>
            </div>
            <div class="form-group">
                <input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
            </div>
        </div>
    </template>
    <script>
        var commentBox = {
            data() {
                return {
                    user: '',
                    content: ''
            }
            },
            template: '#tmpl',
            methods: {
                postComment() { // 发表评论的方法
                    var comment = { id: Date.now(), user: this.user, content: this.content }
                    // 从 localStorage 中获取所有的评论
                    var list = JSON.parse(localStorage.getItem('cmts') || '[]')
                    list.unshift(comment)
                    // 重新保存最新的 评论数据
                    localStorage.setItem('cmts', JSON.stringify(list))
                    this.user = this.content = ''
                    this.$emit('func')
                }
            }
        }
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                list: [
                    { id: Date.now(), user: 'beixi', content: '这是我的网名' },
                    { id: Date.now(), user: 'jzj', content: '这是我的真名' },
                    { id: Date.now(), user: '贝西奇谈', content: '有任何问题可以关注公众号' }
            ]
            },
            beforeCreate(){ /* 注意:这里不能调用 loadComments 方法,因为在执行这个钩子函数的时候,data 和 methods 都还没有被初始化好*/
        },
            created(){
            this.loadComments()
        },
            methods: {
                loadComments() { // 从本地的 localStorage 中,加载评论列表
                    var list = JSON.parse(localStorage.getItem('cmts') || '[]')
                    this.list = list
                }
            },
            components: {
                'cmt-box': commentBox
            }
        });
    </script>
    </body>
    </html>

  • 相关阅读:
    伪静态
    query 文件提交 +php后台入库
    PHP实现URL长连接转短连接方法
    通过经纬度获取所属城市信息
    PHP 学习之路1
    Linux云服务器安装tomcat
    linux下svn服务器搭建步骤
    HttpServletrequest 与HttpServletResponse总结
    HTML5基础
    Ajax相关总结
  • 原文地址:https://www.cnblogs.com/tszr/p/15415986.html
Copyright © 2020-2023  润新知