Vue学习笔记01——Vue开发基础

一、Vue实例配置选项

选项 说明
data Vue实例数据对象
methods 定义Vue中的方法
components 定义子组件
computed 计算属性
filters 过滤器
el 唯一根标签
watch 监听数据变化

1.el唯一根标签

在创建Vue实例时,el表示唯一根标签,class或id选择器可以用来将页面结构与Vue实例对象中的el绑定。

<div id="app">{
    {name}}div>
<script>
	var vm=new Vue({
       
        el:"#app",
        data:{
       
            name:"Vue实例创建成功!"
        }
    })
script>

2.data初始数据

Vue实例的数据对象为data,Vue会将data的属性转换为getter,setter,从而让data的属性都能够响应数据变化。

Vue实例创建后,可以通过**vm. d a t a ∗ ∗ 访 问 原 始 数 据 对 象 。 V u e 实 例 也 代 理 了 d a t a 对 象 上 所 有 的 属 性 , 因 此 访 问 v m . n a m e 相 当 于 访 问 v m . data**访问原始数据对象。Vue实例也代理了data对象上所有的属性,因此访问vm.name相当于访问vm. data访Vuedata访vm.name访vm.data.name。

2.1 data赋值方式一

<div id="app">
    <p>
        {
    {name}}
    p>
div>
<script>
	var vm=new Vue({
       
        el:'#app',
        data:{
       
            name:'定义初始数据'
        }
    })
    console.log(vm.$data.name);
    console.log(vm.name);
script>

2.2 data赋值方式二

<div id="vue_data">
    <h3>{
    {site}}h3>
    <h3>{
    {url}}h3>
    <h3>{
    {student}}h3>
div>
<script>
    // 字典
    var data = {
       
        site: "菜鸟教程",
        url: "https://www.baidu.com",
        student: "Tom"
    };
    var vm = new Vue({
       
        el: "#vue_data",
        data: data
    });
    var h3 = document.querySelector('h3');
    h3.addEventListener('click', function () {
       
        data.site = '百度';
    });
    console.log(vm.site === data.site);
    console.log(vm.$data.site === data.site);
    console.log(vm.$data === data);
script>

3.methods定义方法

methods属性用来定义方法,通过Vue实例可以访问这些方法。在定义的方法中,this指向Vue实例本身。定义在methods属性中的方法可以作为页面中的事件处理方法使用,当事件被触发后,执行相应的事件处理方法。

<div id="app">
    <button @click="showInfo">
        请单击
    button>
    <p>
        {
    {msg}}
    p>
div>
<script>
	var vm=new Vue({
       
        el:'#app',
        data:{
       
            msg:''
        },
        mehods:{
       
            //定义时间处理方法showInfo
            showInfo(){
       
                this.msg='触发单击事件'
            }
        }
    })
script>

4.computed计算属性

Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动,当有一些数据需要随着其他数据而变动时,就需要使用computed计算属性

在事件处理方法中,this指向的Vue实例的计算属性结果会被缓存起来,只有依赖的响应式属性变化时,才会重新计算,返回最终结果。

4.1 案例:增加数量计算总价

<div id="app">
    <p> 总价格:{
    {totalPrice}}p>
    <p> 单价:{
    {price}}p>
    <p> 数量:{
    {num}}p>
    <div>
        <button @click="num == 0?0:num--">减少数量button>
        <button @click="num++">增加数量button>
    div>
div>
<script>
    var vm = new Vue({
       
        el: "#app",
        data: {
       
            price: 20,
            num: 0
        },
        methods: {
       //整个页面重新渲染的时候才会执行
            sum: function () {
       
                return this.price * this.num;
            }
        },
        computed: {
       //依赖的缓存被更改的时候就会执行,在有依赖的情况下执行效率要高一点
            //总价格计算
            totalPrice: function () {
       
                return this.price * this.num;
            }
        }
    });
script>

5.watch状态监听

Vue提供了watch状态监听功能,只需监听当前Vue实例中的数据变化,就会调用数据所绑定的事件处理方法

5.1 基础使用

<div id="app">
    <input type="text" v-model="cityName">
div>
<script>
	var vm=new Vue({
       
        el:'#app',
        data:{
       
            cityName:'shanghai'
        },
        // 使用watch监听cityName变化
        watch:{
       
            cityName(newName,oldName){
       
                // 打印新数据和旧数据
                console.log(newName,oldName);
            }
        }
    })
script>

5.2 计算总价

<div id="app">
    <p> 总价格:{
    {sum}}p>
    <p> 单价:{
    {price}}p>
    数量:<input type="number" v-model="num"/>
    <div>
        <button @click="num == 0?0:num--">减少数量button>
        <button @click="num++">增加数量button>
    div>
div>
<script>
    var vm = new Vue({
       
        el: "#app",
        data: {
       
            sum: 0,
            price: 20,
            num: 0
        },
        watch: {
       
            num(newData, oldData) {
       
                if (newData < 0) {
       
                    this.num = 0;
                }
                this.sum = newData * this.price;
            }
        }
    });
