Vue注意细节

  1. 基础
    • a. 引入vue.js<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    • b. 创建vue对象,并绑定id/类。
    • c. 插值
      //直接用{{}}
      <div> {{message}} </div>
      //计算,支持三元运算
      <div> {{num1+num2}} </div>
      //字符串中(拼接)
      <div style=" 'width: 10rem' + mystyle ">  </div>
      
    • d. $取系统的值 如:vm.$el vm.$data
  2. 指令

v-bind : 单向绑定,绑定样式(class/style/id/href/key/title/disabled),绑定props的属性

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写,用: -->
<a :href="url"></a>

v-on:绑定事件

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 用@ -->
<a @click="doSomething"></a>

v-model: 数据双向绑定 ( 绑定input、select、textarea、checkbox、radio 等表单控件的value)

<!-- 单向,修改a值,i1的value改变。而修改value,a不会改变(简单来说就是传值)-->
<input type="text" :value="a" name="i1"/>  
<!-- 双向,修改a值,i1的value改变。修改value,a改变 -->
<input type="text" v-model="a" name="i2"/>

v-once: 只执行一次性地插值
v-html: html插值(显示html加载后的效果)

  1. v-ifv-show
    v-if: 条件选择,适用于界面第一次加载时使用
    v-if是通过控制dom节点的存在与否来控制元素的显隐,条件不满足是不会加载到dom中的,更新花销更大。如下:当show为0时,只存在<div> 第一层 </div>
  <body>
        <div id="demo">
            <div v-if= "show < 2" > 第一层 </div>
            <div v-else-if = "show < 4"> 第二层 </div>
            <div v-else> 第三层 </div>
        </div>  
    </body>
    <script>
        var demo = new Vue({
          el: '#demo',
          data: {
             show: 0
          },
          methods: {
              tap: function(){
                this.show++;
              }
          }
        });
    </script>

v-show: 选择是否显示,适用于界面频繁刷新(如:点击按钮控制一个div的显隐)

    <body>
        <div id="demo">
            <div v-show = "show< 2" > 第一层 </div>
            <div v-show = "show>=2&&show<4" > 第二层 </div>
            <div v-show = "show>=4" > 第三层 </div>
            <button @click="tap()">点击</button>
        </div>  
    </body>
    <script>
        var demo = new Vue({
          el: '#demo',
          data: {
             show: 0
          },
          methods: {
              tap: function(){
                this.show++;
              }
          }
        });
    </script>

v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
当show为0时,样式为:

<div> 第一层 </div>
<div style="display: none;"> 第二层 </div>
<div style="display: none;"> 第三层 </div>
  1. mixin 混入
    简单而言就是多继承。不同方法继承,相同方法覆盖(Vue对象的方法级别最高,其他混入的mixin按先后顺序覆盖,换而言之就是最后混入的获得调用)

  2. Vue 是响应式的。data中的数据更新时会刷新整个dom(一级目录比较敏感,下级不一定能成功),Vue 不能检测数组和对象的变化

var vm = new Vue({
  data:{
    a:1
  }
})

// `vm.a` 是响应式的

vm.b = 2  // `vm.b` 是非响应式的
Vue.set(vm.someObject, 'b', 2) //单个值响应
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) //多个值响应

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
vm.items = ['x', 'b', 'c']; //全部替换,响应性的

Vue.set(vm.items, indexOfItem, newValue) //indexOfItem处的值更新为newValue
vm.items.splice(indexOfItem, 1, newValue) //在indexOfItem位置添加一个新值
vm.items.splice(indexOfItem) //删除indexOfItem到结尾处的值

