Vue基本语法day05

版权声明:转载-复用,请联系博主微信:qiang510939237 https://blog.csdn.net/qiang510939237/article/details/89396338

组件 (重难点)

一 : 认识组件

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可 (将一个完整的页面,抽离成一个个独立的组件,最终,通过这一个个独立组件完成整个的页面(项目)的功能)

组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的,方便代码分层开发,保证每个功能模块的职能单一
- 组件化: 是从UI界面的角度进行划分的,前端的组件化,方便UI组件的重用
- 组件化开发的优势/作用: 复用

二 : 全局组件定义的三种方式

  1. 使用 Vue.extend 配合 Vue.component 方法:

     var login = Vue.extend({
       template: '<h1>登录</h1>'
     });
     Vue.component('login', login);
    
  2. 直接使用 Vue.component 方法:

     Vue.component('register', {
        template: '<h1>注册</h1>'
     });
    
  3. 将模板字符串,定义到script标签种:

     <script id="tmpl" type="x-template">
        <div><a href="#">登录</a> | <a href="#">注册</a></div>
     </script>
    

    同时,需要使用 Vue.component 来定义组件:

     Vue.component('account', {
        template: '#tmpl'
     });
    

    注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!


组件中展示数据和响应事件

1. 在组件中,data需要被定义为一个方法,例如:
	Vue.component('account', {
      template: '#tmpl',
      data() {
        return {
          msg: '大家好!'
        }
      },
      methods:{
        login(){
          alert('点击了登录按钮');
        }
      }
    });
2. 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问

三 : 组件的基本使用(基本)

先注册, 再使用

扫描二维码关注公众号,回复: 5948155 查看本文章
Vue 中的两种注册组件的方法:
 
	1.全局注册 2.局部注册
	
    全局组件在所有的vue实例中都可以使用
    局部组件在所有的当前实例中可以使用

1.注册全局组件 - 基本使用

    /**
     * 第一个参数 : 组件名称
     * 第二个参数 : 是一个配置对象, 该配置对象与 Vue 实例的配置对象几乎完全相同
     *      	   也就是说: vue实例中用到的配置项,和组件中的配置项几乎相同
     */
    Vue.component('child', {
      template: `
          <h1 class="red">这是child组件</h1>
          `
    })
- 注意点
  - 注册全局组件也是放到 vm 实例之前 
  - 模板只能有一个根节点
  - 组件的配置项和 vue 实例 的配置项一样 (如:data、methods、filters、watch、computed、钩子函数等)
  - 组件的 data 是一个函数 , 并且返回一个对象

    // 演示为什么vue在组件中的数据采用函数,而不是对象 ???
    // 原因 : 只想让组件复用,不想让数据复用
    // 不建议修改对象的属性,
    var Component = function() {}
    // 使用对象
    Component.prototype.data = {
        demo: 123
    }
    // 使用函数
    Component.prototype.data = function() {
        return {
            demo: 111
        }
    }
    var component1 = new Component()
    var component2 = new Component()
    component1.data().demo = '8888'
    console.log(component2.data().demo) // 456

	使用组件: - 当标签一样使用  <child></child>
	
2. 使用components属性定义局部子组件
	//  引用组件
	<div id="app">
		<account></account>
	</div>
	
	// 组件实例定义方式:
	<script>
	    // 创建 Vue 实例,得到 ViewModel
	    var vm = new Vue({
	      el: '#app',
	      data: {},
	      methods: {},
	      components: { // 定义子组件
	        account: { // account 组件
	          template: '<div><h1>这是Account组件{{name}}</h1><login></login></div>', // 在这里使用定义的子组件
	          components: { // 定义子组件的子组件
	            login: { // login 组件
	              template: "<h3>这是登录组件</h3>"
	            }
	          }
	        }
	      }
	    });
  	</script>

四 : 组件通讯 (介绍)

导入: 演示子组件访问父组件数据,发现报错

- 组件是一个独立、封闭的个体
  - 也就是说: 组件中的数据默认情况下, 只能在组件内部使用,无法直接在组件外部使用
  - 可以将 vue 实例看做一个组件
- 对于组件之间需要相互使用彼此的情况,应该使用 **组件通讯机制** 来解决
- 组件通讯的三种情况 :
  1. 父组件将数据传递给子组件 (父 => 子)
  2. 子组件将数据传递给父组件 (子 => 父)
  3. 非父子组件(兄弟组件)

