vue2基础使用(1)

重新补一下vue2的基础使用,对之前掌握的使用方法进行下回顾和查漏补缺

数据与方法

  • 教程参考
  • html:
    1
    2
    3
    <div id="app">
    {{ message }} <!-- 数组插值 -->
    </div>
  • js写法1:
    1
    2
    3
    4
    5
    6
    var app = new Vue({
    el: '#app', // 绑定DOM对象
    data: { // 给DOM对象中的数组插值赋值
    message: 'Hello Vue!'
    }
    })
  • js写法2:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var data = { // 给DOM对象中的数组插值赋值
    message: 'Hello Vue!'
    }
    var app = new Vue({
    el: '#app', // 绑定DOM对象
    data: data
    })
    // 修改app.message和data.message都可以改变DOM对象中message值
    // 注意:如果想要响应式的变量一开始为空,则需要提前在data中设置空值,new了Vue实例以后才往data中新增的属性是不具备响应式的

Object.freeze()

  • Object.freeze()阻止修改现有的 property,也意味着响应系统无法再追踪变化
  • 例子

truthy(真值)

  • js中将被转换为 true 的值
  • MDN
  • if ({})if ([])都是truthy,即都将被转换为 true

自定义组件上使用 v-for要自己传递prop

  • 任何数据都不会被自动传递到自定义组件里
  • 列表渲染

自定义组件在js里写

1
2
3
4
5
6
7
8
9
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})

命名规范

自定义事件名用-

  • 参考文档
  • 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 **v-on 事件监听器在 DOM 模板中会被 自动转换为全小写 (因为 HTML 是大小写不敏感的)**,所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
  • 因此,我们推荐你始终使用 短横线(kebab-case) 的事件名

