prop
官方解释:Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。
通俗点讲就是:prop是父组件用来传递数据的一个自定义属性。
Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' })
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data
中的值一样。
一个 prop 被注册之后,你就可以像这样把数据作为一个自定义特性传递进来:
<blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post>
结果如下
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。(父传子可以,子传父不行)这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。(不能直接改props里面的值,可以定义一个属性或者方法来接受props里面的值后再操作)
官方举例:
1.这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
案例:prop父组件向子组件传值
父组件:
<template> <div> 父组件: <input type="text" v-model="name"> <br> <br> <!-- 引入子组件 --> <child :inputName="name"></child> </div> </template> <script> import child from './child' export default { components: { child }, data () { return { name: '' } } } </script>
子组件:
<template> <div> 子组件: <span>{{inputName}}</span> </div> </template> <script> export default { // 接受父组件的值 props: { inputName: String, required: true } } </script>
$emit 子组件向父组件传值:自定义事件,this.$emit。
子组件:
<template> <div> 子组件: <span>{{childValue}}</span> <!-- 定义一个子组件传值的方法 --> <input type="button" value="点击触发" @click="childClick"> </div> </template> <script> export default { data () { return { childValue: '我是子组件的数据' } }, methods: { childClick () { // childByValue是在父组件on监听的方法 // 第二个参数this.childValue是需要传的值 this.$emit('childByValue', this.childValue) } } } </script>
父组件:
<template> <div> 父组件: <span>{{name}}</span> <br> <br> <!-- 引入子组件 定义一个on的方法监听子组件的状态--> <child v-on:childByValue="childByValue"></child> </div> </template> <script> import child from './child' export default { components: { child }, data () { return { name: '' } }, methods: { childByValue: function (childValue) { // childValue就是子组件传过来的值 this.name = childValue } } } </script>
以上讲了父传子,子传父,那么非父子组件直接如何传值呢?
网上搜到了这样一个例子:vue事件总线(vue-bus)可实现非父子组件传值
安装
$ npm install vue-bus
如果在一个模块化工程中使用它,必须要通过 Vue.use()
明确地安装 vue-bus:
import Vue from 'vue'; import VueBus from 'vue-bus'; Vue.use(VueBus);
如果使用全局的 script 标签,则无须如此(手动安装)。
1.公共实例文件bus.js,作为公共数控中央总线
import Vue from "vue"; export default new Vue();
2.在组件A中传递参数
import Bus from '../bus.js'; export default { name: 'first', data () { return { value: '我来自first.vue组件!' } }, methods:{ add(){// 定义add方法,并将msg通过txt传给second组件 Bus.$emit('txt',this.value); } } }
3.在组件B中接受参数
import Bus from '../bus.js'; export default { name: 'first', data () { return { value: '我来自second.vue组件!' } }, methods:{ add(){// 定义add方法,并将msg通过txt传给second组件 Bus.$on('txt',()=>{
this.message=this.vue;
}); } } }
这样,就可以在第二个非父子关系的组件中,通过第三者bus.js来获取到第一个组件的value。
兄弟组件之间与父子组件之间的数据交互,两者相比较,兄弟组件之间的通信其实和子组件向父组件传值有些类似,其实他们的通信原理都是相同的,
例如子向父传值也是$emit和$on的形式,只是没有eventBus,但若我们仔细想想,此时父组件其实就充当了bus这个事件总线的角色。
这种用一个Vue实例来作为中央事件总线来管理组件通信的方法只适用于通信需求简单一点的项目,对于更复杂的情况,Vue也有提供更复杂的状态管理模式Vuex来进行处理,请自行到官网进行学习。
vue router按需加载
import VueRouter from 'vue-router' import Layout from 'components/layout' // import Layout_2 from 'components/layout1' import HeadTopbar from 'components/head_top_bar' import HeadTopbar1 from 'components/head_top_bar1' import TopBar1 from 'components/top_bar1' import TopBar2 from 'components/top_bar2' import TopBar3 from 'components/top_bar3' import TopBar4 from 'components/top_bar4' import TopBar5 from 'components/top_bar5' //MobileApp // 登陆模块(按需加载,当渲染其他页面时才加载其组件,并缓存,减少首屏加载时间) const Login = resolve => require(['views/login'], resolve) const LocalAllList = resolve => require(['views/MobileApp/local_all_list'], resolve) const Administration = resolve => require(['views/MobileApp/administration'], resolve)
computed 和 methods watch区别
描述
vue 中computed 和methods 在使用效果来看可以说是一样的,但是深入看还是不一样的。区别就在于: computed 依赖缓存, methods 却不是。怎么理解呢?当Dom每次需要渲染computed的值,这个值已经处于缓存之中,不需要再重复的经历一遍计算过程,只有当computed依赖的数据变量发生变化,这个计算属性会自动更新,不需要渲染触发。methods 的值被获取的时候就会每次都会重新经历一遍计算过程。
所以由此可以看出,computed和methods 的应用场景 和 计算过程的复杂程度有关, 如果计算过程复杂庞杂,而且计算属性会被经常调用(getter),那么最好使用缓存;如果,需要的值,计算简单,调用不频繁,实时性比较高(存在异步请求),会比较适合methods
computed有缓存,若相关数据未发生变化,则不调用;
methods无缓存,需要事件才能调用它(如点击等);
watch多用于数据交互频繁的内容。(例如定时axios从服务器获取数据)。
给大家推荐一套简易博客系统,源码已开源,github地址:https://github.com/qqq408370953/blog-nuxt 开源不易,望请star~