组件的深入理解

第一个vue小程序

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 根容器 -->
    <div id="app">
        <h3 :title="message+'哈哈哈哈'">{
   
   {message}}</h3>
        <!-- 4、props没有接收的属性会自动赋给组件最外层标签 
        <h1 style="color: red;">我是一个组件哈哈哈哈</h1>-->
        <name style="color:red" :msg="message"></name>
    </div>
    <!-- CDN引入 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // 2、全局组件:参数一 组件名字  参数二对象
        // 必须组件写在创建实例前边
        Vue.component('name', {
      
      
            template: `<h1>我是一个组件{
       
       {item}}</h1>`, //模板
            // 3、组件data不能使用对象,因为组件复用的时候公用一个data,一个修改会引起其他改变
            data() {
      
      
                return {
      
      
                    item: '哈哈哈哈'
                }
            },
            props: {
      
      
                msg: String
            }
        })

        // 1、new 一个vue实例,参数为对象
        let vm = new Vue({
      
      
            el: '#app', //el指定容器
            data: {
      
         //根组件不会被复用,所以data可以为对象
                message: 'Hello Word!'
            }
        })

    </script>
</body>

</html>

指令

v-bind:name === :name
v-if v-else-if v-else  v-show
v-for 
v-on:click === @click

$attrs 用于向父组件向孙子组件传递值或者样式等

  • 父组件给子组件传值,若子组件不用props接收,则会变为子组件根元素的属性
  • 可使用this.$attrs获取到传递的所有数据集合
//父组件中调用子组件并传递属性
<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
//子组件中调用孙子组件 <main>,并把$attrs传递给main孙子组件,避免了props一层一层向下传递
app.component('custom-layout', {
    
    
  template: `
    <header>...</header>
    <main v-bind="$attrs">...</main>
    <footer>...</footer>
  `
})

插槽

自定义组件

@input:输入框变化就会执行
@change:输入框失焦的时候执行

1. 组件标签上使用 v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型v-model的值会覆盖其标签上的value值:解决方法:添加model选项

<body>
    <!-- 根容器 -->
    <div id="app">
    //1、页面引入name组件,绑定v-model值为变量name,此时如果子组件为input等,则会覆盖其value的值
        <name v-model="name"></name>
    </div>
    <script>
        // 2、为了解决以上问题,子组件中需要定义model属性,分别是prop用来接收绑定的值,event用来改变父组件的值
        Vue.component('name', {
    
    
            template: `<input value="我是默认值" @input="change1" :title="name1"/>`, //模板
            model: {
    
    
                prop: 'name1',
                event: 'change'
            },
            // 3、props中必须再传一下name1,否则子组件内部无法获取到name1的值;
            props: {
    
    
                name1: String
            },
            methods: {
    
    
                // 4、子组件@input的时候给父组件传递数据
                change1() {
    
    
                    this.$emit('change', 'aaaaaaa') //此时name就会变成aaaaaaaa
                }
            }
        })

        let vm = new Vue({
    
    
            el: '#app', //el指定容器
            data: {
    
      
                name: '嘿嘿'
            },
        })

    </script>
</body>

2.在组件上添加原生事件 .native

  • 在组件上直接添加原生事件不会执行,添加 .native 修饰符即可执行change方法
  • 在组件标签上直接添加属性或样式等,会默认添加给组件的根元素
<name @click.native="change"></name>

3. 子组件某个时机改变父组件的data,修饰符 .async

			//子组件change事件里边,向父组件传递值this.son
			change() {
    
    
                    this.$emit('update:foo', this.son)
            }
            // 1、父组件接收并赋值给data中的message
            <age @update:foo="val => message = val"></age>
            // 2、使用 .async 修饰符如下:
            <age :foo.sync="message"></age>

混入Mixins

混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。

项目中如何使用混入

  • 在src目录下创建一个mixins文件夹,文件夹下新建一个myMixins.js文件;
  • 定义混入对象
export default {
    
    
	data(){
    
    
	return {
    
    
      msg: 'erwerwe',
      form:{
    
    
        a:'aaa'
      }
    }
	},
	filters: {
    
     //过滤器
		numToString(value) {
    
    
			return value.toString();
		}
	},
	created(){
    
     //钩子函数
		    console.log('这是混入的组件')
	},
	computed: {
    
       //计算属性
		ids() {
    
    
				return  !this.loading
			 }
	},
	methods:{
    
    
     exm(){
    
    
      console.log('这是混入的exm方法')
      },
     clickFn(){
    
    
      console.log(this.msg)
    },

	// 其它属性方法......
		}
}
  • 在组件中使用
<script>
//导入js文件
import fun from './mixins/common.js'

export default {
    
    
  name: "HelloWorld",
  mixins:[fun],  //混入 fnu对象
  created(){
    
    
    console.log('这是当前组件')
  },
  data() {
    
    
    return {
    
    
      msg: "组件的msg"
    }
  },
  methods:{
    
    
    buttonClick(){
    
    
      console.log(this.form.a)
      console.log(this.msg)
      this.clickFn();
      this.exm();
    },
    exm(){
    
    
      console.log('这是组件的exm方法')
    }
  }
}
</script>

全局混入
它将影响每一个之后创建的 Vue 实例

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
    
    
  created: function () {
    
    
    var myOption = this.$options.myOption
    if (myOption) {
    
    
      console.log(myOption)
    }
  }
})

new Vue({
    
    
  myOption: 'hello!'
})
// => "hello!"

合并规则

  • 混入中的msg属性,和组件的msg属性冲突,以组件的值优先。
  • 同名钩子函数都会调用,混入函数先调用
  • 值为对象的选项,如methods,components,directives等,将会合并为一个新对象,如果键名冲突,组件的值优先

与vuex的区别

  • vuex:里面的变量在每个组件中均可以使用和修改,在任一组件中修改此变量,其他组件中此变量也会随之修改。
  • Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

与公共组件的区别

  • 组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
  • Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。
Vue.prototype.$eventBus = new Vue();
this.$eventBus.$emit("handler","我是传递的值")
this.$eventBus.$on("handle",(value)=>{
    
    
    this.value = value;
})

猜你喜欢

转载自blog.csdn.net/weixin_43848576/article/details/115795275