script>

5.3 距离转换km<=>m

<h2>距离转换h2>
<div id="km_m">
    <input type="number" v-model="km"/>千米<br/>
    <input type="number" v-model="m"/><br/>
div>
<div id="info">div>
<script>
    var vm1 = new Vue({
       
        el: "#km_m",
        data: {
       
            km: 0,
            m: 0
        },
        watch: {
       
            km: function (newData, oldData) {
       
                this.m = newData * 1000;
            },
            m: function (newData, oldData) {
       
                this.km = newData / 1000;
            }
        }
    });
    vm1.$watch('km', function (newValue, oldValue) {
       
        var info = document.querySelector('#info');
        info.innerHTML = '修改前的值是' + oldValue + ',修改后的值是' + newValue;
    })
script>

3-4-5.methods、computed、watch区别

<h2>三个属性的区别h2>
<div id="name">
    姓:<input type="text" v-model="firstName"/>
    名:<input type="text" v-model="lastName"/>
    <h4>用methods形式打印全名{
    {methodFullName()}},年龄{
    {age}}h4>
    <h4>用computed形式打印全名{
    {computedFullName}},年龄{
    {age}}h4>
    <h4>用watch形式打印全名{
    {watchFullName}},年龄{
    {age}}h4>
div>
<script>
    var vm2 = new Vue({
       
        el: '#name',
        data: {
       
            firstName: '张',
            lastName: '三',
            age: 18,
            watchFullName: '张三'
        },
        methods: {
       
            methodFullName: function () {
       
                console.log("这是方法返回的全名");
                return this.firstName + this.lastName;
            }
        },
        computed: {
       
            computedFullName: function () {
       
                console.log("这是计算返回的全名");
                return this.firstName + this.lastName;
            }
        },
        watch: {
       
            firstName: function (newValue) {
       
                console.log('这是监听属性firstName的返回');
                this.watchFullName = newValue + this.lastName;
            },
            lastName: function (newValue) {
       
                console.log('这是监听属性lastName的返回');
                this.watchFullName = this.firstName + newValue;
            }
        }
    })
script>

6.filters过滤器

数据变化除了在Vue逻辑层进行操作外,还可以通过过滤器来实现。

6.1在插值表达式中使用过滤器

通过"{ {data}}“语法,可以将data中的数据插入页面中,该语法就是插值表达式,插值表达式中还可以使用过滤器来对数据进行处理,语法为”{ {data | filter}}"

<div id="app">
    {
    {message|toUpcase|toLowcase}}
div>
<script>
    var vm = new Vue({
       
        el: '#app',
        data: {
       
            message: "abcdefg"
        },
        filters: {
       
            // 参数value表示传到过滤器中的数据
            toUpcase: function (value) {
       
                // 将abcdefg转换为ABCDEFG
                return value ? value.toUpperCase() : '';
            },
            toLowcase: function (value) {
       
                // 将ABCDEFG转换为abcdefg
                return value ? value.toLowerCase() : '';
            }
        }
    })
script>

6.2在v-bind属性绑定中使用过滤器

v-bind用于属性绑定,如"v-bind:id=”data““表示绑定id属性,值为data。在data后面可以加过滤器,语法为"data|filter”。

<div id="app">
    <div v-bind:id="dataId | formatId">
        helloworld
    div>
div>
<script>
	var vm=new Vue({
       
        el:'#app',
        data:{
       
            dataId:'dff1'
        },
        filters:{
       
            //字符串处理
            return value?vlaue.charAt(1)+value.indexOf('d'):'';
        }
    })
script>

二、Vue数据绑定

1.绑定样式

1.1 绑定内联样式

在Vue实例中定义的初始数据data,可以通过v-bind将样式数据绑定给DOM元素

<div id="app">
    
    <div v-bind:style="{backgroundColor:pink,width:width,height:height}">
        <div v-bind:style="myDiv">div>
    div>
div>
<script>
    var vm = new Vue({
       
        el: '#app',
        data: {
       
            myDiv: {
       backgroundColor: 'red', width: '100px', height: '100px'},
            pink: 'pink',
            width: '100%',
            height: '200px',
        }
    });
script>

1.2绑定样式类

样式类即以类名定义元素的样式

<div id="app">
    <div v-bind:class="{box}">
        我是box
        <div v-bind:class="{inner}">我是innerdiv>
        <div v-bind:class="{inner,text}">我是innerdiv>
    div>
div>
<script>
    var vm = new Vue({
       
        el: '#app',
        data: {
       
            box: 'box',
            inner: 'inner',
            text: 'text'
        }
    });
script>

1.3样式数组


<div id="myArr">
    <div v-bind:style="[baseStyle,myStyle]">今天是周四div>
div>
<script>
    var myvm = new Vue({
       
        el: '#myArr',
        data: {
       
            baseStyle: {
       
                color: 'red',
                fontSzie: '30px',
            },
            myStyle: {
       
                'font-weight': 'bold'
            }
        }
    })
