Vue 学习笔记第 4 篇

背景介绍

默认情况下子组件是无法访问父组件中的data和methods的:

<div id="app">
  <comp></comp>
</div>
<script>
var vm = new Vue({
  el:'#app',
  data:{
    msg:' This is father msg'
  },
  methods:{},
  components:{
    
    comp: {
      template:'<h2>这是子组件--{{msg}}</h2>'//此处是无法访问到父组件中的data和methods的
    }
  }
});
</script>

1.父子组件之间传值

1.1父组件向子组件传值

在使用组件标签时,通过属性绑定的方式,将父组件的值传入到子组件

语法:

v-bind:自定义一个属性名称="传入的父组件中的变量名称"
但是该自定义的属性必须要在子组件中事先声明,需要在子组件中的props数组中定义
props:['自定义属性名称']

组件中的props数组数据全都是父组件传递给子组件的。props中的数据都是只读的,无法重新赋值。data中的数据是组件私有的可读可写的

实现方式:

<div id="app">
  <comp v-bind:parentmsg="msg"></comp>
</div>
<script>
var vm = new Vue({
  el:'#app',
  data:{
    msg:' This is father msg'
  },
  methods:{},
  components:{
    
    comp: {
      data:{},//子组件中的data是自身私有的,不是父组件传入的。是可读可写的,比如子组件通过ajax请求的数据可以放在data上。
      template:'<h2>这是子组件--{{msg}}</h2>',//此处是无法访问到父组件中的data和methods的
      props:['parentmsg']//该数组中的数据,都是父组件传入的,并且都是只读的,父组件定义的属性名称,要在此声明,才能接收。
    }
  }
});
</script>

1.2.父组件向子组件传递方法使用事件绑定机制

语法:

组件标签中通过v-on:自定事件属性名称="父组件中的方法名称"
简写为@自定义属性名称="父组件中的方法名称"

子组件在对应事件触发入口通过
this.$emit('自定义属性名称')

实例:

<div id="app">
  <comp @func="show"></comp>
</div>
<template id="temp">
	<div>
    <h1>这是子组件</h1>
    <input type="button" value="调用父组件的方法" @click="mycompClick">
  </div>
</template>
<script>
var vm = new Vue({
  el:'#app',
  data:{
    msg:' This is father msg'
  },
  methods:{
    show(){
      
    }
  },
  components:{
    comp: {
      data:{},
      template:'#temp',
      methods:{
        mycompClick(){
          this.$emit('func');//这样就实现了对父组件中的方法的调用
          //this.$emit('func',参数1,参数2)//实现调用父组件中的方法并传参,参数只要跟着方法名后面就行了,其实通过参数的这种方式也可以实现子组件向父组件传值。
        }
      }
    }
  }
});
</script>

1.3 子组件向父组件传值

上面已经说了,可以通过父组件向子组件传入一个有参数的方法的方式,可以实现父组件中接收该参数的该方式,来实现子组件向父组件传值。

2.ref快速获取元素

vue提供了ref属性可以帮助我们快速获取到元素,vue实例中有一个$refs 中就是元素

<div id="app">
  <input type="button" value="获取元素内容" @click="getElement">
  <h3 ref="myh3">This is H3 </h3>
  <login ref="mylogin"></login>
</div>
<script>
  var login = {
    template: '<h3>这是登录组件</h3>'
  };
var vm = new Vue({
  el:'#app',
  data:{},
  methods:{
    getElement(){
      console.log(this.$refs.myh3.innerText);
      console.log(this.$refs.mylogin.innerText);
    }
  },
  components:{
    login
  }
});
</script>

上面可以得到我们可以使用ref获取组件,因此可以通过$refs获取到组件,然后直接获取使用其数据和方法。

this.$refs.mylogin.msg;//直接调取其数据
this.$refs.mylogin.login();//直接调用其方法

3.路由

3.1 概念

后端路由

对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上的资源。

前端路由

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

3.2 vue-router安装的方式

3.2.1 直接下载/cdn - - 在网页里直接开发的方式

Unpkg.com提供了基于npm的cdn链接。https://unpkg.com/vue-router/dist/vue-router.js 该链接一致指向NPM发布的最新版本。你也可以像https://unpkg.com/vue-router@2.0.0/dist/vue-router.js这样指定版本号或者Tag。在Vue后面加载vue-router,它会自动安装的:

<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>

3.2.2 NPM - - webpack构建工具进行开发的方式

npm install vue-router

如果在一个模块化工程(比如说通过webpack构建的)中使用它,必须要通过Vue.use()明确的安装路由功能:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

