欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Vue初识:一个前端萌新的总结

程序员文章站 2022-08-06 10:09:00
一、前言 时隔三年,记得第一次写博客还是2015年了,经过这几年的洗礼,我也从一个后端的小萌新变成现在略懂一点点知识的文青。如今对于前端的东东也算有一知半解,个人能力总的来说,也能够独立开发产品级项目吧。至于为什么会前端的东西,估计学.NET的人应该大部分都懂些,之前自己搭建过一套框架,但觉得现在的 ......

一、前言

  时隔三年,记得第一次写博客还是2015年了,经过这几年的洗礼,我也从一个后端的小萌新变成现在略懂一点点知识的文青。如今对于前端的东东也算有一知半解,个人能力总的来说,也能够独立开发产品级项目吧。至于为什么会前端的东西,估计学.NET的人应该大部分都懂些,之前自己搭建过一套框架,但觉得现在的时代趋势吧,前后端分离是主流,再加上想借这次机会改变部门的开发方式,所以就打算改造一下。

  本文仅为个人心得,从实践项目出发,不讲理论,适合萌新学习,如果有说错了欢迎大家在评论区指出,共同进步,哈哈。

  这里假定大家的前端技术都达到了熟练使用JavaScript、Html和CSS的地步。

 

二、起步

  2.1 Vue入门需要知道的一些基础知识

  1. 这是一套用于构建用户界面的MVVM框架,但有些时候却又无法实现双向绑定(需要一些特殊处理,比如子组件更新父组件的属性)
  2. 非常容易入门,使用OO思想会让你更加发现这套框架在应用上的简单(组件化开发)
  3. 使用模板语法(Template),在使用的时候就像写html一样
  4. Vue有两种声明形式(全局、区域)后面会解释
  5. Vue这款框架十分霸道,使用之后会发现以前用的Jquery/Bootstrap会被排斥得很厉害(可是我又很不想放弃这两者一些生态里的东西,怎么办?毕竟Vue现在的生态还不是很好。答案是:不使用vue-cli构建的时候,只能在它的生命周期中创建使用,勉强兼容,但是有代码洁癖的话就会很不舒服。如果使用vue-cli构建之后,通过NPM就可以获取bootstrap-vue、fontawesome-vue等针对vue开发的新东东)
  6. 萌新入门,还是按照官方说法,先不要用vue-cli去构建项目(这种感觉对于我这种后端小渣渣是最为清楚,使用之后瞬间感觉前端这几年变得极度复杂,貌似这样显得逼格更高?)
  7. 下面就让我们一步步从简单的html+js引用的方式使用vue吧,基础的使用方式在里都有,此处就不再对那些内容重写一遍了。

 

  2.2 Vue页面级组件的基本结构(每一个页面对象都大同小异,根据实际需要取舍部分对象属性即可,记住了就懂了一半)

  

var Test = new Vue({
    el: '#test-vm',    // 此处对应html页面中一个id=test-vm的元素,必须指定
    data: {
        id: 0         // data是组件内部维护的属性对象
    },
    computed: {
        newid: function () {
            return this.id === 0  // 此处返回一个boolean值,computed是计算属性的集合体,里面每一个属性都是function,因此数据更新时,也会更新对应的视图数据
        }
    },
    methods: {
       Test: function () {
          // 方法1内容
       },
       Test2: function () {
         // 方法2内容
      }
    },
    components: {
        'test-input': TestInput    // components 是子组件容器,在这里引入其他要使用的子组件,多个用,分隔。格式为:'组件名':组件对象 (组件名可以自定义,但要和html对应)
    },
    created: function () {
        // 组件生命周期,此时可以对实例的数据做一些操作,比如用ajax请求数据
    },
    mounted: function () {
       // 组件生命周期,执行到这里说明整个组件已经渲染完成,在这里你可以执行一些其他操作,比如实例一个bootstrap-datetimepicker组件
    },
    template: '<div>这是测试内容</div>'  // 这是组件的模板,也就是这里的内容会被加载在上面el指定的#test-vm元素中,这里要注意的是template必须只有一个root。
                                       // 你不能写成<div>标题内容</div><div>主体内容</div>,只能加多一层<div><div>标题内容</div><div>主体内容</div></div>

});  

  2.3 Vue组件的基本结构(每一个组件都大同小异,根据实际需要取舍部分对象属性即可)

    