script>

1.4是否加载样式


<div id="flag_css">
    <div v-bind:class="{inner,active:isActive}">div>
div>
<script>
    var flag_css = new Vue({
       
        el: "#flag_css",
        data: {
       
            inner: 'inner',
            isActive: true,
            active: 'active'
        }
    })
script>

1.5样式绑定综合

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>内联样式属性title>
    <script src="js/vue.js">script>
    <style>
        .active {
       
            width: 100px;
            height: 100px;
            background-color: blue;
        }

        .mytext {
       
            background-color: red;
        }
    style>
head>
<body>
<div id="app">
    <div v-bind:class="{
      'active':isActive,'mytext':hasError}">div>
    <button @click="upIsActive">isActivebutton>
    <button @click="upHasError">hasErrorbutton>
div>
<script>
    var vm = new Vue({
       
        el: '#app',
        data: {
       
            isActive: true,
            hasError: true
        },
        methods: {
       
            upIsActive: function () {
       
                this.isActive = !this.isActive;
            },
            upHasError: function () {
       
                this.hasError = !this.hasError;
            }
        }
    })
script>

<div id="app1">
    <div v-bind:class="obj">div>
    <button @click="upIsActive">isActivebutton>
    <button @click="upHasError">hasErrorbutton>
div>
<script>
    var vm1 = new Vue({
       
        el: '#app1',
        data: {
       
            obj: {
       
                active: true,
                mytext: true
            }
        },
        methods: {
       
            upIsActive: function () {
       
                this.obj.active = !this.obj.active;
            },
            upHasError: function () {
       
                this.obj.mytext = !this.obj.mytext;
            }
        }
    })
script>

<div id="app2">
    <div v-bind:class="comNum">div>
    <button @click="upIsActive">isActivebutton>
div>
<script>
    var vm2 = new Vue({
       
        el: '#app2',
        data: {
       
            isActive: true,
            num: 100
        },
        methods: {
       
            upIsActive: function () {
       
                this.isActive = !this.isActive;
            }
        },
        computed: {
       
            comNum: function () {
       
                return {
       
                    active: this.isActive && this.num >= 100,
                    hasError: this.isActive && this.num < 100
                }
            }
        }
    })
script>
body>
html>

2.内置指令

指令 说明
v-model 双向数据绑定,页面修改同步
v-on 监听事件,可简写为“@”
v-bind 单向数据绑定,页面修改不同步,可简写为“:”
v-text 插入文本内容
v-html 插入包含HTML的内容
v-for 列表渲染
v-if 条件渲染
v-show 显示隐藏

2.1 v-model 双向数据绑定

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>内置指令title>
    <script src="js/vue.js">script>
head>
<body>

<div id="app">
    <label>
        姓名
        <input type="text" v-model="name"/>
    label>
    <label>
        年龄
        <input type="number" v-model="age"/>
    label>
    <label>
        性别
        <input type="text" v-model="sex"/>
    label>
    <hr/>
    <p>姓名:{
    {name}}<br/>年龄:{
    {age}}<br/>性别:{
    {sex}}p>
div>
<script>
    var vm = new Vue({
       
        el: '#app',
        data: {
       
            name: '张三',
            age: 18,
            sex: '男'
        }
    })
script>
script>
body>
html>

2.2 v-bind 单向数据绑定

数据仅可从model端view端,详细请看绑定样式

2.3 v-text 文本填充

向DOM中添加文本内容


<div id="app1">
    <p v-text="msg">p>
div>
<script>
    var vm = new Vue({
       
        el: '#app1',
        data: {
       
            msg: '我是v-text'
        }
    })
script>

2.4 v-html HTML标签填充


<div id="app2">
    <div v-html="h">div>
div>
<script>
    var vm = new Vue({
       
        el: '#app2',
        data: {
       
            h: '

我是v-html

'
} })
script>

2.5 v-on 事件监听指令


<div id="app3">
    <button @click="showAlert">v-onbutton>
    <input type="text" @keyup.enter="submit"/>
div>
<script>
    var vm = new Vue({
       
        el: '#app3',
        methods: {
       
            showAlert: function () {
       
                alert('v-on')
            },
            submit: function () {
       
                alert('登录成功!')
            }
        }
    })
script>

2.6 v-for 列表循环

v-for 可以实现页面列表的渲染,常用来循环数组。


<div id="app4">
    <div v-for="(item,key) in list" data-id="key">
        索引是:{
    {key}},元素内容是:{
    {item}}
    div>
div>
<script>
    var vm = new Vue({
       
        el: '#app4',
        data: {
       
            list: ['a', 'b', 'c', 'd']
        }
    })
script>

2.7 v-if 或v-show

控制元素显示隐藏,属性为布尔值。

v-if真正的条件渲染,会触发一些绑定的事件,惰性的,如果初始条件是false原始元素就不会进行渲染。条件不经常切换使用这个

v-show:简单进行css样式切换,初始条件为false也会进行渲染,初始渲染开销大。条件经常改变的话常用这个