如果使用全局的script标签,则无需如此(手动安装),即3.2.1的方式是不需要使用Vue.use(VueRouter)这种操作的。

3.3 vue-router 使用

3.3.1 router-view方式

安装vue-router之后便可使用,创建VueRouter实例对象,传入一个配置对象或者配置对象数组,配置对象即路由配置规则,每一个路由配置规则有两个属性:

  • path : 表示监听的那个路由链接地址;
  • component : **该属性的值只能放模板对象不能放组件名称. **表示 如果路由是前面匹配到的path,则展示component属性对应的组件。

vue实例通过router属性,建立与VueRouter实例对象的关系,router属性的租用是将路由规则对象VueRouter注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件。页面中通过vue-router提供的元素router-view标签来进行展示,否则无效果,因为该标签是专门用来当做占位符的,路由规则匹配到的组件就会展示到这个router-view中去。所以我们可以认为router-view 是一个占位符。

实例代码如下:

<script src="libs/vue.js"></script>
<script src="libs/vue-router.js"></script>
<body>
  <div id="app">
    <a href="#/login">登录</a><!-- 因为vue中的路由是基于hash的所以必须要加#号 -->
     <a href="#/register">注册</a><!-- 因为vue中的路由是基于hash的所以必须要加#号 -->
  	<router-view></router-view>
	</div>
  <script>
    var login = {
      template: '<h3>我是登录组件</h3>'
    };
    var register = {
      template: '<h3>我是注册组件</h3>'
    };
    var routerObj = new VueRouter({//在创建路有对象的时候可以通过构造函数,传递一个配置对象
      //route //这个配置对象中的route 表示路由配置规则
    	routes: [// 路由匹配规则,可以有多个,即每个按钮跳转的组件或者页面
        {path:'/login',component:login},//每个路由规则都是一个对象,path属性表示监听的那个路由链接地址,component属性表示如果路由是前面匹配到的path,则展示component属性对应的组件。此处component 值只能写成login不能写成'login'
        {path:'/register',component:register}
      ]//
    });
  	var vm = new Vue({
      el:'#app',
      data:{},
      methods:{},
      router:routerObj//通过该属性与VueRouter对象建立关联关系
    });
  </script>
</body>

从上述实例中我们可以得出,其实路由的改变规则就是通过hash方式改变了地址栏(即通过修改URL地址,因为该URL地址已经注册到了VueRouter对象上了,路由规则对象会监听URL的改变进行对路由规则的匹配,一旦检测到对应的path与该URL匹配便展示该path对应的对象的component组件到reouter-view中去。)

3.3.2 router-link方式

和上面的区别在于不使用a标签,而换成router-link标签,router-link默认渲染成一个a标签的效果。

<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>

<script>
routes: [// 路由匹配规则,可以有多个,即每个按钮跳转的组件或者页面
  	{path:'/',redirect:'/login'},//这里的redirect重定向是前端的重定向,和后端的重定向是不同的,这里作用是让页面默认展示某个组件      
  {path:'/login',component:login},
        {path:'/register',component:register}
      ]//
</script>

router-link 选中时默认样式为router-link-active 类样式,所以可以通过该样式来修改被选中时的样式。

还可以通过设置链接激活时使用的CSS类名。默认值可以通过路由的构造选项linkActiveClass来全局配置

var routerObject = new VueRouter({
  routes: [],
	linkActiveClass:'myactive'
});

另外可以用transition标签将router-view包裹起来实现router-view的切换效果动画。

3.4 路由传参

3.4.1 通过$route.query方式获取查询字符串中的参数

如果在路由中使用查询字符串给路由传递参数,则不需要修改路由规则的path属性

<router-link to="/login?id=1101&name=张三"></router-link>
<router-view></router-view>
<script>
var login = {
      template: '<h3>我是登录组件---{{$route.query.id}}---{{$route.query.name}}</h3>'
    };
</script>

3.4.2通过$route.params方式获取参数

该方式需要再路由设置的时候指定参数

<div id="app">
  <router-link to="/login/1201/张三">登录</router-link>
  <router-link to="/register">注册</router-link>
  <router-view></router-view>
</div>
<script>
  var login = {
    template:'<h3>登录----{{$route.params.id}}---{{$route.params.name}}</h3>'
    data(){
      return {
        msg:'123'
      }
    },
    created(){//组件的生命周期函数
      console.log(this.$route.params.id);
    }
  }
	var router = new VueRouter({
    routes:[
      {path:'/login/:id/:name',component: login}//需要通过斜杠和冒号来指定参数
    ]
  });
</script>

3.5 路由嵌套

通过route的children属性配置子路由

