IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue笔记(四) [自定义指令、组件] -> 正文阅读

[JavaScript知识库]vue笔记(四) [自定义指令、组件]

自定义指令 v-

作用: 对普通 DOM 元素进行底层操作;

全局自定义指令; Vue.directive( 指令名, 配置对象/回调函数)

局部自定义指令; directives:{指令名,配置对象/回调函数}


组件

组件的定义——实现应用中局部功能代码和资源的集合;

  • 全局组件 Vue.component(); 可以在多个vue实例中使用;
  • 局部组件 components:{ }; 只能在在注册的vue实例中使用;
  1. 创建组件构造器; 传入一个配置对象; 这个对象除了el配置项,其他的都有;
  2. 注册组件; 两个参数, '组件标签' 和 构造器名字
  3. 使用组件; 在挂载点中使用;
<body>
    <div id="app">
        <!-- 使用全局组件 -->
        <cpn></cpn>
        <!-- 使用局部组件 -->
        <cpn2></cpn2>
    </div>

    <script>
        // 创建组件的构造器
        const cpnC = Vue.extend({
            template:
            `<div>
                <p>你好</p>
                <h3>hello</h3>
            </div>
            `
        })
        // 注册全局组件
       Vue.component('cpn',cpnC)

        const vm = new Vue({
           el:'#app',
           data:{},
           methods:{},
        //    注册局部组件
           components:{
               // 对象的key可以用引号,也可以不用
               'cpn2':cpnC,
            //    cpn2:cpnC
           }
        });
    </script>
</body>

注意:

  • 调用Vue.extend()方法 - 创建组件构造器
  • 调用Vue.component()方法 - 注册组件
  • 在Vue实例的作用范围内 - 使用组件
  • 组件构造器中的template中可以用引号(不能换行),用反引号(字符串模板可以换行);要有一个根标签<div>包裹;
  • 在vue实例的配置项,components:{ } 注册局部组件 ;
  • 对象的key值,可以加引号(当做字符串),也可以不加(变量)
  • 对象字面量的增强写法:? 函数名: funtion() 可以省略:function ;
  • 对象的字面量增强写法: 对象的属性名和属性值一样,是个变量可以省略一个;

父子组件

子组件在父组件中注册,在父组件中使用;

在父组件的构造器对象的配置项: coponents:{ } 中注册子组件,;在template模板中使用组件;

<body>
    <div id="app">
      <!-- 使用父组件B,包含子组件A -->
      <cpn-b></cpn-b>
      <hr>
      <!-- 在root根组件中注册组件A,直接使用子组件A -->
      <cpn-A></cpn-A>
    </div>

    <script>
      // 创建子组件构造器 cpnA
      const cpnA = Vue.extend({
        template:
        `
        <div>
          <h5> 我是子组件 </h5>
        </div>
        `
      })
      // 创建父组件构造器 cpnB
      const cpnB = Vue.extend({
        template:
        // 在父组件的tempalte模板中使用子组件
        `
        <div>
          <h3> 我是父组件 </h3>
          <cpn-a></cpn-a>
        </div>
        `,
        // 在父组件的components中注册子组件
        components:{
          'cpn-a':cpnA
        }
      })

        const vm = new Vue({
           el:'#app',
           data:{},
           methods:{},
           // 注册局部组件 父组件
           components:{
             'cpn-b':cpnB,
             // 想直接单独使用子组件A,在根组件root组件中注册
             'cpn-a':cpnA
           }
          
          });
    </script>
</body>

组件的语法糖注册方法

把创建组件构造器Vue.extend()中的配置对象{ } ,直接写到注册组件中去;省略Vue.extend()书写;

构造器名字,直接写成一个对象;这个对象就是之前构造器传入的配置对象;

但Vue会仍会自动的将此对象给Vue.extend()

// 内部会自动调用Vue.extend()
<body>
    <div id="app">
      <!-- 使用全局组件 -->
      <cpn-a></cpn-a>
      <hr>
      <!-- 使用局部组件 -->
      <cpn-b></cpn-b>
    </div>
    <script>
      // 注册全局组件
      Vue.component("cpn-a",{
        template:'<div><h4>我是全局组件</h4></div>'
      })
        const vm = new Vue({
           el:'#app',
           data:{},
           methods:{},
           // 注册局部组件
           components:{
             "cpn-b":{
               template:`
               <div>
                 <p>我是局部组件</p>
                </div>
                `
             }
           }
        });
    </script>
