Vue组件模板--深入浅出

组件模板

如果仅仅具备前面的知识,那你的前端开发与Jquery、甚至原生Javascript形式的开发别无二样,Vue真正的强大之处在于,它不仅彻底实现了网页组件的模块化,还提供了大量实用且美观的模块
基础组件
W3C命名规范:字母全小写,包含连字符
核心语法

// 组件定义(组件应定义在脚本内容的前方)- 参数1:组件名	参数2:组件逻辑 
Vue.component('cmp-a', {		// 组件名:cmp-a
    props: [{},],               // 组件属性
    template: '',   			// 组件内容(只能有一个"根")
    methods:{},					// 组件函数库
    data:{}						// 组件的变量
    // ,...
  }
);

简单样例

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
    Vue.component('cmp-a', {
            props: ['attr1'],
            template: '
  • {{ attr1 }}
  • '
    } ); // .. </script>
    <div id="demo">
        <!-- 值传递:message ~ x → attr1 → <cmp-a> -->
        <cmp-a 
               v-for="x in message" 
               v-bind:attr1="x"
               v-bind:key="x.id">		<!-- 为每个组件提供一个“key” -->
        </cmp-a>
    </div>
    
    <script>
        // ViewModel
        let vue = new Vue({
            el: '#demo',
            data: {
                message: [
                      { id: 0, text: 'A' },
                      { id: 1, text: 'B' },
                      { id: 2, text: 'C' }
                ]
            }
        });
    </script>
    

    说明:<组件标签>会被加载替换成其定义时的`组件内容

    生存范围

    全局作用
    Vue.component()方式定义的组件是全局可用的,如果打包程序不够细节,就意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中,用户需要无谓的下载。
    局部作用

    // 手动导入局部组件A和C,并存到组件库
    import ComponentA from './ComponentA'
    import ComponentC from './ComponentC'
    
    export default {
      components: {
        ComponentA,
        ComponentC
      },
      // ...
    }
    
    // 自动导入需要的组件(Vue CLI 3+)
    // https://cn.vuejs.org/v2/guide/components-registration.html#%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6%E7%9A%84%E8%87%AA%E5%8A%A8%E5%8C%96%E5%85%A8%E5%B1%80%E6%B3%A8%E5%86%8C
    

    属性验证

    Vue.component('my-component', {
      props: {
        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型检查验证)
        propA: Number,
        // 多个可能的类型
        propB: [String, Number],
        // 必填的字符串
        propC: {
          type: String,
          required: true
        },
        // 带有默认值的数字
        propD: {
          type: Number,
          default: 100
        },
        // 带有默认值的对象
        propE: {
          type: Object,
          // 对象或数组默认值从一个工厂函数获取
          default: function () {
            return { message: 'hello' }
          }
        },
        // 自定义验证函数
        propF: {
          validator: function (value) {
            // 这个值必须匹配下列字符串中的一个
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
        }
      }
    })
    

    自定义属性的继承

    Vue.component('base-input', {
      inheritAttrs: false,
      //...
    })
    

    跨级传递数据
    如果A组件内嵌套着B组件,B组件内嵌套着C组件,那么A传递数据到C的办法是在B中:

    <ComponentC v-bind="$attrs" />
    

    文件组件

    命名规范:文件名采用驼峰命名,导入时如果以驼峰命名则在使用时对应的是"-"式

    import AsideList from "./components/List";
    ...
    	components: {Test, AsideList, Main, Login}
    

    基本语法

    <template>								// 组件内容
      <p>{{ greeting }} World!</p>
    </template>
    
    <script>
    module.exports = {						
      data: function() {					// 组件的变量
        return {
          greeting: "Hello"
        };
      }
    };
      export default {						// 组件暴露
        name: 'Xxx',						// 组件名字【可选】
        components: {}						// 组件库
      }
    </script>
    
    <style scoped>							// 组件样式:scope指仅作用于当前
    p {
      font-size: 2em;
      text-align: center;
    }
    </style>
    

    return

    (1) 返回对象,当前组件可引用来进行初始化,作用域仅限于当前组件!

    (2) rules对象为组件配置监听,作用域仅限于当前组件!
    集成样例:

    </template>
    <script>
    import ChildComponents from './ChildComponents.vue' // 提前引入子组件
    import Cookie from '../lib/cookie.js'  			// 引入公共Js脚本或类库
    
    export default {
      data () {  						//组件的私有数据(基于函数来返回私有对象)
        return {
          title: '...',
          firstName: '...',
          lastName: '...',
        }
      },
      props: ['age'],					// 父组件传递过来的数据(数组或对象)
      computed: {						// 计算属性
          函数名: function (){}
      },						
      watch: {							// 监听
        title (preVal, newVal) {
            console.log(`改变之前的值:${preVal};改变之后的值:${newVal}`)
        }
      },
      methods: {},						// 函数集
      beforeCreated () {}				// 各种钩子函数...
    }
    </script>
    
    
    <style lang="scss" scoped>			// CSS样式:scoped省略后会应用到全局
    @import "../base/reset.css";		// 支持import语法引入css文件	
    ...
    </style>
    

    插座插槽

    为了拼接组合多个组件,Vue提出了插座插槽的概念,巧妙的是,Vue通过对插座插槽里的组件进行拔插就能实现局部更新(后续)!
    编写组件

    Vue.component('cmp-a', {                      // 组件名:cmp-a
            props: ['a_attr1'],                   // 属性名:a_attr1
            template: '
  • {{ a_attr1 }}
  • '
    // 组件内容 } ); Vue.component('cmp-b', { // 组件名:cmp-b props: ['b_attr1'], // 属性名:b_attr1 template: '
  • {{ b_attr1 }}
  • '
    // 组件内容 } );

    编写插座

    Vue.component('slot-x', {	// 组件名:slot-x
            template:			// 组件内容:插座=[slot-a]+[slot-b]+..
                '
    \ \
      \ \
    \
    '
    } );

    编写视图模型

    let vue = new Vue({
        el: '#demo',
        data: {
            msg1: "Alpha",
            msg2: ["A", "B", "C"]
        }
    });
    

    使用插座

    <div id="demo">
      <!-- 插座:<slot-x>的作用是在此处放置一个插座 -->
      <slot-x>
        <cmp-a slot="slot-a" :a_attr1="msg1"></cmp-a>
        <cmp-b slot="slot-b" v-for="ele in msg2" :b_attr1="ele"></cmp-b>
      </slot-x>
    </div>
    

    组件事件

    组件调用自定义事件的函数其实分为两种,一个是调用组件内部的函数,另一个是调用视图模型的函数
    组件函数

    // 1、编写组件
    Vue.component('cmp', {                          // 组件名:cmp
            props: ['attr1'],                       // 属性:attr1
            template:                               // 组件内容
                '
  • {{ attr1 }}
  • '
    , methods: { // 函数:emit_remove() emit_remove: function () { alert("你点击了删除!"); } } } );

    说明:v-on:click事件调用属性可以简写为@click,二者作用完全相同!
    使用组件

    <div id="demo">
      <cmp slot="slot-b" v-for="(ele, index) in msg" :attr1="ele"></cmp>
    </div>
    

    模型函数

    由于ViewModel和组件分别属于两个访问域,所以组件内部并不能直接访问ViewModel,这样就一来,组件事件函数就不能修改视图模型中的数据。不过,Vue巧妙地借助事件分发解决了问题。

    所谓分发,指当触发组件的事件函数时,this.$emit()语句又会触发属性所绑定的函数,就像是一次触发被分给了两个函数!
    编写组件

    Vue.component('cmp', {                          // 组件名:cmp
            props: ['attr1', 'del'],                // 属性
            template: '
  • {{ attr1 }}
  • '
    , // 组件内容 methods: { // 函数 emit_remove: function (del) { // 事件分发:触发emit_remove属性所绑定的函数 this.$emit('emit_remove', del); } } } );

    编写视图模型

    let vue = new Vue({
        el: '#demo',
        data: {
            msg: ["A", "B", "C"]
        },
        methods: {
            remove: function (begin) {
                // splice(begin, len): 从指定索引开始删除数组的若干个元素
                this.msg.splice(begin, 1);
            }
        }
    });
    

    使用组件

    <div id="demo">
        <cmp slot="slot-b" v-for="(ele, index) in msg"
             :attr1="ele" :del="index" v-on:emit_remove="remove(index)"></cmp>
    </div>
    

    你可能感兴趣的:(Vue,vue,javascript,js,java,node.js)