zoukankan      html  css  js  c++  java
  • Vue 路由组件

    组件数据局部化处理

    1. 不管页面组件还是小组件,都可能会被多次复用
    2. 复用组件的原因,其实就是复用组件的 页面结构、页面样式、页面逻辑
    3. 但是页面上的数据需要区分(被复用的两个组件数据多少是有区别的),所以组件的数据要做局部化处理
    4. 借助函数可以产生局部作用域的特点,为每一次复用组件产生一个独立的作用域

    语法:

    data () {
    	return {
    		// 数据们
    	}
    }
    

    子组件

    <template>
        <div class="beat" @click="count += 1">
            {{ count }}下
        </div>
    </template>
    
    <script>
        export default {
            name: "Beat",
            // 不管是页面组件还是小组件,都可能被复用,页面结构与样式都可以采用一套,但是数据一定要相互独立
            data () {
                return {
                    count: 0
                }
            }
        }
    </script>
    
    <style scoped>
        .beat {
             100px;
            height: 100px;
            background-color: orange;
            text-align: center;
            line-height: 100px;
            border-radius: 50%;
        }
    </style>
    

    父组件

    <template>
        <div class="home">
            <Beat/>
            <Beat/>
        </div>
    </template>
    
    <script>
        import Beat from '@/components/Beat'
        export default {
            components: {
                Beat,
            }
        }
    </script>
    


    路由逻辑跳转

    1. 很多时候,我们需要通过普通按钮的逻辑,或是直接在某些逻辑中完成页面的跳转
    2. 可以通过在逻辑中用 this.$router.push() 来完成前往目标页,两种语法如下
      • this.$router.push('路劲')
      • this.$router.push({name: '路由名'})
    3. 在做移动端项目时,没有像浏览器那样的前进后台键,页可以用 this.$router.go() 来完成前进后退,语法如下
      • 前进后退:this.$router.go(正负整数),正式代表前进,负数代表后台,数值就是步长

    案例:

    <template>
        <div class="home">
            <Nav/>
            <h1>主页</h1>
            <button @click="goPage('/first')">前往第一页</button>
            |
            <button @click="goPage('/second')">前往第二页</button>
            |
            <button @click="goBack(-1)">后退一页</button>
            |
            <button @click="goBack(-2)">后退二页</button>
            |
            <button @click="goBack(1)">前进一页</button>
        </div>
    </template>
    
    <script>
        import Nav from '@/components/Nav'
    
        export default {
            methods: {
                goPage(path) {
                    // 可以通过 this.$router 完成逻辑跳转
                    this.$router.push();
                },
                goBack(num) {
                    // 一般在移动端项目上运用
                    this.$router.go(num);  
                }
            },
            components: {
                Nav,
            }
        }
    </script>
    

    组件传参

    父传子

    1. 在子组件内通过 props 设置组件的自定义属性

      1. props: ['abc', 'goods']
        
    2. 在父组件渲染子组件时对自定义属性赋值即可

      1. <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods"/>
        

    子组件

    <template>
        <div class="goods-box">
            <img :src="goods.img" alt="">
            <p>{{ goods.title }}</p>
        </div>
    </template>
    
    <script>
        export default {
            name: "GoodsBox",
            // 在组件内部通过props定义组件的自定义属性
            props: ['abc', 'goods'],
        }
    </script>
    
    <style scoped>
        .goods-box {
             260px;
            height: 300px;
            border: 1px solid black;
            border-radius: 5px;
            margin: 20px;
            float: left;
            overflow: hidden;
            text-align: center;
        }
        img {
             260px;
            height: 260px;
        }
    </style>
    

    父组件

    <template>
        <div class="goods">
            <div class="main">
                <!-- 在使用子组件时对自定义属性赋值即可 -->
                <GoodsBox v-for="goods in goods_list" :key="goods" :goods="goods" />
            </div>
        </div>
    </template>
    <script>
        import GoodsBox from "../components/GoodsBox";
    
        let goods_list = [
            {
                img: require('@/assets/img/001.jpg'),
                title: '小猫',
            },
            {
                img: require('@/assets/img/002.jpg'),
                title: '小猫儿',
            },
            {
                img: require('@/assets/img/003.jpg'),
                title: '小狗',
            },
            {
                img: require('@/assets/img/004.jpg'),
                title: '小狗儿',
            },
        ];
    
        export default {
            name: "Goods",
            data () {
                return {
                    goods_list,
                }
            },
            components: {
                GoodsBox,
            },
        }
    </script>
    
    
    {
                img: require('@/assets/img/1.jpeg'),
                title: '1号',
            },
            {
                img: require('@/assets/img/2.jpeg'),
                title: '2号',
            },
            {
                img: require('@/assets/img/3.jpg'),
                title: '3号',
            },
            {
                img: require('@/assets/img/4.jpeg'),
                title: '4号',
            },
    

    子传父

    前提:子组件是被父组件渲染的,所以子组件渲染要晚于父组件

    1. 子组件一定要满足一个条件,才能对父组件进行传参(某个时间节点 === 某个被激活的方法)

      1. 子组件刚刚加载成功,给父组件传参
      2. 子组件某一个按钮被点击的时刻,给父组件传参 iii)子组件要被销毁了,给父组件传参
    2. 在子组件满足条件激活子组件的方法中,对父组件发生一个通知,并将数据携带处理(自定义组件事件)

      1. <div class="goods-box" @click="boxClick"></div>
            methods: {
                boxClick () { this.$emit('receiveData', this.goods.title, '第二个数据', '第三个数据') }
            }
        
    3. 在父组件渲染子组件时,为自定义事件绑定方法

      1. <GoodsBox @receiveData="recFn"/>
        
    4. 在父组件实现绑定方法时,就可以拿到子组件传参的内容(接收到了通知并在父组件中相应)

      1. recFn(title, data2, data3) {
                console.log('接收到了' + title);
            }
        

    组件标签不能绑定系统定义的事件,没有意义,子组件的事件都是在自己内部完成

    子组件

    <template>
        <div class="goods-box" @click="boxClick">
            <img :src="goods.img" alt="">
            <p>{{ goods.title }}</p>
        </div>
    </template>
    
    <script>
        export default {
            props: ['abc', 'goods'],
            methods: {
                boxClick () {
                    // 通知父级 - 自定义组件的事件
                    this.$emit('receiveData', this.goods.title)
                }
            }
        }
    </script>
    

    父组件

    <template>
        <div class="goods">
            <div class="main">
                <!-- 实现自定义事件,接收子组件通知的参数 -->
                <GoodsBox v-for="goods in goods_list" @receiveData="recFn"/>
            </div>
        </div>
    </template>
    <script>
        import GoodsBox from "../components/GoodsBox";
        export default {
            name: "Goods",
            data () {
                return {
                    goodsTitle: '哪个',
                }
            },
            methods: {
                recFn(title) {
                    console.log('接收到了' + title);
                    this.goodsTitle = title;
                }
            },
            components: {
                GoodsBox,
            },
        }
    </script>
    
    

    组件的生命周期钩子

    1. 组件的生命周期:一个组件从创建到销毁的整个过程

    2. 生命周期钩子:在一个组件生命周期中,会有很多特殊的时间节点,且往往会在特定的时间节点完成一定的逻辑,特殊的事件节点可以绑定钩

      注:钩子 - 提前为某个事件绑定方法,当满足这个事件激活条件时,方法就会被调用 | 满足特点条件被回调的绑定方法就称之为钩子

    <template>
        <div class="goods">
            <Nav />
        </div>
    </template>
    <script>
        import Nav from "../components/Nav";
        export default {
            name: "Goods",
            components: {
                Nav,
            },
            beforeCreate() {
                console.log('该组件要被加载了')
            },
            created() {
                console.log('该组件要被加载成功了')
            },
            updated() {
                console.log('数据更新了')
            },
            destroyed() {
                console.log('该组件销毁了')
            }
        }
    </script>
    
    

    路由传参

    通过 url 正则传递数据

    1. 设置

      1. 路由:path: '/goods/detail/:pk'		|   '/goods/:pk/detail/:xyz'
        请求:'/goods/detail/任意字符'        |    '/goods/任意字符/detail/任意字符'
        
    2. 如何传

      1. <router-link :to="`/goods/detail/${pk}`"></router-link>
        this.$router.push(`/goods/detail/${pk}`)
        
    3. 如何取

      1. this.$route对象是管理路由参数的,传递的参数会在this.$route.params字典中
        this.$route.params.pk
        

    通过 url 参数传递数据

    1. 设置

      路由: path: '/goods/detail'
      请求: '/goods/detail?pk=数据'
      
    2. 如何传

      <router-link :to="`/goods/detail?pk=${pk}`"></router-link>
      <router-link :to="{name:'GoodsDetail', query:{pk: pk}}"></router-link>
      
      this.$router.push(`/goods/detail?pk=${pk}`)
      this.$router.push({name:'GoodsDetail', query:{pk: pk}})
      
    3. 如何取

      this.$route对象是管理路由参数的,传递的参数会在this.$route.query字典中
      this.$route.query.pk
      

    第一种

    配置:router/index.js

    const routes = [
        {
            path: '/goods/detail/:pk',
            name: 'GoodsDetail',
            component: GoodsDetail
        },
    ]
    

    传递: GoodsBox.vue

    <router-link class="goods-box" :to="`/goods/detail/${goods.pk}`">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </router-link>
    
    <!------------------- 或者 ------------------->
    
    <div class="goods-box" @click="goDetail(goods.pk)">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
    <script>
        export default {
            name: "GoodsBox",
            methods: {
                goDetail (pk) {
                    this.$router.push(`/goods/detail/${pk}`);
                }
            }
        }
    </script>
    

    接收:GoodsDetail.vue

    <script>
        export default {
            name: "GoodsDetail",
            data () {
                return {
                    pk: '未知',
                }
            },
            // 通常都是在钩子中获取路由传递的参数
            created() {
                this.pk = this.$route.params.pk || this.$route.query.pk;
            }
        }
    </script>
    

    第二种

    配置:router/index.js

    const routes = [
        {
            path: '/goods/detail',
            name: 'GoodsDetail',
            component: GoodsDetail
        },
    ]
    

    传递:GoodsBox.vue

    <router-link class="goods-box" :to="`/goods/detail?pk=${goods.pk}`">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </router-link>
    
    <!------------------- 或者 ------------------->
    
    <div class="goods-box" @click="goDetail(goods.pk)">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
    <script>
        export default {
            name: "GoodsBox",
            methods: {
                goDetail (pk) {
                    // this.$router.push(`/goods/detail?pk=${goods.pk}`);
                    
                    // 或者
                    this.$router.push({
                        name: 'GoodsDetail',
                        query: {
                            pk,
                        }
                    });
                }
            }
        }
    </script>
    

    接收:GoodsDetail.vue

    <script>
        export default {
            name: "GoodsDetail",
            data () {
                return {
                    pk: '未知',
                }
            },
            // 通常都是在钩子中获取路由传递的参数
            created() {
                this.pk = this.$route.params.pk || this.$route.query.pk;
            }
        }
    </script>
    

    全家配置自定义 CSS 与 js

    global.css

    html, body {
        margin: 0;
    }
    
    a {
        color: black;
        text-decoration: none;
    }
    
    ul {
        margin: 0;
        padding: 0;
    }
    

    settings.js

    export default {
        base_url: 'https://127.0.0.1:8000'
    }
    

    main.js

    //1) 配置全局css
    import '@/assets/css/global.css'
    // import global_css from '@/assets/css/global.css'  // 资源需要用变量保存,方便以后使用
    // require('@/assets/css/global.css')
    // let global_css = require('@/assets/css/global.css')  // 资源需要用变量保存,方便以后使用
    
    
    // 2) 配置自定义js设置文件
    import settings from '@/assets/js/settings.js'
    Vue.prototype.$settings = settings;
    // 在任何一个组件中的逻辑,可以通过 this.$settings访问settings.js文件的{}数据
    


    总结:

    """
    项目:
    	环境;node -> npm -> cnpm -> vue/cli
    	创建:vue create proj
    	配置:配置npm启动项
    	项目目录结构:依赖、环境、入口、核心代码们
    	
    组件:
    	构成:template + script + style
    	导入:import 别名 from '路径'
    	父加子:1)导入 2)注册 3)使用
    	组件数据:组件化处理 data(){ return {} }
    	传参:父传子 - 自定义组件属性  |  子传父 - 自定义组件事件
    	生命周期钩子:created() { //完成后台请求等 }
    
    路由:
    	根组件中的页面占位:<router-view />
    	导航栏中的页面跳转:<router-link to=""></router-link>
    	代码中的逻辑跳转:this.$router.push() | this.$router.go()
    	路由传参:两种方式
    	两个路由对象:
    		this.$router - 控制路由跳转
            this.$route - 控制路由数据
    """
    
  • 相关阅读:
    Swift 设置navigation左右两侧按钮
    Tab Bar Controller和Navigation Controller混合使用详细教程
    导航栏控制器和标签栏控制器(UINavigationController和UITabBarController)混用
    UIViewController、UINavigationController与UITabBarController的整合使用
    iOS开发UI篇—UIWindow简单介绍
    mod_wsgi + pymssql通路SQL Server座
    UVA 11464 Even Parity(递归枚举)
    iOS kvc
    数据的同步为每个站点创建触发器同步表
    精彩编码 【进制转换】
  • 原文地址:https://www.cnblogs.com/kai-/p/12309827.html
Copyright © 2011-2022 走看看