</body>

组件构造器的配置对象中的template模板的抽离写法:?

template模板写:? '选择器';

template便签内写:? 选择器; 需要有个根标签<div>包裹;<div>内写需要的模板;

template标签不会被渲染,

<body>
    <div id="app">
      <!-- 使用组件 -->
      <cpn></cpn>
    </div>
    <!-- template模板的抽离写法 -->
    <template id="aaa"> // 选择器
      <div>
        <h3>模板的分离写法</h3>
      </div>
    </template>
    <script>
      // 注册组件
      Vue.component('cpn',{
        template:'#aaa' //选择器
      })
        const vm = new Vue({
           el:'#app',
           data:{},
           methods:{}
        });
    </script>
</body>

组件使用数据

子组件不能直接使用父组件中的数据;

vue实例也是一个父组件,root根组件;

组件可以使用自己组件内的data配置项中的数据;

组件的data属性,必须是一个函数,且返回一个对象;

组件也有自己的data属性(在vue.extend()的配置对象中),必须是一个函数,且返回一个对象;

<body>
  <div id="app">
    <!-- 使用组件 -->
    <cpn></cpn>
  </div>
  <template id="aaa">
    <div>
      <!-- 使用组件data中的数据 -->
      <h3>{{msg}}</h3>
    </div>
  </template>
  <script>
    // 注册组件
    Vue.component('cpn', {
      template: '#aaa',
      // 必须是一个函数,且返回一个对象
      // 对象的字面量增强写法 省略 :function
      data() {
        return {
          msg: '组件的data必须是一个函数'
        }
      },
      // data:function () {
      //   return{
      //     msg:"组件的data必须是一个函数,且返回一个对象"
      //   }
      // }
    })
    const vm = new Vue({
      el: '#app',
      data: {},
      methods: {}
    });
  </script>
</body>

父子通信

父组件通过props向子组件传递数据 [props=> property 属性]

方法一: ? props:[ ]

  • 注册组件的配置对象中的添加props配置项,是一个数组;
  • 数组中的字符串是变量, 用来接受父组件传递过来的数组;
  • 使用组件时,用过v-bind属性绑定, 用props中的变量接受父组件中的数据;
  • 在模板中使用这些props[ ]中的变量;
<body>
  <div id="app">
    <!-- 使用子组件,父组件是vue实例 -->
    <!-- 通过v-bind绑定props中的变量;
       接收父组件传递给子组件的数据 -->
    <cpn :cmsg="msg" :cmovies="movies"></cpn>
  </div>
  <template id="aaa">
    <div>
      <!-- 使用父组件传递过来的数据 -->
      <h2>{{cmsg}}</h2>
      <ul>
      <!-- 使用父组件传递过来的数据 -->
        <li v-for="item in cmovies">{{item}}</li>
      </ul>
    </div>
  </template>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        msg: '你很棒',
        movies: ['西游记', '三国演义', '红楼梦', '水浒传']
      },
      methods: {},
      // 注册局部组件
      components: {
        // 组件中的对象的key(属性名) 就是组件标签名, 可以加引号,也可以不加
        'cpn': {
          template: '#aaa',
          // 数组中的字符串就是变量,
          props: ['cmsg','cmovies'],
          data() {
            return {
            }
          }
        }
      }
    });
  </script>
</body>

方法二:? props:{ }

  • props是一个对象时, 可以对接受的变量进行类型限制;
  • 这些变量是一个对象,required: true 表示这个变量必传;
  • default 是当没有数据接收时,显示默认值;
  • 当数据类型是数组或对象时, 默认值必须是一个函数,且return{ 默认值 }

props的数据类型验证:

 props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)

    propA: Number,// 要求这个变量的数据类型是Number;

    // 多个可能的类型
    propB: [String, Number],//数据类型是字符串或数字类型;

    // 必填的字符串
    propC: {
      type: String, // 数据类型是字符串类型,且这个变量必须使用;
      required: true
    },

    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100  // 默认值,当没有接受数据时,默认值显示
    },

    // 带有默认值的对象或数组
    propE: {
      type:[Object,Array],
      // 当数据类型是对象或数组时, 默认值必须函数获取且 return {默认值};
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:27:49  更:2021-08-24 15:30:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 4:51:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计