Vue 笔记

目录

Vue 渲染

插值表达式

v-text和v-html指令

v-if和v-show指令

Vue  v-for 列表渲染

Vue 事件绑定 v-on指令

Vue 事件修饰符

Vue 标签属性的赋值:v-bind指令

Vue JSON对象拷贝

Vue 表单的双向数据绑定:v-model指令

Vue 过滤器

Vue 钩子函数

Vue 组件

全局注册

局部注册

注册优化


Vue 渲染

插值表达式

数据绑定最常见的形式就是使用 {{值}}(双大括号)的文本插值:

<body>
<div id="id">
    {{a}}
    {{ff()}}
    {{up()}}
    {{xx}}
    {{zz}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
new Vue({
    el:"#id",
    data:{    //属性
        a:'abc',
    },
    methods:{    //函数
      ff(){return 2+2},
      up(){return this.a.toUpperCase()}
    },
    computed:{    //计算属性
        xx(){return 2+2},
        zz(){return this.a.toUpperCase()}
    }
})

</script>

说明:{{}}中通常是变量, 但也可以是表达式(比如 a+b) 有返回值的函数调用(函数必须加()) 计算属性不能加()

v-text和v-html指令

如果数据不是预先定义好,而是通过网络获取时,使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的 {{}} ,加载完毕后才显示正确数据,称为插值闪烁。此时,可以使用v-text代替插值表达式:

v-text指令

<div id="app">
    <h1 v-text="msg"></h1>
</div>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            msg:"hello vue"
        }
    })
</script>

如果数据中包含有HTML标签,双大括号和 v-text指令 会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用v-html指令:

v-html指令

<div id="app">
    <h1>{{msg}}</h1>
    <h1 v-text="msg"></h1>
    <h1 v-html="msg"></h1>
</div>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            msg:"<span style='color:red'>hello vue</span>"
        }
    })
</script>

v-if和v-show指令

v-if指令:  v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true 值的时候被渲染

当和 v-if 一起使用时,v-for 的优先级比 v-if 更高。

v-else  不需要表达式

限制:前一兄弟元素必须有 v-if 或 v-else-if

用法: 为 v-if 或者 v-else-if 添加“else 块”.

v-else-if   2.1.0 新增

限制:前一兄弟元素必须有 v-if 或 v-else-if

<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-show指令  另一个用于根据条件展示元素的指令是 v-show 指令。和v-if用法大致一样,不过v-show后不能跟v-else

<div id="app">
    <h1 v-show="show">
        <span style="color:green">show=true</span>
    </h1>
    <h1 v-show="!show">
        <span style="color:red">show=false</span>
    </h1>
    <button onclick="handleClick()">点我</button>
</div>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            show:true
        }
    })

    function handleClick(){
        vm.show = !vm.show;
    }
</script>

v-if 和 v-show 的区别

<div id="app">
    <h1 v-if="show">
        <span style="color:green">v-if指令</span>
    </h1>
    <h1 v-show="show">
        <span style="color:green">v-show指令</span>
    </h1>
    <button onclick="handleClick()">点我</button>
</div>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            show:true
        }
    })

    function handleClick(){
        vm.show = !vm.show;
    }
</script>

v-if 和 v-show 指令展示效果相同,但是打开开发者工具(F12或者ctrl+shift+i)查看Element面板,会发现2者的区别

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的子组件适当地被销毁和重建。当初始条件为false时,其内部组件不会渲染。

  • v-show 就简单得多,它在切换过程中,只是简单地基于 CSS 进行切换。当初始条件为false时,其内部组件也会预先渲染。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

 

 

Vue  v-for 列表渲染

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

<ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

结果:

    Foo

    Bar

在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。

 

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:

<div v-for="item of items"></div>

在v-for里使用对象    你也可以用 v-for 来遍历一个对象的 property。

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

你也可以提供第二个的参数为 property 名称 (也就是键名):

<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

还可以用第三个参数作为索引:

<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

v-for时的key属性

当我们需要更新 v-for 渲染过的元素列表时,比如向数组中添加一个新的元素。为了保证Vue正确并高效的渲染页面,官方建议我们为每项提供一个唯一 key 属性,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。key一般使用在遍历完后,又增、减数组的元素的时候更有意义。

<ul>
	<li v-for="(item,index) in items" :key="index"></li>
</ul>
  • 这里使用了属性赋值语法: :key="index"为每一个生成的元素设置一个唯一的key属性

  • 这里绑定的key是数组的索引,应该是唯一的

Vue 事件绑定 v-on指令

在Vue中通过v-on指令给页面元素绑定事件。

v-on:事件名="js代码片段或函数" //事件名=事件属性-on  比如:click=onclick-on

简单写法

@事件名="js代码片段或函数"

