Vue第五天:组件与路由

一、父组件传值子组件

 Vue.component('login',{
        template:'#login',
        data(){
          return{}
        },
        props:{
          // 自己定义接收
          type:String,
          size:Number,
          // 定义多个数据类型
          // pageSize:[String,Number]
          // 设置默认值
          pageSize:{
            type:[Number,String],
            default(){
              return 5
            }
          },
        },

二、子组件传值父组件

子组件调用父组件的方法

  1. 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
  2. 子组件可以触发这个事件$emit('事件名字')

子组件给父组件传递数据

  1. $emit方法第二个参数可以定义子组件给父组件传递的内容
  2. 在父组件中怎么拿到这内容

2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到

2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。

<!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>组件自定义事件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <!-- 1.给组件添加事件 -->
    <div id="app">
        <son v-on:click-son='clickParent($event,"自定义参数")' v-on:click-son2='clickParent2'></son>
    </div>

    <template id='sonTemp'>
        <div>
            <button @click='clickSon'>点击事件</button>
            <button @click='clickSon2'>点击事件2</button>
            <h3>这是子组件的内容</h3>
        </div>
    </template>

    <script>
        var son = {
            template: '#sonTemp',
            methods: {
                clickSon() {
                    console.log('子组件的方法');
                    // 2. 在子组件中触发这个事件
                    // 发射,触发
                    // 通过这种方式,子组件也可以给父组件传值
                    this.$emit('click-son', {
                        name: '张三'
                    })
                },
                clickSon2(){
                    console.log('子组件的方法2');
                    this.$emit('click-son2', 'nihao')
                }
            },
        }

        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {
                // e是接受子组件传过来的参数,msg是这个方法自己参数
                clickParent(e, msg) {
                    console.log(e);
                    console.log('父组件的方法,数据为:' + msg);
                },
                clickParent2(e) {
                    console.log(e);
                }
            },
            components: {
                son
            }
        })
    </script>
</body>
</html>

三、ref的使用

 1、获取dom节点
        (1).给dom节点记上ref属性,可以理解为给dom节点起了个名字。
        (2).加上ref之后,在$refs属性中多了这个元素的引用。
        (3).通过vue实例的$refs属性拿到这个dom元素。
 2、获取组件
         (4).给组件记上ref属性,可以理解为给组件起了个名字。
         (5).加上ref之后,在$refs属性中多了这个组件的引用。
         (6).通过vue实例的$refs属性拿到这个组件的引用,之后可以通过这个引用调用子组件的方法,或者获取子组件的数据。
 


<!DOCTYPE html>
<html>
<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></title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id='app'>
 
        <div id="good" ref="good"> 好消息,距离国庆 还有7天 </div>
        <div> 坏消息,下周一考试 </div>
        
        <son id="myson" ref="myson"></son>
        
        <button @click="changeSon">点我 </button>
    </div>
    
    <template id="son">
        <div>
            son --{{sonMsg}}
            <button  @click="log1"> 点我</button>
        </div>
    </template>
    
    <script>
Vue.component("son",{
            template: '#son',
 
            data(){
 
                return{
                    sonMsg:"sonmsg"
                }
            },
            methods:{
                log1(){
                    console.log(1);
                }
            }
        })
        
        console.log(document.getElementById("good"));
    const vm = new Vue({
        el: '#app',
        data: {
            
        },
        methods: {
            changeSon(){
                this.$refs.myson.sonMsg = 'father'
            }
        },
        beforeCreate(){},
        created(){
            console.log(this.$refs);
            console.log(this.$refs.good);
            // // dom操作
            // this.$refs.good.style.color = 'red'
            // this.$refs.good.style.fontSize = '50px'
        },
        beforeMount(){},
        mounted(){
 
            // console.log(this.$refs);
            // dom操作
            this.$refs.good.style.color = 'red'
            this.$refs.good.style.fontSize = '50px'
 
            console.log(document.getElementById("myson"));
            console.log(this.$refs.myson.log1());
            console.log(this.$refs.myson.sonMsg);
        },
        beforeUpdate(){},
        updated(){},
        beforeDestroy(){},
        destroyed(){},
    })
    </script>
 </body>
</html>

四、什么是路由

1、后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源

2、前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现


五、路由的基本使用

1、引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)

2、创建路由new VueRouter(),接受的参数是一个对象

3、在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性

4、path属性是url的地址,component属性就是显示的组件(传组件的对象)

5、创建的路由需要和vue实例关联一下 

6、路由到的组件显示在哪个位置<router-view></router-view>

<!DOCTYPE html>
<html>
<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></title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- 第一步 引入router的js文件 -->
  <script src="https://unpkg.com/vue-router@3.0.0/dist/vue-router.js"></script>
  <style>
    .router-link-active{
      font-size: 30px;
      color: hotpink;
    }
    .myactive{
      font-size: 40px;
      color: red;
    }
  </style>