子组件命名、引用、使用

  • 总结:
    • 子组件 命名 与 引用 要么始终以大写字母开头(PascalCase),要么始终-连接(kebab-case)
    • 无论使用哪种方式命名与引用,组件的 使用方式 都是短横线(类似<list-item>
  • 常见使用:
    1
    2
    3
    components :{ListItem} // 命名 ListItem 大写字母开头/短横线
    import ListItem from 'xxx.vue' // 引用 大写字母开头/短横线
    <list-item>// 使用组件 短横线

模板语法

  • 除了插值(双大括号)直接显示变量值之外的使用方法
  • 双大括号还可用于显示js表达式的最终值例子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <div id="app">
    {{5+5}}<br> <!-- 10 -->
    {{ ok ? 'YES' : 'NO' }}<br> <!-- YES -->
    {{ message.split('').reverse().join('') }} <!-- BOONUR -->
    <div v-bind:id="'list-' + id">菜鸟教程</div> <!-- 菜鸟教程 -->
    </div>

    <script>
    new Vue({
    el: '#app',
    data: {
    ok: true,
    message: 'RUNOOB',
    id : 1
    }
    })
    </script>
  • 属性值可以使用{js表达式} 通过data中是变量判断是否使用class类的例子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <div id="app">
    <label for="r1">修改颜色</label><input type="checkbox" v-model="use" id="r1">
    <br><br>
    <div v-bind:class="{'class1': use}">
    v-bind:class 指令
    </div>
    </div>

    <script>
    new Vue({
    el: '#app',
    data:{
    use: false
    }
    });
    </script>

vm.$set

  • 文档
  • vm.$set( target, propertyName/index, value )设置对象/数组

ref可操作原生DOM

  • 文档
  • this.$refs.refName
    1
    2
    <!-- 父组件调用子组件时设置ref -->
    <select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/>

父子组件传值

父组件向子组件传值

  • 父组件在调用子组件时传值
    1
    2
    <!-- 父组件中,select-form-2是子组件 -->
    <select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/>
  • 子组件在data()中通过props取值,注意要以对象的形式,不是数组形式
    1
    2
    3
    4
    5
    6
    7
    // 子组件js中
    props: {
    defaultShopName: {
    type: Number,
    required: false,
    default: 0,
    },

子组件向父组件传值【重点】

  • 文档参考
  • 子组件位置components/OrderSalesRetrunDetail/select-form-2.vue,父组件pages.index.report-management.test.vue
  • 子组件用this.$emit(“自定义事件名”,值)自定义事件向父组件传数据
    1
    2
    3
    4
    5
    6
    // 子组件js中
    methods: {
    onSubmit() {
    this.$emit('callback', '123')
    },
    },
  • 父组件调用子组件时,通过自定义的事件@自定义事件名="函数名"(切记函数名无()否则无法传值到函数中)获取子组件传的值
    1
    2
    <!-- 父组件中,select-form-2是子组件 -->
    <select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/>
    1
    2
    3
    4
    5
    // 父组件中js
    methods: {
    getCallback(res){
    console.log(res);
    },

子组件获取调用父组件函数后的返回值

  • 父组件中+子组件中用emit的参数3(一个函数)来接收返回值returnVal
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 父组件中(参数1:子组件传来的参数a;参数2:传给子组件的值b)
    DadFn(a, callback){
    // ...
    callback(b)
    }

    // 子组件中
    // 注意调用父组件函数后的返回值是val,子组件中获取的returnVal需要提前定义
    let returnVal = []
    // emit的参数1:父组件函数名;参数2:传给父组件函数的参数;参数3:获取父组件函数的返回值
    this.$emit('DadFn', a, val => { returnVal = val })

  • [(参考文章1)[https://www.cnblogs.com/shenpeng/p/13731274.html]、[参考文章2](https://blog.csdn.net/u013795975/article/details/106335573)]

v-model的妙用(绑定父子组件的值)

  • 参考文档
  • 目的:直接在子组件中快速修改父组件中的某一个值
  • 用途:希望父组件中的值与子组件值绑定的情况
  • 父组件中调用子组件时使用v-model给子组件传值<子组件 v-model = "父组件的值"/>
  • 子组件中可通过value拿到v-model传递的值,也可通过this.$emit('input',传递去改v-model值的值)修改父组件的值。
    • 也可以在子组件中使用model.prop给value 重命名model.event给input 重命名
  • 注意:子组件里watch是必备的,不能直接在子组件中使用父组件传来的model值,需要改成子组件自己的value。
    • 如果没有watch,则子组件内的value不允许修改,只做展示
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      // ---父组件中---
      <子组件名 v-model="confirmValue" />

      // ---子组件中---
      data() {
      return { value: "", }
      },
      // 【重点】model重命名(和data同级)
      model: {
      prop: 'modelValue',
      event: 'input'
      },
      props: {
      modelValue: { // 父组件的confirmValue,原本是value,但和子组件重名了,故在model.prop里重命名为modelValue
      type: String,
      default: ''
      },
      },
      // 注意:watch这里是必备的,不能直接在子组件中使用父组件传来的model值,需要改成子组件自己的value
      watch: {
      modelValue(val) { // 父组件传来的值变化时
      this.value = val // 改变子组件的value
      },
      },
      methods:{
      change(){ // 某事件函数
      ...
      this.$emit('input',this.value) // 用子组件value改变父组件v-model中定义的confirmValue
      },
      }

相似的:xx.sync

  • 文档
    1
    2
    3
    4
    5
    6
    7
    8
    常规用法:
    <text-document
    v-bind:title="doc.title"
    v-on:update:title="doc.title = $event"
    ></text-document>

    简写:
    <text-document v-bind:title.sync="doc.title"></text-document>
  • :timeEnd.syncv-model用法基本没有区别
    • 父组件使用v-model=a后,子组件使用this.$emit('input',改变父组件v-model中a的值)
    • 父组件使用:a.sync后,子组件使用this.$emit('update:a',改变父组件中a的值)
  • 父组件可以同时使用:timeEnd.syncv-model传递不同的值给子组件

同时设置多个 prop

  • 有多个需要绑定值的属性时,可传入一个对象v-bind.sync="doc",这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器(搭配v-on的对象语法使用效果更加)

    v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

    • 应该就是说,doc对象在conputed或data又或者methods里定义才行,在v-bind里写有可能解析的时候被拆的分崩离析就无法正常工作了
      1
      2
      3
      4
      5
      6
      7
      8
      常规用法:(updateDocTitle是方法名,v-on可接收对象)
      <text-document
      v-bind="doc"
      v-on="{ update:doc.title: updateDocTitle, update:doc.footer: updateDocFooter }"
      ></text-document>

      简写:
      <text-document v-bind.sync="doc"></text-document>

修饰符

事件修饰符

  • 事件修饰符
  • 修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定
  • 例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()
    1
    <form v-on:submit.prevent="onSubmit"></form>

表单输入绑定(v-model)修饰符

  • 总结:.trim-过滤首尾空白,.lazy-失去焦点更新,.number-数字类型
  • .trim: 去掉输入框内首尾空格,实际绑定的input会禁止输入空格
  • .lazy: 在默认情况下,v-model 在 input 事件中同步输入框的值与数据 (除了 IME 部分),但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步
  • .number: 可以将输入的数据转换为Number类型,否则虽然你输入的是数字,但它的类型其实是String(比如数字输入框)
    • 会限制只允许输入数字
    • 不允许输入小数点/负号