单向数据流,子组件不允许改变props的值,如msg
在组件上写event,都是自定义事件
即便: <Son @click='fn'/> 点击不会触发click 要想使用原生click: 父 <Son @click.native='fn'/> 子 (不用写this.$emit)
.native原理: 将@click="$emit('click')"绑定在了子组件的根div上,点击子组件的哪里都会触发(事件委派)
1.全局定义,在main.js文件将bus挂载到vue.prototype上 import Vue from 'vue'; Vue.prototype.bus = new Vue(); 2.新建一个bus.js文件,作为中央总线,然后再组件引用时调用这个bus.js文件 import Vue from 'vue'; const EventBus = new Vue(); export default EventBus;
一个触发事件 bus.$emit('名' , 参)
一个监听事件 bus.$on( '名' , fn(参) )
父组件: <Son type="" titil="" :msg="msg" @click='fn' >
子组件props:['type'] 用this.$attrs {titil="" msg="msg"}
子组件
<p :title="this.$attrs.title" :msg="this.$attrs.msg"></p> 可简写为:<p v-bind="this.$attrs"></p> $lieteners值为父组件的 自定义事件&&非.native
ref:用在子组件上,访问组件实例
$parent / $children:访问父 / 子实例
ref 父: <Son ref="comA" /> const a=this.$ref.comA.title 子: data () { return { title: 'Vue.js' } } $parent / $children 父: <Son /> const a=this.$children.title 子: data () { return { title: 'Vue.js' } }
祖先组件=>子孙组件
祖先组件provider来提供变量,子孙组件inject来注入变量。
//provide 是一个对象, inject 是:一个字符串数组 // A.vue export default { provide: { name: '浪里行舟' } } // B.vue export default { inject: ['name'], mounted () { console.log(this.name); // 浪里行舟 } }
provide 和 inject 绑定并不是可响应的,A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的
实现数据响应式: provide 是一个函数(返回值为一个对象), inject 是:一个对象,对象的 key 是本地的绑定名 //方法一:提供祖先组件的实例 data () { return { color: 'red' } }, provide() { return { theme: this }; }, //方法二:使用2.6最新API Vue.observable 优化响应式 provide provide() { this.theme = Vue.observable({ //向实例this上添加theme对象 color: "blue" }); return { theme: this.theme }; /************ return { theme: Vue.observable({ color: "blue" }); }; ************/ }, methods: { changeColor(color) { this.theme.color = color; } } //子孙组件写法一样 <template functional> <div class="border2"> <h3 :style="{ color: theme.color }">F 组件</h3> </div> </template> <script> export default { inject: { theme: { //函数式组件取值不一样 default: () => ({}) } } }; </script>
插槽: 父组件提供代码(html模板) => 子组件的slot => 再显示在父组件上
父: <div> <Son></Son> </div> 子: <div> <slot>没插</slot> </div> //结果: 没插 父: <div> <Son>插了</Son> </div> 子: <div> <slot>没插</slot> </div> //结果: 插了
父: <Son> <template v-slot:header> <h1>Here might be a page title</h1> </template> </Son> 子: <div> <slot name="header"></slot> ... <slot name="footer"></slot> </div>
父组件提供代码(html模板)带有子组件的数据 => 子组件的slot => 再显示在父组件上
父: <Son> <template v-slot:todo="slotProps" > {{slotProps.user.firstName}} </template> </Son> //slotProps 可以随意命名 //slotProps 接取的是子组件标签slot上属性数据的集合所有v-bind:user="user" //:todo是插槽名(具名插槽), :default是默认插槽 子: <slot name="todo" :user="user" :test="test"> </slot> data() { return { user:{ lastName:"Zhang", firstName:"yue" }, test:[1,2,3,4] } },
重复的js 写在一个单独的js里, 如myMixin
export default{
...
}
引入 import myMixin from './myMixin'
使用 mixins: [ ' myMixin ' ]