五 : 父 ==> 子 (重点) 两步

1. 通过属性,父组件将要传递的数据,传递给子组件

    <child :msg="pmsg"></child>
    
2. 子组件通过 props 配置项,来指定要接收的数据 (来定义父组件传递过来的数据)

    props: ['msg']
    
    // 以后使用
    - 组件内: msg
    - 事件中: this.msg

1. 组件实例定义方式,注意:一定要使用props属性来定义父组件传递过来的数据

	<script>
	    // 创建 Vue 实例, 得到 ViewModel
	    var vm = new Vue({
	      el: '#app',
	      data: {
	        msg: '这是父组件中的消息'
	      },
	      components: {
	        son: {
	          template: '<h1>这是子组件 --- {{finfo}}</h1>',
	          props: ['finfo']
	        }
	      }
	    });
	</script>
	
2. 使用v-bind或简化指令,将数据传递到子组件中:
 
	<div id="app">
    	<son :finfo="msg"></son>
  	</div>

六 : 子 ==> 父 (重点) 三步

  1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;

  2. 父组件将方法的引用传递给子组件,其中,getMsg是父组件中methods中定义的方法名称,func是子组件调用传递过来方法时候的方法名称

       <son @func="getMsg"></son>
    
  3. 子组件内部通过this.$emit(‘方法名’, 要传递的数据)方式,来调用父组件中的方法,同时把数据传递给父组件使用

       <div id="app">
         <!-- 引用父组件 -->
         <son @func="getMsg"></son>
     
         <!-- 组件模板定义 -->
         <script type="x-template" id="son">
           <div>
             <input type="button" value="向父组件传值" @click="sendMsg" />
           </div>
         </script>
       </div>
    
       <script>
         // 子组件的定义方式
         Vue.component('son', {
           template: '#son', // 组件模板Id
           methods: {
             sendMsg() { // 按钮的点击事件
               this.$emit('func', 'OK'); // 调用父组件传递过来的方法,同时把数据传递出去
             }
           }
         });
     
         // 创建 Vue 实例,得到 ViewModel
         var vm = new Vue({
           el: '#app',
           data: {},
           methods: {
             getMsg(val){ // 子组件中,通过 this.$emit() 实际调用的方法,在此进行定义
               alert(val);
             }
           }
         });
       </script>
    

1. 父组件中提供一个方法

    pfn(arg) {
        console.log('父组件中接受到子组件传递过来的数据:', arg)
    }

2. 通过自定义事件, 父组件将这个方法传递给子组件

    // 自定义事件 <child @fn="pfn"></child>

3. 子组件调用这个方法( 触发父组件中传递过来的自定义事件 )

    // 在钩子函数里演示也可以,自己调用
     created() {
        // 调用父组件中的方法 pfn
        // 注意:通过 $emit 方法来触发事件 fn
        // 第一个参数:表示要触发的自定义事件名称,也就是 @fn
        // 第二个参数:表示要传递给父组件的数据
        this.$emit('fn', 'child msg')
    }

七 : 目前为止可以存属性的地方

1. data
2. 计算属性
3. props

八 : 单向数据流(组件与组件之间) (了解)

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定: 父级 prop 的更新会向下流动到子组件中,但是反过来则不行.这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

- 透漏三个问题 :
  	- 组件与组件之间是单向数据流 
	- 父级 props 的更新会向下流动到子组件中
    - 子组件不允许修改父组件传过来的prop数据

问题: vue 是单向的还是双向的 ?? (单向)

双向 (V <==> M)  (v-model 语法糖,本质还是我给你,你给我)

单向 ( 组件 与 组件 )

九 : props 的特点 : (只读)

- 演示验证 props 只读
	 - 传的是简单类型 : 修改会报错
	 - 传的复杂类型 (地址) : 修改不会报错,是因为地址没有变 ,测试 obj={}立马报错
 	 - 修改父组件传给子组件的数据
 	 
 思路: 把接收过来的数据,保存到 data 中一个临时值 (适用在该组件接收数据只会在当前组件内使用)
  Vue.component('child', {
      template: `
      	<div>子组件 {{ cmsg }} </div>
       `,
        data() {
          return {
            cmsg: this.msg
          }
        },
        props: ['msg'],
        created() {
          this.cmsg = 666
        }
  })

猜你喜欢

转载自blog.csdn.net/qiang510939237/article/details/89396338