<div id="app5">
    <div v-if="isShow" style="background-color: #ccc;">我是v-ifdiv>
    <div v-show="isShow" style="background-color: #ccc;">我是v-showdiv>

    <button @click="isShow=!isShow">显示/隐藏button>
div>
<script>
    var vm = new Vue({
       
        el: '#app5',
        data: {
       
            isShow: true
        }
    })
script>

3.事件修饰符

修饰符 说明
.stop 阻止事件冒泡
.prevent 阻止默认事件行为
.capture 事件捕获
.self 将事件绑定到自身,只有自身才能触发
.once 事件只触发一次

3.1 stop 阻止事件冒泡


<div id="app1" @click="doParent" style="width: 100px;border: solid red 1px;">
    <button @click="doThis">事件冒泡button>
    <br/>
    <button @click.stop="doThis">阻止事件冒泡button>
div>
<script>
    var vm = new Vue({
       
        el: '#app1',
        methods: {
       
            doThis: function () {
       
                alert('this');
            },
            doParent: function () {
       
                alert('parent');
            }
        }
    })
script>

3.2 prevent 阻止默认行为


<div id="app2">
    <a href="https://www.baidu.com">不阻止默认事件a>
    <br/>
    <a href="https://www.baidu.com" @click.prevent>阻止默认事件a>
div>
<script>
    var vm = new Vue({
       
        el: '#app2'
    })
script>

3.3 capture 事件捕获


<div id="app3" @click.capture="doParent" style="width: 100px;border: solid red 1px;">
    <button @click="doThis">事件捕获button>
div>
<script>
    var vm = new Vue({
       
        el: '#app3',
        methods: {
       
            doThis: function () {
       
                alert('this');
            },
            doParent: function () {
       
                alert('parent');
            }
        }
    })
script>

3.4 self 自身触发


<div id="app4" @click.self="doParents" style="width: 100px;height: 100px;background-color: #aaaa;">
    a
    <div @click="doSub" style="width: 70px;height: 70px;background-color: #5555;">
        b
    div>
div>
<script>
    var vm = new Vue({
       
        el: '#app4',
        methods: {
       
            doParents: function () {
       
                console.log('调用了doParent');
            },
            doSub: function () {
       
                console.log('调用了doSub');
            }
        }
    })
script>

3.5 once 只触发一次


<div id="app5">
    <button @click.once="doThis">只触发一次button>
div>
<script>
    var vm = new Vue({
       
        el: '#app5',
        methods: {
       
            doThis: function () {
       
                console.log('只触发一次')
            }
        }
    })
script>

三、Vue组件

在Vue中,组件是构成页面中的独立结构单元,能够减少重复代码的编写,提高开发效率,降低代码之间的耦合程度,使项目更易维护和管理。

举例:如果页面中常常要有公司logo那么可以将logo定义为组件。

1.全局组件

在js内部使用**Vue.component(‘组件名’,{template:‘标签’})**可以定义全局组件

<div id="app">
    <my-component>my-component>
    <my-component>my-component>
    <my-component>my-component>
div>
<div id="app1">
    <myComponent>aaamyComponent>
