Vue基础四(上)

组件

  • 前端组件化发展历史
    • 前后端耦合
      • 前后端不分离项目
        • 找后台搭建项目开发环境
        • 寻找项目目录中的静态资源目录
        • 同步修改css
    • 前后端分离
    • 前端团队合作项目
      • 组件化为了解决多人协作冲突问题
      • 复用
  • 使用组件的优势
    • 项目的维护、更新会简单
    • 复用
  • 组件的概念
    • 组件是一个 html、css、js、img 等的一个聚合体
    • 组件中的 options 大体上和Vue中的 options 是一致的
      • 即 data / methods / watch / computed 等在组件中均可使用
    • Vue中的组件属于扩展性功能,通过 Vue.extend() 来扩展的
    • 组件是对html标签的扩展【 后端发展来的,借鉴了 angular / react 】
ƒ Vue (options) {
    if (!(this instanceof Vue)
       ) {
        warn('Vue is a constructor and should be called with the `new` keyword');
    }
    this._init(options);
}
ƒ VueComponent (options) {
    this._init(options);
}
// VueComponet这个构造函数我们不进行new实例化,我们希望组件是以标签化的形式展示
  • 组件的注册
    • 组件是以标签的形式使用的,但其不符合html标准,故需要解析,这个过程叫组件的注册
    • <Banner></Banner> -> <div></div> 组件要想合法化,必须注册解析
- 全局注册
<body>
  <div id="app">
    <Hello></Hello>
    <head-title></head-title>
    <Hello/>
  </div>
  
  <div id="root">
    <Hello></Hello>
  </div>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /* 它是组件的选项 options */
  var Hello = Vue.extend({
    template: '<div> hello 组件 </div>', // 定义一个组件的模板
  })
  /* 组件的全局注册 */
  // Vue.component( 组件名,组件的选项 )
  /* 
    组件的命名: 
      1. 大驼峰命名法:Hello HeadTitle
      2. 小写加 - :head-title
    备注:如果js中定义的是大驼峰,那么html结构中要使用小写带 -
    	  在Vue框架中没有上条要求限制
  */
  Vue.component('Hello',Hello )
  Vue.component('HeadTitle',Hello)

  new Vue({ // 这个是根实例组件,它是最大的组件
    el: '#app'
  })

  new Vue({
    el: '#root'
  })
</script>
- 局部注册
<body>
  <div id="app">
    <Hello></Hello>
  </div>

  <div id="root">
    <Hello/> <!-- 不起作用 -->
  </div>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  var Hello = Vue.extend({
    template: '<div> Hello 组件 </div>'
  })

  new Vue({
    el: '#app',
    /* 局部注册 - components选项 */
    components: {
      // 组件名:组件的选项
      'Hello': Hello
    }
  })

  new Vue({
    el: '#root'
  })
</script>
- 组件的简写
<script>
// 全局注册
  Vue.component('Hello',{
    template: '<div> hello 组件 </div>',
  })

  new Vue({
    el: '#app'
  })
</script>
----------------------------------------
<script>
// 局部注册
  new Vue({
    el: '#app',
    components: {
      'Hello': {
        template: '<div> Hello 组件 </div>'
      }
    }
  })
</script>
  • template模板标签
<body>
  <div id="app">
    <Hello></Hello>
    <template>
      <p> 456 </p>
    </template>
  </div>
  <Hello></Hello>
  <!-- 组件的模板用一个template标签来完成 -->
  <!-- 
	   缺点:将来会渲染到页面中
	   有解决方案
   -->
  <template id = "hello">
    <!-- template标签的直接子元素只能有一个 -->
    <div>
      Hello 组件
      <p> 123 </p>
    </div>
  </template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /* template标签在实例范围内是会被解析,将来不会在页面出现,但是实例范围外会出现 */
  Vue.component('Hello',{
    template: '#hello'
  })

  new Vue({
    el: '#app'
  })
</script>
  • 组件的规则 - is属性
<body>
  <div id="app">
    <table>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <!-- <Hello></Hello> 不起作用 -->
      <tr is = "Hello"></tr>
      <!-- 添加 is 属性 -->
    </table>
  </div>
  <template id = "hello">
      <tr>
        <td>4</td>
        <td>5</td>
        <td>6</td>
      </tr>
  </template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /* 
    * html中那些规定了自己的直接子元素的标签,是不能直接放组件的
    解决:通过is属性绑定一个组件
  */
  Vue.component('Hello',{
    template: '#hello'
  })
  new Vue({
    el: '#app'
  })