</head>
<body>
  <div id='app'>
    <router-link to="/index">首页1</router-link>
    <router-link :to="{name: 'index'}">首页2</router-link>
    <router-link to="/detail">去详情0</router-link>
    <button @click="gotodetail">去详情</button>
    <button @click="gotomine">去个人中心</button>
    <!-- 预留的展示区  即被路由链接的显示区域-->
    <router-view></router-view>
  </div>
 
  <!-- 组件的创建 -->
  <template id="index">
    <div>
      首页
      <!-- 普通跳转 -->
      <router-link to="/detail">去详情1</router-link>
      <!-- 跳转时路径传参 -->
      <router-link to="/detail?id=104&name='zs'">
        去详情2
      </router-link>
      <!-- <router-link :to="{path: '/detail',query:{id: 10000,name: 'zs'}}">去详情3</router-link> -->
      <!-- <router-link :to="{name: 'my',params:{userid: 2222222}}">去个人中心</router-link> -->
      <!-- 缺少params参数 -->
      <!-- <router-link :to="{name:'my'}">错误示范</router-link> -->
    </div>
  </template>
 
  <template id="detail">
    <div>
      详情页
    </div>
  </template>
 
  <template id="mine">
    <div>
      个人页
    </div>
  </template>
  <script>
    // Vue.component('index',{
    //   template: '#index',
    // });
    // 简写声明组件
    let index = {
      template: '#index',
    }
    let detail = {
      template: '#detail',
    }
    let mine = {
      template: '#mine',
    }
    // 第二步 创建一个路由
    const router = new VueRouter({
      routes: [
        // 路由重定向
        {
          path: '/',
          redirect: '/index',
        },
        // 确定路由方向
        {
          // url地址
          path:'/index',
          // 配合的组件
          component: index,
          // 对应声明的组件
          name:'index'
        },
        {
          // url地址
          path:'/detail',
          // 配合的组件
          component: detail,
          // 对应声明的组件
          name:'detail'
        },
        // 路径传参
        {
          path:'/mine/:userid',
          component:mine,
          name:'my'
        }
      ],
      // 自定义路由激活时高亮
      linkActiveClass: 'myactive'
    });
  const vm = new Vue({
    el: '#app',
    // 挂载定义的路由到Vue实例上
    router,
    data: {
    },
    methods: {
      // 点击进行函数式跳转
      gotodetail(){
        this.$router.push({path:'/detail'})
        this.$router.push({path:'/mine',query:{id:104,name:'list'}});
      },
      gotomine(){
        this.$router.push({path:'/my',params:{userid:666}});
      },
    },
    // 监听 跳转的方向是否正确。。
    // watch: {
    //   $route(){
    //     console.log(this.$route);
    //     if(this.$route.name == 'my'){
    //       alert('你好');
    //     }
    //   }
    // },
    created(){
    },
    beforeMount(){
    },
    mounted(){
    },
    beforeUpdate(){
    },
    updated(){
    },
  })
  </script>
</body>
</html>

路由高亮:

        1、使用默认的样式

        直接设置router-link-active

        2、自定义样式

        配置 linkActiveClass:'自定义的类名'

路由重定向 :

        通过redirected重定向

六、计算属性和监听器

1.watch:监听data中属性的改变

const vm = new Vue({
          el: '#app',
          data: {
              firstName:"",
              lastName:"",
              // name:"",
          },
          // watch监听data中属性的改变
          watch:{
              firstName:function(value){
                  console.log(value);
                  this.name = this.firstName + '-' +this.lastName
              },
              lastName:function(value){
                  console.log(value);
                  this.name = this.firstName + '-' +this.lastName
              },
          },
      })

2.computed:默认只有getter的计算属性,定义有getter和setter的计算属性

(1)getter:只要该表达式中含有的data中的数据发生改变时,该属性中的数据就会发生改变

(2)setter:只有当自身发生改变的时候才触发

const vm = new Vue({
          el: '#app',
          data: {
              firstName:"",
              lastName:"",
              // name:"",
          },
          // 属性计算
        computed: {
              // 属性不能和data中重复
              // name() {
              //     return this.firstName + '-' +this.lastName;
              // },
              name: {
                  get:function(){
                      return this.firstName + '-' +this.lastName;
                  },
                  // 只有当自身发生改变的时候才触发
                  set(value){
                      console.log(value);
                      console.log(value.split('-'));
                      if( value.split('-').length ==2){
                          this.firstName = value.split('-')[0]
                      this.lastName = value.split('-')[1]
                      }
                  }
              },
          },
      })

method、computed和watch的区别
1.computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,使用的时候不加();

2.methods方法表示一个具体的操作,主要书写业务逻辑;

3.watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed和methods的结合体
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值