// 这是全局声明组件,这样每一个引用的组件的components都会默认添加这个组件,就不需要再像上面一样手动添加
// 局部声明格式为: var TestInput = { 此处的内容和组件声明一样 }
// 此处实现了一个文本框(多行/水印/密码模式/最大值限制/默认值/禁用)
Vue.component('test-input', {
    props: ['type','placeholder','disabled','multiple', 'maxlength', 'val'],
    data: function () {
     // 此处的data和页面级组件的data不同,这里是一个function,需要把内部维护的属性通过对象的方式return
        return {
            value: '',
            isError: false,
            errorMsg: ''
        }
    },
    computed: {
        contentLength: function () {
            return this.value.length;
        },
        typeObject: function () {
            return this.type ? this.type : 'text';
        }
    },
    watch: {
        // watch是监视器,可以监视组件内部的属性变化并做出相应处理,属性命名必须和data或者computed中的属性一致
        contentLength: function (val, oldVal) {
            if (this.maxlength && val > this.maxlength) {
                this.value = this.value.substring(0, this.maxlength);
            }
        },
        val: function (val, oldVal) {
            if (val) this.value = val;
        }
    },
    created: function () {
        if (this.val) this.value = this.val;
    },
    template: '<div class="input-box">' +
                '<input :disabled="disabled" :type="typeObject" class="form-control"  v-if="!multiple" :placeholder="placeholder" v-model="value"/>' +
                '<textarea :disabled="disabled" class="form-control" v-else  :placeholder="placeholder" v-model="value"></textarea>' +
                '<div v-if="isError">' +
                '<div>{{errorMsg}}</div>' +
                '<div class="arrow"></div>' +
        '</div>' +
        '<i class="fas fa-exclamation-circle fa-lg" v-if="isError" ></i>' +
        '<span class="count" v-if="maxlength">{{value.length}}/{{maxlength}}</span>'+
        '</div>'
});

   2.4 子组件更新父组件属性与父组件控制子组件内容

    

// 父组件改变子组件的内部属性
// 父组件内部的属性通过子组件的props属性进行传递,当父组件属性值发生改变时,会相应更新子组件视图,如:
// 必须先声明子组件,才能声明父组件
var TestInput = { 
    props: ['type'],
    template:'<input :type="type" ></input>'
}

var view = new Vue({
  el:'#test-vm',
  data:{
      inputType: 'text'
  },
  methods:{
      visibleInputText: function () {
          // 该方法用于转换子组件文本框的文本类型(密码/明文)
          this.inputType === 'text'? this.inputType = 'password' : this.inputType = 'text'
      }
  },
  components:{
     'test-input':TestInput
  },
  template:'<div>'+
                  '<button @click="visibleInputText">点击我修改文本框类型   </button><test-input :type="inputType"></test-input>'+
                '</div>'
})

 

// 子组件更新父组件中的属性
// 子组件通过$emit来将内部的属性传递给父组件中的方法,并通过父组件内部方法来实现更新。简单点来说就是一个委托方法:
// 1.子组件内部声明委托方法名以及将数据传递给$emit(变相地给自己增加了一个隐式方法)
// 2.父组件通过绑定子组件声明的委托方法名把自己的方法传递给子组件
var TestInput = {
   data: function () { 
       return {
          value: ''
       }
   },
   methods: {
       textChange: function () {
           // $emit 接受[委托方法名,传递参数]两个参数
           // 所谓的委托方法名,其实就是父组件中给子组件添加绑定的方法名称
           // 委托方法是一个单参数方法
           this.$emit('ontextchange',this.value)
      }
   },
   template:'<input v-model="value" @onchange="textChange"></input>'
}

var parent = new Vue({
    el: '#text-vm',
    data: {
       childContent: ''     // 子组件文本框的值
   },
   methods: {
       onTextChange: function (value) {
            // 该方法就是委托的方法,value为子组件传递的参数
            console.log(value)
this.childContent = value } }, components: { ‘test-input’: TestInput }, template: '<test-input @ontextchange="onTextChange" ></test-input>' // 上面的ontextchange必须和子组件在$emit中声明的一致 })