ES事件
标签的事件属性
所有标签都有的事件属性:
单击事件   onclick(重要)
双击事件   ondblclick
鼠标移入事件  onmouseover(重要)
鼠标移出事件  onmouseout(重要)
鼠标按下事件  onmousedown
鼠标弹起事件  onmouseup
鼠标移动事件  onmousemove
body标签 
页面加载完毕事件 onload//通常在该事件中定义只需要执行1次的代码
form标签相关事件属性[重点]:
input标签的事件:
	获取焦点事件   onfocus(重要)
	失去焦点事件   onblur(重要)
	值发生改变事件 onchange(重要)
form标签的事件:
	表单提交事件   onsubmit(重要)

 

Vue 事件修饰符

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 (子元素的事件冒泡来的不执行)-->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

注意:  使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你想阻止事件的默认行为。

Vue 标签属性的赋值:v-bind指令

无法直接在标签的属性中使用插值表达式动态的设置标签的属性值,这时候就需要使用v-bind指令。语法如下:

不过,v-bind太麻烦,因此可以省略,直接写成::属性名="属性值" ,即:  <img :src="imgsrc" :width="abc" />

<div id="app">
    <img v-bind:src="imgsrc" v-bind:width="abc" />
    <img :src="imgsrc" :width="abc" />
</div>

<!--引入vue文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    const v=new Vue({
        el:"#app",
        data:{
            imgsrc:"img/nane.gif",
            abc:100
        }
    });
</script>

绑定class属性的对象语法

我们可以传给 `v-bind:class` 一个对象,以动态地切换 class:

<div id="app">
    <div v-bind:class="{red_bg:showRed,green_bg:!showRed}">点击按钮改变背景样式</div>
    <button @click="showRed=true">红色</button>
    <button @click="showRed=false">绿色</button>
</div>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            showRed:true
        }
    })
</script>

 

Vue JSON对象拷贝

obj2 复制  obj1 的数据

obj2 = JSON.parse(JSON.stringify(obj1))  obj1是需要拷贝的对象

优点:obj1 与 obj2都是独立的对象,对obj2对象操作,对obj1没有影响

 

Vue 表单的双向数据绑定:v-model指令

之前我们演示的数据绑定都是单向绑定,数据影响了视图渲染,但是反过来就不行(视图的变化不会影响模型数据)。如下例所示:

<div id="app">
    <input type="text" :value="name"> <br>
    <button @click="setName">点我设置value</button>
    <button @click="getName">点我获取value</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            name:""
        },
        methods:{
            setName(){
                this.name="xiaohei";
            },
            getName(){
                alert(this.name);
            }
        }
    })
</script>

而对于表单中的控件而言,我们需要数据的绑定是双向的,即:模型数据的变化会影响视图,同时视图发生变化也会同步到模型数据。

接下来学习的v-model是双向绑定,视图(View)和模型(Model)之间会互相影响。既然是双向绑定,一定是在视图中可以修改数据的组件,这样就限定了视图的元素类型。

目前v-model的可使用元素有:

  • input

  • radio

  • checkbox

  • select

  • textarea

  • components(Vue中的自定义组件)

v-model本质上是一个语法糖。如下代码<input v-model="test">本质上是<input :value="test" @input="test = $event.target.value">,其中@input是对<input>输入事件的一个监听:value="test"是将监听事件中的数据放入到input,下面代码是v-model的一个简单的例子。在这边需要强调一点,v-model不仅可以给input赋值还可以获取input中的数据,而且数据的获取是实时的,因为语法糖中是用@input对输入框进行监听的。

基本上除了最后一项,其它都是表单的输入项。 首先我们先看一个简单的示例:

<div id="app">
        <input v-model="test">
        <input :value="test" @input="test= $event.target.value"> 语法糖
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            test: '这是一个测试'
        }
    });
</script>

 

Vue 过滤器

过滤器的作用是对数据进行格式化,比如字母全部大写、日期格式化输出、货币前添加货币符号等场景。Vue.js支持在{{ }}插值的尾部添加一个管道符“(|)”对数据进行过滤。过滤的规则,通过给Vue实例添加选项filters来设置。

<div id="app">
    <!-- 过滤器只有1个参数时,过滤器不需要写出(),默认传入|前的数据 -->
    <h2>使用过滤器字母全大写:{{str | toUpperCase}}</h2>
    <h2>使用过滤器日期格式化:{{date | dateFormat}}</h2>
    <!-- 过滤器有多个参数时,第1个参数仍然是|前的数据,后续的参数需要显式给出 -->
    <h2>货币格式化输出:{{money | moneyFormat("¥")}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            str:"hello filter",
            date:new Date(),
            money:1000.0
        },
        filters:{
            toUpperCase(value){
                return value.toUpperCase();
            },
            dateFormat(value){
                let year = value.getFullYear();
                let month = value.getMonth();
                let day = value.getDay();
                let hours = value.getHours();
                let seconds = value.getSeconds();
                let minutes = value.getMinutes();
                return `${year}-${month}-${day} ${hours}:${seconds}:${minutes}`;
            },
            moneyFormat(value,symbol){
                return symbol+" "+value;
            }
        }
    })