vm.items.forEach((item)=>{
    Vue.set(item,"goodlist",result.data); //指定位置插入goodlist的列表
    Vue.set(item,"offset",0); //指定位置插入offset字段值为0                       
});

  1. 属性
    <body>
        <div id="demo">
            <!-- 过滤器的使用,firstName作为第一个参数传递给capitalize函数 -->
            <div v-show = "show" >  {{ firstName | capitalize }} {{lastName}} </div>
            <button @click="tap()">点击</button>

            <p v-for="(money) in list"> {{money | local(font)}}</p>
        </div>  
    </body>
    <script>
        new Vue({
            el: "#demo", //为实例提供挂载元素,该元素下被vue控制
            data: {
                firstName: 'foo',
                lastName: 'Bar',
                show: true,
                list: [10,10000, 0.01],
                font: "RMB"
            },
            props: ["content"], //父组件向子组件传值,自定义组件中常用
            methods: {
                //该属性中申明方法
                tap: function(){
                    this.show = !this.show;
                }
            },
            mounted: function(){
                // 钩子函数,挂载时调用
                console.log(2);
            },
            created: function(){
                //创建时调用,先创建再挂载,看vue的生命周期
                console.log(1);
            },
            filters:{ //过滤器
                //首字母大写
                capitalize: function (value) {
                  if (!value) return ''
                  value = value.toString()
                  return value.charAt(0).toUpperCase() + value.slice(1)
                }
                 //金额格式化
                 local: function (value, f) {
                  return value.toLocaleString()+ f;
                }
            },
            directives: {
                // 注册一个局部的自定义指令 v-focus
                focus: {
                  // 指令的定义 inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)
                  inserted: function (el) {
                    // 聚焦元素
                    el.focus()
                  }
                }
            },
            computed: {
                //计算属性,当数据发生变化时才调用,否则直接调用缓存。提升性能,可使用get/set函数,必须有返回值
                //fullName可作为一个属性直接使用
                fullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            },
            watch: {
                //监测变化。监听函数
                firstName: function (val) {
                    this.fullName = val + ' ' + this.lastName
                },
                lastName: function (val) {
                    this.fullName = this.firstName + ' ' + val
                }
            }
        });
    </script>
  1. 生命周期

    生命周期

    createdmounteddestoryed只调用一次,updated会多次调用。

  2. 父组件与子组件的互调
    a. 父组件向子组件传值

//main.js 全局引入组件(也可以局部引入,这边图个方便)
import cuTest from './components/test.vue'
Vue.component('test',cuTest)

//父组件
<test :num="10"></test>

//子组件
<template>
    <button @tap="ontap"> {{ num }} 点击 </button>
</template>

<script>
    export default {
        data() {
            return {};
        },
        name: 'test',
        props: {
            num:{
                type: Number,
                default: 0
            },
        },
    }
</script>

通过v-bind单选绑定,传递num值。
如果想要在子组件修改传递的num,使用this.num++类似的修改方法是会报错的。这时需要这样操作,修改子组件:

<template>
    <button @tap="ontap"> {{ n }} 点击 </button>
</template>

<script>
    export default {
        data() {
            return {
                n : 0,
            };
        },
        name: 'test',
        watch: {
            num(newV,oldV) {
                console.log(newV,oldV);
                this.n = newV;
            },
        },
        mounted() {
            this.n = this.num;
        },
        props: {
            num:{
                type: Number,
                default: 0
            },
        },
        methods: {
            ontap() {
                this.n = this.num + 100;
            }
        }
    }
</script>

使用一个新的n接收num数据,通过watch监听num的数据变化

b. 子组件向父组件传值
我们将接收的num修改后再传给父组件

//子组件
ontap() {
  this.n = this.num + 100;
  this.$emit('ontap', this.n);
}
//父组件
<template>
  <test :num="num" @ontap="onChange"></test>
</template>
<script>
    export default {
        data() {
            return {
                num: 10,
            };
        },
        mounted() {
            let _this = this;
            setTimeout(function(){
                _this.num = 100;
            },3000);
        },
        methods: {
            onChange(num){
                console.log(num);
            }
        }
    }
</script>

通过this.$emit向父组件传值,父组件通过@ontap(注意和emit的第一参数函数名一致)绑定onChange方法。
接收多个参数时

//和之前对应
this.$emit('ontap', a, b, c);
onChange(msg) {
    let a = msg[0];
    let b = msg[1];
    let c = msg[2];
}

c. sync 简化
在父组件中添加sync修饰,会自动在父组件中创建update:num(对应.sync的前值)的事件,父组件就不需要再去写接收方法,去掉@ontap="onChange"

<test :num.sync="num" ></test>

在子组件中

this.$emit('ontap', this.n); => this.$emit('update:num', this.n); //替换

这样就能自动同步父与子组件的参数值了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,321评论 6 543
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,559评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,442评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,835评论 1 317
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,581评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,922评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,931评论 3 447
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,096评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,639评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,374评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,591评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,104评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,789评论 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,196评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,524评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,322评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,554评论 2 379