div>
<script>
    // 全局组件
    Vue.component('myComponent',//组件名称,命名的时候可以用驼峰命名法,引用的时候不能使用驼峰命名法,只能使用连接法
        {
       
            template: "

这是一个全局组件

"
//模板就是组件的内容 } ); Vue.component('my-abc', { // data是方法,该方法必须要有返回值,通常该返回值是给模板使用的 data() { return { count: 0 } }, template: "" } ); new Vue({ el: '#app' }); new Vue({ el: '#app1' })
script>

2.局部组件

Vue()内部使用components关键字定义自定义组件


<div id="app2">
    <my-abc>my-abc>
div>
<script>
    new Vue({
       
        el: "#app2",
        components: {
       
            myAbc: {
       
                template: "

这是一个局部组件

"
} } })
script>

3.模板变量

将template模板使用变量装起来,使用的时候直接调用该变量即可。

<div id="app3">
    <my-aaa>my-aaa>
div>
<script>
    //模板变量
    var mytemp = {
       
        template: '

这是第二个局部组件

'
}; new Vue({ el: '#app3', components: { myAaa: mytemp } });
script>

4.template模板

template内的内容是使用字符串保存的很容易出错,所以我们可以使用template标签html内部定义自定义组件的内容。

注意:template标签下只能有一个子标签


<div id="app4">
    <my-comp>my-comp>
div>
<template id="temp1">
    <div>
        <h1>这是一个标题h1>
        <p>这是一个段落:{
    {title}}p>
        <button v-on:click="show">单击我button>
    div>
template>
<script>
    Vue.component('my-comp', {
       
        template: '#temp1',
        data() {
       
            return {
       
                title: '我是组件内的title'
            }
        },
        methods: {
       
            show: function () {
       
                alert(this.title)
            }
        }
    });
    new Vue({
       
        el: '#app4'
    })
script>

5.数据使用规则

vue定义的标签下面使用的自身data内的变量

template下自定义标签使用的变量是data()函数返回来的数据变量

注意:data()函数必须要有返回值

<div id="app5">
    <p>{
    {title}}p>
    <my-comp2>my-comp2>
div>
<template id="temp2">
    <p>{
    {title}}p>
template>
<script>
    Vue.component('my-comp2',
        {
       
            template: '#temp2',
            data() {
       
                return {
       
                    title: '这是组件中的data'
                }
            }
        }
    );
    new Vue({
       
        el: '#app5',
        data: {
       
            title: '我是vm实例的title'
        }
    })
script>

6.组件传值

在Vue中,组件实例具有局部作用域。组件之间的数据传递需要借助一些工具。

6.1 props传值

props即道具,用来接受父组件中定义的数据,其值为数组,数组中是父组件传递的数据信息。

在调用**自定义组件(父组件)的时候使用“ 自定义属性=‘值’ ”的形式想模板中传递数据,子组件中使用“props:[‘name’]”**形式读取到父组件中的自定义属性值。


<div id="app">
    <my-comp name="Tom">my-comp>
div>
<script>
    Vue.component("my-comp",
        {
       
            props: ['name'],
            template: '

从组件中传递的值是:{ {name}}

'
} ); new Vue({ el: '#app' });
script>
<div id="app1">
    <my-comp1 props-message="父组件的数据">my-comp1>
div>
<template id="temp1">
    <div>
        <h3>父组件传给子组件h3>
        <p>通过props传递的,用props设置的值是组件(自定义标签)的属性名称p>
        <h4>父组件传递了:{
    {propsMessage}}h4>
        <h4>子组件自生的值:{
    {dataMessage}}h4>
    div>
template>
<script>
    Vue.component('my-comp1',
        {
       
            template: '#temp1',
            data() {
       
                return {
       
                    dataMessage: '子组件中的数据'
                }
            },
            props: ['propsMessage']
        }
    );
    new Vue({
       
        el: '#app1'
    })
script>

6.2 父组件用循环传值

案例一:通过循环创建网站列表

<div id="app">
    <ol>
        <todo-item v-for="item in sites" v-bind:todo="item">todo-item>
    ol>
div>
<script>
    Vue.component('todo-item', {
       
        template: "
  • { {todo.text}}
  • "
    , props: ['todo'] }); new Vue({ el: '#app', data: { sites: [ { text: 'www.taobao.com'}, { text: 'www.jingdong.com'}, { text: 'www.baidu.com'}, ] } })
    script>

    案例二:通过循环创建子组件表格

    <div id="app1">
        <table>
            
            <student-list v-bind:stu="title">student-list>
            
            <student-list v-for="item in students" v-bind:stu="item">student-list>
        table>
    div>
    <template id="temp1">
        
        <tr>
            <td style="border: 1px solid #000">{
        {stu.id}}td>
            <td style="border: 1px solid #000">{
        {stu.name}}td>
            <td style="border: 1px solid #000">{
        {stu.age}}td>
            <td style="border: 1px solid #000">{
        {stu.sex}}td>
        tr>
    template>
    <script>
        Vue.component('student-list', {
           
            template: '#temp1',
            props: ['stu']
        });
        new Vue({
           
            el: '#app1',
            data: {
           
                title: {
           
                    id: 'ID',
                    name: 'NAME',
                    age: 'AGE',
                    sex: 'SEX'
                },
                students: [
                    {
           id: '0001', name: '张三', age: 18, sex: '男'},
                    {
           id: '0002', name: '田媛媛', age: 18, sex: '女'},
                    {
           id: '0003', name: '陈雨', age: 20, sex: '男'},
                ]
            }
        })
    script>
    

    6.3 组件多个属性传值

    案例一:v-bind 基本多属性传值

    <div id="app">
        <p>第一个值<input type="text" v-model="s1"/>p>
        <p>第二个值<input type="text" v-model="s2"/>p>
        <p>第三个值<input type="text" v-model="s3"/>p>
        <hr/>
        
        <my-comp v-bind:attr1="s1" v-bind:attr2="s2" v-bind:attr3="s3">my-comp>
    div>
    <template id="my-temp">
        <div>
            <h3>多个属性的传值h3>
            <p>值1:{
        {attr1}}p>
            <p>值2:{
        {attr2}}p>
            <p>值3:{
        {attr3}}p>
        div>
    template>
    <script>
        Vue.component('my-comp', {
           
            template: '#my-temp',
            props: ["attr1", "attr2", "attr3"]
        });
        new Vue({
           
            el: '#app',
            data: {
           
                s1: '',
                s2: '',
                s3: ''
            }
        })
    script>
    

    案例二:多个属性传值双向绑定

    <div id="app">
        <p>第一个值<input type="text" v-model="s1"/>p>
        <p>第二个值<input type="text" v-model="s2"/>p>
        <p>第三个值<input type="text" v-model="s3"/>p>
        <hr/>
        <my-comp v-bind:attr1="s1" v-bind:attr2="s2" v-bind:attr3="s3">my-comp>
    div>
    <template id="my-temp">
        <div>
            <h3>多个属性的传值h3>
            <p>值1:{
        {attr1}}p>
            <p>值2:{
        {attr2}}p>
            <p>值3:{
        {attr3}}p>
            <p>点击按钮后得到的值:{
        {content1}}p>
            <p>及时得到的值:{
        {content2}}p>
            <p>计算得到的值:{
        {contentx}}p>
            <button @click="show">按钮button>
        div>
    template>
    <script>
        Vue.component('my-comp', {
           
            template: '#my-temp',
            props: ["attr1", "attr2", "attr3"],
            data: function () {
           
                return {
           
                    content1: "",
                    content2: ""
                }
            },
            methods: {
           
                //方法:按钮触发
                show() {
           
                    this.content1 = this.attr1 + this.attr2 + this.attr3;
                }
            },
            watch: {
           
                //数据监听
                attr1: function () {
           
                    this.content2 = this.attr1 + this.attr2 + this.attr3;
                },
                attr2: function () {
           
                    this.content2 = this.attr1 + this.attr2 + this.attr3;
                },
                attr3: function () {
           
                    this.content2 = this.attr1 + this.attr2 + this.attr3;
                },
            },
            computed:{
           
                //数据计算
                contentx:function () {
           
                    return this.attr1 + this.attr2 + this.attr3;
                }
            }
        });
        new Vue({
           
            el: '#app',
            data: {
           
                s1: '',
                s2: '',
                s3: ''
            }
        })
    script>
    

    6.4 $emit方法 子组件像父组件传值

    语法

    this.$emit('处理方法', 数据);
    

    案例

    <div id="app">
        
        <parent>parent>
    div>
    <template id="child">
        
        <div>
            <button @click="click">传值button>
            
            <input type="text" v-model="message"/>
        div>
    template>
    <script>
        //父组件
        Vue.component('parent', {
           
            //父组件模板,子组件通过@childFn绑定了一个父组件事件处理方法,子组件可以通过该方法改变父组件中message的值
            template: '
    子组件传来的值:{ {message}}
    '
    , data: function () { return { // 父组件中的message message: '' } }, methods: { //通过该事件处理方法可以修改父组件中message的值 transContent: function (payload) { this.message = payload; } } }); //子组件 Vue.component('child', { template: '#child', data: function () { return { //子组件中的message属性 message: '子组件的消息' } }, methods: { click() { //激活调用父组件中childFn绑定的事件,传的值是message this.$emit('childFn', this.message); //有点像java里面的super? } } }); new Vue({ el: '#app' })
    script>

    7.组件切换

    7.1 v-if v-else形式切换

    <div id="app">
        <label>
            第一个页面内容
            <input type="text" v-model="titleLogin"/>
        label>
        <label>
            第二个页面内容
            <input type="text" v-model="titleRegister"/>
        label>
        <br/>
        
        <a href="#" @click.prevent="flag=true">登录页面a>
        <a href="#" @click.prevent="flag=false">注册页面a>
        
        <login v-if="flag" :title-name="titleLogin">login>
        <register v-else="flag" :title-name="titleRegister">register>
    div>
    <script>
        // div的基本样式
        Vue.component('login', {
           
            props: ['title-name'],
            template: '
    { {titleName}}
    '
    }); Vue.component('register', { props: ['title-name'], template: '
    { {titleName}}
    '
    }); new Vue({ el: '#app', data: { flag: true, titleLogin: '登录', titleRegister: '注册' } })
    script>

    7.2 is属性组件切换

    <div id="app">
        
        <a href="#" @click.prevent="comName='login'">登录页面a>
        <a href="#" @click.prevent="comName='register'">注册页面a>
        
        <component :is="comName">component>
    div>
    <script>
        Vue.component('login', {
           
            props: ['title-name'],
            template: '
    { {登录页面}}
    '
    }); Vue.component('register', { props: ['title-name'], template: '
    { {注册页面}}
    '
    }); new Vue({ el: '#app', data: { comName: 'login', } })
    script>

    四、Vue的生命周期

    1.钩子函数

    钩子函数用来描述Vue实例从创建到销毁的的整个生命周期

    钩子 说明
    beforeCreate 创建实例对象之前执行
    created 创建实例对象之后执行
    beforeMount 页面挂在成功之前执行
    mounted 页面挂在成功之后执行
    beforeUpdate 组件更新之前执行
    updated 组件更新之后执行
    beforeDestroy 实例销毁之前执行
    destroyed 实例销毁之后执行

    1.1实施创建

    <div id="app">{
        {msg}}div>
    <script>
        new Vue({
           
            el: '#app',
            data: {
           
                msg: '张三'
            },
            beforeCreate() {
           
                console.log('实例创建之前');
                // console.log(this.$data.msg);
            },
            created() {
           
                console.log('实例创建之后');
                console.log(this.$data.msg);
            }
        })
    script>
    

    1.2实施销毁

    <div id="app">
        
        <div ref="self">{
        {msg}}div>
    div>
    <script>
        new Vue({
           
            el: '#app',
            data: {
           
                msg: '张三'
            },
            beforeDestroy(){
           
                console.log('销毁之前');
                console.log(this.$refs.self);
                console.log(this.msg);
                console.log(vm);
            },
            destroyed(){
           
                console.log('销毁之后')
            }
        })
    script>
    

    1.3实时更新

    <div id="app">
        
        <div v-if="isShow" ref="self">testdiv>
        <button @click="isShow=!isShow">更新button>
    div>
    <script>
        new Vue({
           
            el: '#app',
            data: {
           
                isShow: false
            },
            beforeUpdate() {
           
                console.log('更新之前');
                console.log(this.$refs.self);
            },
            updated() {
           
                console.log('更新之后');
                console.log(this.$refs.self);
            }
        })
    script>
    

    1.4页面挂载

    <div id="app">{
        {msg}}div>
    <script>
        new Vue({
           
            el: '#app',
            data: {
           
                msg: '张三'
            },
            beforeMount() {
           
                //Vue与DOM关联之前
                console.log('页面挂载之前');
                console.log(this.$el.innerHTML);
            },
            mounted() {
           
                //Vue与DOM关联之后
                console.log('页面挂载之后');
                console.log(this.$el.innerHTML);
            },
            beforeCreate() {
           
                console.log('实例创建之前');
                // console.log(this.$data.msg);
            },
            created() {
           
                console.log('实例创建之后');
                console.log(this.$data.msg);
            }
        })
    script>
    

    1.5案例:实时显示时间

    <div id="app">
        <p id="time">p>
        <h3>格式化时间h3>
        <p>{
        {date|formatTime}}p>
        <p>
            <button @click="stop">停止时间button>
        p>
    div>
    <script>
        var p1 = document.querySelector('#time');
        p1.innerHTML = new Date();
    
        function parseDate(val) {
           
            return val < 10 ? '0' + val : val;//小于10的数字,前面加0
        }
    
        var vm = new Vue({
           
            el: '#app',
            data: {
           
                date: new Date(),
            },
            filters: {
           
                formatTime: function (time) {
           
                    var year = time.getFullYear();
                    var month = parseDate(time.getMonth() + 1);
                    var day = parseDate(time.getDate());
                    var hours = parseDate(time.getHours());
                    var minute = parseDate(time.getMinutes());
                    var seconds = parseDate(time.getSeconds());
                    return year + '-' + month + '-' + day + " " + hours + ':' + minute + ':' + seconds;
                }
            },
            created: function () {
           
                var that = this;//保持作用域的一致,此处that就是当前对象
                this.timmer = setInterval(function () {
           
                    that.date = new Date();
                }, 1000);
            },
            methods: {
           
                stop: function () {
           
                    clearInterval(this.timmer)
                }
            }
        })
    script>
    

    五、插槽

    使用方法为:

    1. 在自定义组件标签中间写上预留内容。
    2. 在模板中使用标签,将预留内容引入。(假如模板中未使用标签,那么自定义标签中间的内容将会被忽略。)

    1.插槽简单使用

    当组件渲染的时候,将会被插槽预留的内容所替换,如下案例:

    <div id="app">
        <my-comp>
            <h5>这是组件,在组件中写内容h5>
        my-comp>
    div>
    <template id="temp1">
        <div>
            
            <slot>slot>
            <p>这是模板内容,段落1p>
            <p>这是模板内容,段落2p>
            <p>这是模板内容,段落3p>
            <slot>slot>
            <p>模板中的数据{
        {tempData}}p>
            <slot>slot>
        div>
    template>
    <script>
        Vue.component('my-comp',{
           
            template: '#temp1',
            data:function () {
           
                return{
           
                    tempData: new Date()
                }
            }
        });
        new Vue({
           
            el: "#app",
        })
    script>
    

    2.简单使用2

    <div id="app">
        <my-comp1>辣椒炒肉my-comp1>
        <my-comp1>辣椒炒蛋my-comp1>
        <my-comp1>空心菜my-comp1>
        <hr/>
        
        <my-comp1 v-for="item in foods">{
        {item.name}}my-comp1>
        <hr/>
        <my-comp1>my-comp1>
    div>
    <template id="temp1">
        <dl>
            <dt>
                
                <slot>默认值,使用时没有给内容slot>
                
            dt>
            <dd>中国湘菜,湘菜最强。dd>
        dl>
    template>
    <script>
        Vue.component('my-comp1', {
           
            template: '#temp1'
        });
        new Vue({
           
            el: '#app',
            data: {
           
                foods: [
                    {
           name: '辣椒炒肉'},
                    {
           name: '辣椒炒蛋'},
                    {
           name: '辣子鸡'}
                ]
            }
        })
    script>
    

    3.具名插槽

    在定义自定义标签的预留内容的时候将标签加上slot='名字’属性,那么在标签调用插槽的时候,就需要用name='名字’匹配使用

    <div id="app">
        <my-compl>
            
            <span style="background-color: pink;" slot="girl">漂亮、温柔、贤惠span>
            
            <span style="background-color: #007fff" slot="boy">帅气,高大,富有span>
            
            <div>
                打工仔、干饭人、舔狗
            div>
        my-compl>
    div>
    <template id="templ">
        <div>
            <h4>这个世界有男人和女人h4>
            <p>女人:
                
                <slot name="girl">slot>
            p>
            <p>男人:
                
                <slot name="boy">slot>
            p>
            
            <slot>slot>
        div>
    template>
    <script>
        Vue.component('my-compl', {
           
            template: '#templ'
        });
        new Vue({
           
            el: '#app'
        })
    script>
    

    4.案例:标题、正文、页脚匹配

    此处我们也能看出,采用自定义控件+插槽的形式会使得控件格式更好规范添加。

    <div id="app">
        <my-compl>
            
            <h3 slot="headerName">这是我的主页h3>
            <p slot="mainName">这是我的主页内容p>
            <h4 slot="footerName">这是页脚部分h4>
            <p>今天是2021年的4月25日p>
        my-compl>
    div>
    <template id="templ">
        <div>
            <header>
                
                <slot name="headerName">页面标题slot>
            header>
            <mian>
                
                <slot name="mainName">正文部分slot>
                <slot>默认插槽slot>
            mian>
            <footer>
                
                <slot name="footerName">页脚部分slot>
            footer>
        div>
    template>
    <script>
        Vue.component('my-compl', {
           
            template: '#templ'
        });
        new Vue({
           
            el: '#app'
        })
    script>
    

    5.插槽作用域

    通过slot-scope(插槽作用域)刻印进行一些数据的传递。slot-scope返回的是一个数据集合,里面有调用者的自定义属性的key:value集合

    <div id="app">
        <my-compl>
            <template slot-scope="a">
                {
        {a}}
            template>
        my-compl>
    div>
    <script>
        Vue.component('my-compl', {
           
            template: '
    '
    }); new Vue({ el: '#app' })
    script>

    6.案例:匹配item格式

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>插槽作用域title>
        <script src="../js/vue.js">script>
        <style>
            .current {
           
                color: orange;
            }
        style>
    head>
    <body>
    <div id="app">
        
        
        <fruit :list="flist">
            
            <template slot-scope="slotprops">
                
                <strong v-if="slotprops.info.id==2" class="current">
                    {
        {slotprops.info.name}}
                strong>
                <span v-else>{
        {slotprops.info.name}}span>
            template>
    
        fruit>
    div>
    
    <template id="temp">
        <div>
            <ul>
                
                <li :key="item.id" v-for="item in list">
                    
                    <slot :info="item">slot>
                li>
            ul>
        div>
    template>
    <script>
        Vue.component('fruit', {
           
            template: '#temp',
            props: ['list'],//2.将父组件的属性list传到子组件
        });
        new Vue({
           
            el: "#app",
            data: {
           
                //数据集合
                flist: [
                    {
           id: 1, name: 'apple'},
                    {
           id: 2, name: 'banana'},
                    {
           id: 3, name: 'orange'},
                ]
            }
        })
    script>
    body>
    html>
    

    7.具名插槽结合使用

    <div id="app">
        
        <my-comp :items="items">
            
            <template slot="item" scope="pro">
                <li>
                    {
        {pro.text}}--{
        {pro}}
                    
                li>
            template>
        my-comp>
    div>
    <template id="temp">
        <div>
            <ul>
                
                <slot name="item" v-for="item in items" :text="item.text">slot>
            ul>
        div>
    template>
    <script>
        Vue.component('my-comp', {
           
            template: '#temp',
            //2.数据传递,传递到子组件
            props: ['items']
        });
        new Vue({
           
            el: '#app',
            data: {
           
                items: [
                    {
           text: '示例1'},
                    {
           text: '示例2'},
                    {
           text: '示例3'},
                ],
            }
        })
    script>
    

    8.具名插槽默认内容

    <div id="app">
        <my-comp>
            
        my-comp>
        <my-comp>
            
            <template slot-scope="myslot">
                <span>
                    {
        {myslot.datail.join("-")}}
                span>
            template>
        my-comp>
    div>
    <template id="temp">
        <div>
            <slot :datail="books">
                
                <ul>
                    <li v-for="item in books">{
        {item}}li>
                ul>
            slot>
        div>
    template>
    <script>
        Vue.component('my-comp', {
           
            template: '#temp',
            data() {
           
                return {
           
                    books: [
                        '唐诗三百首',
                        '宋词',
                        '元曲',
                        '小说',
                    ]
                }
            }
    
        });
        new Vue({
           
            el: '#app',
            data: {
           
                books: '父组件数据'
            }
        })
    script>
    

    Vue学习笔记02——Vue路由

    你可能感兴趣的:(笔记,Vue,vue,html,js,bootstrap)