</script>
  • 组件的选项
<body>
  <div id="app">
    <Hello></Hello>
  </div>
  <template id = "hello">
    <!-- 唯一根元素 -->
    <div>
      <h3> hello </h3>
      <input type = "text" v-model = "msg">
      <p> {{ msg }} </p>
      <button @click = "handler"> 点击 </button>
      <p>
         {{ newMsg }}
      </p>
      <p> {{ title }} </p>
    </div>
  </template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /* 
     面试题:data选项为什么是函数?
      1. 组件是一个整体,那么它的数据也应该是独立的,函数形式可以给一个独立作用域
      2. 返回值为什么是对象呢?
          - Vue的特点是深入响应式,data选项要做数据劫持【 es5的Object.defineProperty的getter和setter设置 】
  */
  Vue.component('Hello',{
    template: '#hello',
    data () {
      return {
        msg: 'Vue.js',
        title: ''
      }
    },
    watch: {
      msg ( ) {
        this.title = this.msg 
      }
    },
    methods: {
      handler () {
        alert('方法')
      }
    },
    computed: {
      newMsg: {
        get () {
          return this.msg.split('').reverse().join('')
        }
      }
    } 
  })
  new Vue({
    el: '#app'
  })
</script>
  • 组件的嵌套
- 全局嵌套
<body>
  <div id="app">
  	<Father></Father> 
   <!--  
     直接这么写是不行的
    <Father>
      <Son></Son>
    </Father> 
   -->
  </div>
  <template id="father">
    <div>
      <h3> father </h3>
      <hr>
      <Son/>
    </div>
  </template>
  <template id="son">
    <h5> son </h5>
  </template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /* 组件之间的嵌套要将子组件以标签化的形式放在父组件的模板中使用 */
  Vue.component('Father',{
    template: '#father'
  })
  Vue.component('Son',{
    template: '#son'
  })
  new Vue({
    el: '#app'
  })
</script>
- 局部嵌套
<script>
  new Vue({
    el: '#app',
    components: {
      'Father': {
        template: '#father',
        components: {
          'Son': {
            template: '#son'
          }
        }
      }
    }
  })
</script>
  • 组件上实现原生事件
<body>
  <div id="app">
    <Hello :name = "name" @click.native = "changeName"></Hello>
  </div>
  <template id="hello">
    <div style = "width: 100px;height: 100px;background: red;">
      <p> {{ name }} </p>
    </div>
  </template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  Vue.component('Hello',{
    template: '#hello',
    props: ['name'] // App也是一个组件(父组件)
  })
  new Vue({
    el: '#app',
    data: {
      name: 'Vue 1.0'
    },
    methods: {
      changeName () {
        this.name = "Vue 2.0"
      }
    }
  })
</script>
  • 动态组件 - 动态缓存组件
<body>
  <div id="app">
    <select name="" id="" v-model = "val">
      <option value="father"> father </option>
      <option value="son"> son </option>
    </select>
    <keep-alive :include = "val">
      <component :is = "val"></component>
    </keep-alive>
  </div>
</body>
<script src="../../../lib/vue.js"></script>
<script>
  /*
  	keep-alive 组件可以实现组件的缓存,让组件的切换能够更快 
    keep-alive 会激活两个钩子函数:activated / deactivated 
	    activated 激活,正在显示的
	    deactivated keep-alive被停用
	    include 属性表示只有name属性为 val 的组件会被缓存,(注意是组件的名字,不是路由的名字)其它组件不会被缓存
	    exclude 属性表示除了name属性为 val 的组件不会被缓存,其它组件都会被缓存
  */
  Vue.component('Father',{
    template: '<div> father </div>',
    activated () {
      console.log('father-activated')
    },
  })
  Vue.component('Son',{
    template: '<div> son </div>',
    activated () {
      console.log('son-activated')
    },
  })
  new Vue({
    el: '#app',
    data: {
      val: 'Father'
    },
    activated () {
    /* keep-alive组件专用 */
      console.log('inactived')
    },
    deactivated () {
    /* keep-alive组件专用 */
      console.log("deactivated")
    }
  })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值