比如说一个account下嵌套login 和register两个组件,实现方式如下:

<script>
var router = new VueRouter({
  routes:[
    {
      path:'/account',
      component:account,
      children:[//子路由的path 前面不要带斜线
        {path:'login',component:login},//注意不能加斜线
        {path:'login',component:register}//注意不能加斜线
      ]
    }
  ]
});
</script>

3.6 命名视图

给视图组件router-view进行命名,然后通过route的components属性来制定对应视图组件要展示的组件。具体实例如下:

<div id="app">
  <router-view></router-view>
  <router-view name="left"></router-view><!-- 命名该视图组件为left-->
  <router-view name="main"></router-view>
</div>
<script>
var header = {
  template:'我是头部'
};
var leftBox = {
  template:'我是左侧栏'
};
var mainBox = {
  template:'我是主面板'
};
var router = new VueRouter({
  routes:[
    {
      path:'/',
      components:{
        'default': header,//默认展示组件header
        'left': leftBox,//试图组件名称为left的展示leftBox 组件
        'main': mainBox
      }
    }
  ]
});

</script>

4.组件的watch属性

4.1 watch 监听数据变化

可以通过watch属性监视 data 中指定数据的变化,触发该属性中对应的function处理函数,对应的该function函数可以传入两个参数[newValue, oldValue] 分别对应的是输入改变后和输入改变前的数据内容。

<div id="app">
  <input type = "text" v-model="firstName">
  <input type = "text" v-model="lastName">
  <input type = "text" v-model="fullName">
</div>
<script>
	var vm = new Vue({
    el: 'app' ,
    data: {
      firstName: '' ,
      lastName: '' ,
      fullName: '' 
    },
    methods: {},
    watch: {
      'firstName' : function(){//当firstName中的值发生改变就会触发该function   function(newValue,oldValue)// 参数可选
        this.fullName = this.firstName + ' ' + this.lastName;
      },
      'lastName' : function(newValue){
        this.fullName = this.firstName+ ' ' + newValue;//newValue 和 this.lastName 值是一样的
      }
    }
  });
</script>

另一种实现上述功能的方式-- keyup

通过@keyup添加键盘抬起时的事件处理逻辑,实现数据的动态监听与改变。

<div id="app">
  <input type = "text" v-model="firstName" @keyup="updateFullName">
  <input type = "text" v-model="lastName" @keyup="updateFullName">
  <input type = "text" v-model="fullName">
</div>
<script>
	var vm = new Vue({
    el: 'app' ,
    data: {
      firstName: '' ,
      lastName: '' ,
      fullName: '' 
    },
    methods: {
      updateFullName() {
        this.fullName = this.firstName + ' ' + this.lastName;
      }
    }
  });
</script>

但是,当上述事件改成路由的监听时,@keyup则无能为力了,这是就凸显了watch属性的作用了——watch监听路由地址的改变

4.2 watch监听路由地址的改变

思路:只需要监听到 $route.path 的值的改变也就是路由地址的值。

var vm = new Vue({
  el:'#app',
  data: {},
  methods: {},
  router,
  watch: {
    '$route.path': function(newValue,oldValue) {
      //此处可以处理路由地址变更的逻辑
    }
  }
});

5.组件的computed属性

在computed属性中,可以定义一些计算属性,计算属性的本质就是一个方法,且是有返回值的一个方法,在使用这些计算属性的时候把方法的名称直接当做属性来使用,并不会把计算属性当做方法调用。

比如我们将上述watch属性的监听方式替换成computed的方式:

<div id="app">
  <input type = "text" v-model="firstName">
  <input type = "text" v-model="lastName">
  <input type = "text" v-model="fullName">
</div>
<script>
	var vm = new Vue({
    el: 'app' ,
    data: {
      firstName: '' ,
      lastName: '' //,
      //fullName: '' //此处的data中的fullName删掉
    },
    methods: {},
  	computed: {
      'fullName': function(){//将fullName的声明放在此处
        return this.firstName + ' ' + this.lastName;
      }
    }
  });
</script>

6.methods、watch 和 computed属性的对比

  • methods: 该属性内是一些方法,主要处理一些业务逻辑操作;

  • **watch:**内容组成方式是一个键(需要观察的表达式),值(是对应的回调函数),主要用于监听指定数据的变化或者是虚拟的数据(比如路由),从而进行某些具体的业务逻辑操作,可以看成是computed和methods的结合体;

  • computed: 它主要处理一些计算逻辑,且必须有返回值,且计算结果会被缓存,如果没有变更是不会重新计算的,主要被当做属性来使用;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值