</script>

说明:还可以将过滤器定义为全局过滤器。

Vue.filter('过滤器名称', function (value[,param1,...] ) {  
    //逻辑代码
})

Vue 钩子函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这些函数在生命周期的不同阶段自动触发执行,这给了用户在不同阶段添加自己的代码的机会。

生命周期钩子含义
beforeCreate(vue对象创建前)组件实例刚被创建,组件属性计算之前,此时不能访问属性
created(创建后)组件实例创建完,属性可以访问,但是还不能通过 $el 访问DOM
beforeMount(加载前)模板编译、挂载之前,可以通过 $el 访问渲染前的DOM
mounted(载入后)模板编译、挂载之后,可以通过 $el访问渲染前的DOM
beforeUpdate(更新前)组件更新之前,可以获取组件更新前的DOM
updated(更新后)组件更新之后,可以获取组件更新后的DOM
beforeDestroy(销毁前)组件销毁前调用
destroyed(销毁后)组件销毁后调用
<div id="app">
    <h1>{{msg}}</h1>
    <button @click="changeMsg">点我修改msg</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    const vm = new Vue({
        el:"#app",
        data:{
            msg:"hell vue"
        },
        methods:{
            changeMsg(){
                this.msg = "hello baizhi";
            }
        },
        beforeCreate:function(){
            // alert("beforeCreate...");
            console.log("beforeCreate...");
            console.log(this.$el);//undefined
            console.log(this.msg);//undefined
        },
        created:function(){
            // alert("created...");
            console.log("created...");
            console.log(this.$el);//undefined
            console.log(this.msg);//hello vue
        },
        beforeMount:function(){
            // alert("beforeMount...");
            console.log("beforeMount...");
            console.log(this.$el);//加载前的标签,就是原始代码,插值表达式、事件绑定都还没解析
            console.log(this.msg);//hello vue
        },
        mounted:function(){
            // alert("mounted...");
            console.log("mounted...");
            console.log(this.$el);//加载后的标签,插值表达式、事件绑定均已解析
            console.log(this.msg);//hello vue
        },
        beforeUpdate:function(){
            // alert("beforeUpdated...");
            console.log("beforeUpdated...");
            console.log(this.$el.innerHTML);//更新前的DOM
            console.log(this.msg);//hello baizhi
        },
        updated:function(){
            // alert("updated...");
            console.log("updated...");
            console.log(this.$el.innerHTML);//更新后的DOM
            console.log(this.msg);//hello baizhi
        },
        beforeDestroy:function(){//在console中执行vm.$destroy()触发,开发时很少关注
            // alert("destroyed...");
            console.log("beforeDestroy...");
            console.log(this.$el);
            console.log(this.msg);
        },
        destroyed:function(){
            // alert("destroyed...");
            console.log("destroyed...");
            console.log(this.$el);
            console.log(this.msg);
        }
    })
</script>

说明:一般地,我们会在 created 钩子函数中,从服务端获取数据,并对数据进行初始化。

Vue 组件


全局注册

全局注册的组件,可以在不同的Vue实例中使用。语法如下:

<script>
	Vue.component("组件名",{
        template:"复用的html片段",
        data:function(){
            return {...}//return的对象,类似于创建Vue实例时的data
        },
        methods:{
            //和定义Vue实例时一样,用于定义函数
        }
    })
</script>

局部注册

一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用局部注册。在Vue实例中添加选项 components 语法如下

<script>
	const vm = new Vue({
        el:"选择器",
        data:{
            //属性
        },
        components:{
            //注册局部组件
            "组件名":{
                template:"复用的html片段",
                data:function(){
                    return {...}//return的对象,类似于创建Vue实例时的data
                },
                methods:{
                    //和定义Vue实例时一样,用于定义函数
                }
            }
        }
    });
</script>

注册优化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <template id="temp">
        <h1>dafjoiddf</h1>
    </template>
    <template id="temp2">
        <h1>dafjoiddf</h1>
    </template>
    
    
    <div id="id">
        <aaa></aaa>
        <bbb></bbb>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
    const temp2 = {
        template: "#temp2",
    }
    new Vue({
        el: "#id",
        components: {
            aaa: {
                template: "#temp"
            },
            bbb: temp2,
        }
    })
</script>
</html>

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值