[TOC]

vue

image.png
vue官方API
以下案例涉及到的示例代码:示例代码

渐进式框架

🐵Vue全家桶 - 图2
vue是一套构建用户界面的渐进式框架,采用自底向上增量开发的设计。vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整。
渐进式表现:声明式渲染—组件系统—客户端路由—大数据状态管理—构建工具

两个核心点

(1)响应式数据绑定
当数据发生变化的时候,视图自动更新,即双向数据同步,原理利用了ES6中的 Object.definedProperty 中的setter/getter 代理数据,监控对数据的操作。
(2)组合的视图组件
即页面最终映射为一个组件树,采用树形数据结构进行设计,方便维护,重用。

虚拟DOM

image.png
利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM。当数据发生变化时,能够智能的计算出重新渲染组件的最小代价并应用到DOM操作上。

MVVM

image.png
MVVM 是 Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对 View 和 ViewModel 的双向数据绑定,这使得 ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
M:Model(数据层,也就是指数据(前端是js))
V:View ( 也就是指DOM层 或用户界面 )
VM : ViewModel (处理数据和界面的中间层,也就是指Vue)
image.png

声明式渲染

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。
额外补充:
渲染分为:命令式渲染和声明式渲染
命令式渲染:命令我们的程序去做什么,程序就会跟着你的命令去一步一步执行
声明式渲染 :只需要告诉程序想要什么效果,其他的交给程序来做
具体区别看如下代码,执行结果一样,实现方式不同。

<script type="text/javascript">
    var arr = [1, 2, 3, 4, 5];

    // 命令式渲染:关心每步,关心流程,用命令去实现
    var newArr = [];
    for(var i = 0, len = arr.length; i < len; i++) {
        newArr.push(arr[i] * 2);
    }
    console.log(newArr);

    // 声明式渲染:不关心中间流程,只需要关心结果和实现条件
    var arr1 = arr.map(function(item) {
        return item*2;
    });
    console.log(arr1);
</script>

入门示例

1、安装

(1)CDN引入

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

(2)NPM安装

npm install vue

2、helloworld

(1)完整代码如下:

<!--第一步:创建文件夹及html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之Helloworld</title>
    <!--第二步:引入Vue库-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <!--第三步:创建一个Div-->
    <div id="app">
        <!--Vue的模板的绑定数据的方法,用两对花括号进行绑定Vue中的数据对象的属性 -->
        {{message}}
    </div>

    <!--第四步:创建Vue的对象,并把数据绑定到上面创建好的div上去。-->
    <script type="text/javascript">
        var app=new Vue({ // 创建Vue对象。Vue的核心对象。
            el:'#app', // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器
            data:{    // data: 是Vue对象中绑定的数据
                message:'hello Vue!' // message 自定义的数据
            }
        })
    </script>
</body>
</html>

(2)输出结果:

hello Vue!

内部指令

1、v-if 、v-else、 v-show、v-else-if

这几个条件指令用于显示与隐藏各类元素,使用方式如下:

v-if

<div v-if="isLogin">你好</div>

v-else

<div v-else>请登录后操作</div>

v-show

<div v-show="isLogin">你好</div>

v-else-if

<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-if与v-show的区别

  • v-if: 在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,开销较高,在运行时条件很少改变时使用。
  • v-show:调整css dispaly属性,开销较小,在常频繁地切换时使用。

2、v-for

(1)基本用法

<!-- 模板 -->
<div id="app">
    <ul>
        <li v-for="item in items">
            {{item}}
        </li>
    </ul>
</div>

<!--JS代码 -->
<script type="text/javascript">
    var app=new Vue({
        el:'#app',
        data:{
            items:[20,23,18,65]
        }
    })
</script>

(2)对象遍历

参数: 第一个为值,第二个为键名,第三个为索引

<!-- 模板 -->
<div id="app">
    <ul>
        <li v-for="(value, key, index) in object">
        {{ index }}. {{ key }} - {{ value }}
        </li>
    </ul>
</div>

<!--JS代码 -->
<script type="text/javascript">
    var app=new Vue({
        el:'#app',
        data:{
            object: {
                firstName: 'John',
                lastName: 'Doe'
            }
        }
    })
</script>

3、v-text 、v-html

v-text

{{xxx}}取值有个弊端,当网速很慢或javascript出错时,会在页面显示{{xxx}},Vue提供的v-text可以解决这个问题

<div>{{ message }}</div>
<!-- 和下面的一样 -->
<div v-text="message"></div>

v-html

用于输出html代码

<span v-html="msgHtml"></span>

v-on

(1)常规用法

// html
<div>本场比赛得分:{{count}}</div>
<button v-on:click="add">加分</button>

// JS
data:{
    count: 1
},
methods: {
    add() {
        this.count++;
    }
}

(2)缩写

<button @click="add">加分</button>

指令详情的更多用法参照v-on官方API

5、v-model

以下的model都需要在data中声明初始值:

data: {
    count: 1,
    status: [],
    sex: '男',
    selected: ''
}

(1)input

<input type="text" v-model="message">

(2)textarea

<textarea  cols="30" rows="10" v-model="message"></textarea>

(3)checkbox

<input type="checkbox" id="first" value="1" v-model="status">
<label for="first">有效</label>
<input type="checkbox" id="second" value="2" v-model="status">
<label for="second">无效</label>
<div>状态:{{status}}</div>

(4)radio

<input type="radio" id="one" value="男" v-model="sex">
<label for="one">男</label>
<input type="radio" id="two" value="女" v-model="sex">
<label for="one">女</label>
<div>性别:{{sex}}</div>

(5)select

<select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
</select>
<div>Selected: {{ selected }}</div>

6、v-bind

用于处理html标签的动态属性,即动态赋值。
(1)常规用法

// html
<img v-bind:src="imgSrc"  width="200px">

// js
data: {    
    imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png'
}

(2)缩写

<img :src="imgSrc"  width="200px">

指令详情的更多用法参照v-bind官方API

7、v-pre、v-cloak、v-once

(1)v-pre
在模板中跳过vue的编译,直接输出原始值,如果在标签中加入v-pre就不会输出vue中的data值了

<div v-pre>{{message}}</div>

(2)v-cloak
在vue渲染完指定的整个DOM后才进行显示。它必须和CSS样式一起使用

// css
[v-cloak] {
    display: none;
}

// html
<div v-cloak>{{message}}</div>

(3)v-once
只显示DOM第一次渲染的值,以后不改变了

<div v-once>第一次绑定的值:{{message}}</div>

8、完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style type="text/css">
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- v-if -->
        <div v-if="isLogin">你好</div>
        <!-- v-else -->
        <div v-else>请登录后操作</div>
        <!-- v-show -->
        <div v-show="isLogin">你好</div>
        <!-- v-else-if -->
        <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-for基本使用 -->
        <ul>
            <li v-for="item in items">
                {{item}}
            </li>
        </ul>
        <!-- v-for高级使用 -->
        <ul>
            <li v-for="(value, key, index) in object">
                {{ index }}. {{ key }} - {{ value }}
            </li>
        </ul>
        <!-- v-text -->
        <div v-text="message"></div>
        <!-- v-html -->
        <div v-html="msgHtml"></div>
        <!-- v-on部分 -->
        <div>本场比赛得分:{{count}}</div>
        <!-- 常规写法 -->
        <button v-on:click="add">加分</button>
        <!-- @缩写 -->
        <button @click="add">加分</button><br/>
        <!-- v-model input -->
        <input type="text" v-model="message"><br/>
        <!-- v-model textarea -->
        <textarea  cols="30" rows="10" v-model="message"></textarea><br/>
        <!-- v-model checkbox -->
        <input type="checkbox" id="first" value="1" v-model="status">
        <label for="first">有效</label>
        <input type="checkbox" id="second" value="2" v-model="status">
        <label for="second">无效</label>
        <div>状态:{{status}}</div>
        <!-- v-model radio -->
        <input type="radio" id="one" value="男" v-model="sex">
        <label for="one">男</label>
        <input type="radio" id="two" value="女" v-model="sex">
        <label for="one">女</label>
        <div>性别:{{sex}}</div>
        <!-- v-model select -->
        <select v-model="selected">
            <option disabled value="">请选择</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
        <div>Selected: {{ selected }}</div>
        <!-- v-model select -->
        <img v-bind:src="imgSrc"  width="200px"><br/>
        <img :src="imgSrc"  width="200px"><br/>
        <!-- v-pre -->
        <div v-pre>{{message}}</div>
        <!-- v-cloak -->
        <div v-cloak>{{message}}</div>
        <!-- v-pre -->
        <div v-once>第一次绑定的值:{{message}}</div>
    </div>
    <script type="text/javascript">
        var app=new Vue({
            el:'#app',
            data:{
                isLogin: false,
                type: 'A',
                items:[20,23,18,65],
                object: {
                    firstName: 'John',
                    lastName: 'Doe'
                },
                message: 'hello Vue',
                msgHtml: '<h2>hello Vue!</h2>',
                count: 1,
                status: [],
                sex: '男',
                selected: '',
                imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png'

            },
            methods: {
                add() {
                    this.count++;
                }
            }
        })
    </script>
</body>
</html>

生命周期

官方文档:
vue官方生命周期图
vue生命周期API

1、生命周期图解

1531106989.png

2、生命周期表格

周期 说明
beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用
created 在实例创建完成后被立即调用,完成数据观测,属性和方法的运算,初始化事件,$el属性未见
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用,只在虚拟DOM生成HTML
mounted 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互
beforeUpdate 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程
updated 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用
activated keep-alive 组件激活时调用
deactivated keep-alive 组件停用时调用
beforeDestroy 在实例销毁之前调用。实例仍然完全可用
destroyed 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用

3、代码详解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
    </div>

<script type="text/javascript">
var app=new Vue({
    el:'#app',
    data:{
        message:'hello Vue!'
    },
    beforeCreate: function () {
        console.group('beforeCreate 创建前状态===============》');
        console.log("%c%s", "color:red" , "el      : " + this.$el); //undefined
        console.log("%c%s", "color:red","data    : " + this.$data); //undefined 
        console.log("%c%s", "color:red","message: " + this.message)  
    },
    created: function () {
        console.group('created 创建完毕状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el); //undefined
        console.log("%c%s", "color:red","data    : " + this.$data); //已被初始化 
        console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    beforeMount: function () {
        console.group('beforeMount 挂载前状态===============》');
        console.log("%c%s", "color:red","el      : " + (this.$el)); //已被初始化
        console.log(this.$el);
        console.log("%c%s", "color:red","data    : " + this.$data); //已被初始化  
        console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
    },
    mounted: function () {
        console.group('mounted 挂载结束状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el); //已被初始化
        console.log(this.$el);     
        console.log("%c%s", "color:red","data    : " + this.$data); //已被初始化
        console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
    },
    beforeUpdate: function () {
        console.group('beforeUpdate 更新前状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el);
        console.log(this.$el);    
        console.log("%c%s", "color:red","data    : " + this.$data); 
        console.log("%c%s", "color:red","message: " + this.message); 
    },
    updated: function () {
        console.group('updated 更新完成状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el);
        console.log(this.$el); 
        console.log("%c%s", "color:red","data    : " + this.$data); 
        console.log("%c%s", "color:red","message: " + this.message); 
    },
    beforeDestroy: function () {
        console.group('beforeDestroy 销毁前状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el);
        console.log(this.$el);     
        console.log("%c%s", "color:red","data    : " + this.$data); 
        console.log("%c%s", "color:red","message: " + this.message); 
    },
    destroyed: function () {
        console.group('destroyed 销毁完成状态===============》');
        console.log("%c%s", "color:red","el      : " + this.$el);
        console.log(this.$el);  
        console.log("%c%s", "color:red","data    : " + this.$data); 
        console.log("%c%s", "color:red","message: " + this.message)
    }
})
</script>
</body>
</html>

4、结果解析

在chrome浏览器里打开,F12看console查看,分三个阶段解读:
阶段一:创建和挂载

  • beforecreated:el 和 data 并未初始化
  • created:完成了 data 数据的初始化,el没有
  • beforeMount:完成了 el 和 data 初始化
  • mounted :完成挂载

阶段二:更新
在chrome console执行以下命令:

app.message= 'yes !! I do';
  • beforeUpdate:虚拟DOM中根据data变化去更新html
  • updated:将虚拟DOM更新完成的HTML更新到页面中

阶段三:销毁
在chrome console执行以下命令:

app.$destroy();
  • beforeDestroy:销毁之前调用
  • destroyed:销毁之后调用,之后再执行app.message= ‘hello vue’,页面不会同步更新。

具体图解如下:

常用选项

vue有许多配置选项,这节之类出常用的一些选项

1、computed

计算属性:主要是对原数据进行改造输出。改造输出:包括格式化数据(价格,日期),大小写转换,排序,添加符号

computed: {
    newPrice () {
        return '¥' + this.price + '元';
    }
}

2、methods

方法属性:用于绑定html中的事件对应的方法

methods:{
    add (num) {
        this.count += num;
    }
}

3、watch

数据变化监听器:主要用于监测data中的数据变化,迪v-model生效

watch: {
    question(val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal);
    }
}

4、filters

过滤器:通常格式化字符,使用传值

filters: {
    filterA(value) {
        return value.toUpperCase();
    }
}

5、mixins

混入:用于减少代码污染、减少代码量、实现代码重用

// 额外临时加入时,用于显示日志
var addLog={
    updated:function(){
        console.log("数据放生变化,变化成"+this.count+".");
    }
}

// 实例化vue
var app = new Vue({
    // 挂载实例
    el:'#app',
    // 页面数据初始化,字符,对象、数组
    data:{
        count: 100
    },
    // 混入
    mixins: [addLog]
})

6、extends

扩展:对构造器进行扩展

// 扩展
var extendObj ={
    created: function(){
        console.log("我是被扩展出来的");
    }
}

// 实例化vue
var app = new Vue({
    // 挂载实例
    el:'#app',
    // 页面数据初始化,字符,对象、数组
    data:{
    },
    // 扩展
    extends: extendObj
})

完整的代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
        <div>价格: {{newPrice}}</div>
        <div>数字: {{count}}</div>
        <div><button @click="add(2)">add</button></div>
        <div><input v-model="question"></div>
        <div>过滤: {{filtera | filterA}}</div>
    </div>

<script type="text/javascript">
// 额外临时加入时,用于显示日志
var addLog={
    updated:function(){
        console.log("数据放生变化,变化成"+this.count+".");
    }
}

// 扩展
var extendObj ={
    created: function(){
        console.log("我是被扩展出来的");
    }
}

// 实例化vue
var app = new Vue({
    // 挂载实例
    el:'#app',
    // 页面数据初始化,字符,对象、数组
    data:{
        message: 'hello Vue!',
        price: 100,
        count: 100,
        question: '',
        filtera: 'abc'
    },
    // 计算属性:主要是对原数据进行改造输出。
    // 改造输出:包括格式化数据(价格,日期),大小写转换,排序,添加符号
    computed: {
        newPrice () {
            return '¥' + this.price + '元';
        }
    },
    // 方法声明:用于绑定html中的方法
    methods:{
        add (num) {
            this.count += num;
        }
    },
    // data属性监听器, 作用v-model
    watch: {
        question(val, oldVal) {
            console.log('new: %s, old: %s', val, oldVal);
        }
    },
    // 过滤器,通常格式化字符,使用传值
    filters: {
        filterA(value) {
            return value.toUpperCase();
        }
    },
    // 混入,作用:减少代码污染、减少代码量、实现代码重用
    mixins: [addLog],
    // 扩展
    extends: extendObj
})
</script>
</body>
</html>

实例事件

vue有实例属性,实例方法,实例事件,前两个跟选项类似,不是很常用,这次只讲实例事件。

1、$on(在构造器外部添加事件)

$on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法

app.$on('reduce',function(){
    console.log('执行了reduce()');
    this.count--;
});

2、$once(执行一次的事件)

app.$once('reduceOnce',function(){
    console.log('只执行一次的方法');
    this.count--;
});

3、$off(关闭事件)

function off(){
    console.log('关闭事件');
    app.$off('reduce');
}

4、$emit(事件调用)

function reduce() {
    // 事件调用
    console.log('emit事件调用');
    app.$emit('reduce');
}

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div>数字:{{count}}</div>
        <button onclick="reduce()">on调用</button>
        <button onclick="reduceOnce()">once调用</button>
        <button onclick="off()">off调用</button>
    </div>

<script type="text/javascript">
var app = new Vue({
    el:'#app',
    data:{
        count: 1
    }
})
// $on 在构造器外部添加事件
app.$on('reduce',function(){
    console.log('执行了reduce()');
    this.count--;
});
// 调用
function reduce() {
    // 事件调用
    console.log('emit事件调用');
    app.$emit('reduce');
}

// $once执行一次的事件
app.$once('reduceOnce',function(){
    console.log('只执行一次的方法');
    this.count--;
});
// 调用
function reduceOnce() {
    app.$emit('reduceOnce');
}

// 关闭事件
function off(){
    console.log('关闭事件');
    app.$off('reduce');
}
</script>
</body>
</html>

自定义指令

vue中的自定义指令通过Vue.directive来实现,主要完成内置指令不能完成的一些事情

1、示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之自定义指令</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <div v-test="color">
        {{num}}
    </div>
</div>
<button onclick="unbindApp()">解绑</button>

<script type="text/javascript">
// 解绑
function unbindApp() {
    app.$destroy();
}

// 自定义指令
Vue.directive("test",{
    //1-被绑定
    bind:function (el, binding, vnode) {
        console.log("1-bind 被绑定");
        console.log("el:",el);
        console.log("binding:",binding);
        console.log("vnode:",vnode);
        el.style.color = binding.value;
    },
    //2-被插入
    inserted:function (el, binding, vnode) {
        console.log("2-inserted 被插入");
    },
    //3-更新
    update:function (el, binding, vnode) {
        console.log("3-update 更新");
    },
    //4-更新完成
    componentUpdated:function (el, binding, vnode) {
        console.log("4-componentUpdated 更新完成");
    },
    //5-解绑
    unbind:function (el, binding, vnode) {
        console.log("5-unbind 解绑");
    }
});

var app = new Vue({
    el:'#app',
    data:{
        num: 123,
        color:'red'
    }
})
</script>
</body>
</html>

2、调试步骤

(1)chrome打开控制器查看
(2)控制台输入“app.num=’通过控制台设置的新name’”
(3)点击解绑按钮

3、参数说明

  • el:指令所绑定的元素,可以用来直接操作DOM
  • binding: 一个对象,包含指令的很多信息
  • vnode::Vue编译生成的虚拟节点

4、生命周期

自定义指令有五个生命周期(也叫钩子函数),分别是bind、inserted、update、componentUpdated、unbind,说明如下:

  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作
  2. inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)
  3. update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用
  5. unbind:只调用一次,指令与元素解绑时调用

组件基础

1、组件注册

(1)全局注册

// script
Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    template: '<button v-on:click="count++">全局组件显示: {{ count }}</button>'
});

new Vue({
    el: '#app'
});

// html使用
<button-counter></button-counter>

(2)局部注册

// script
new Vue({
    el: '#app',
    components:{
        "button-inner":{
            data: function() {
                return {
                    inner: 0
                }
            },
            template: '<button v-on:click="inner++">局部组件显示: {{ inner }}</button>'
        }
    }
});

// html使用
<button-inner></button-inner>

2、props属性传值

(1)属性取值

// script
new Vue({
        el: '#app',
        components:{
            "button-props":{
                template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`,
                props:['here', 'fromHere']
            }
        }
    });

// html使用
<button-props here="hello" from-here="world"></button-props>

PS:如果属性带“-”,props中需要驼峰取值

(2)在构造器向组件传值(v-bind)

// script
new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        components:{
            "button-props":{
                template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`,
                props:['here', 'fromHere']
            }
        }
    });

// html使用
<button-props v-bind:here="message" :from-here="message"></button-props>

3、父子组件

// script
// 子组件
var city = {
    template:`<div>Sichuan of China</div>`
}
// 父组件
var parent = {
    template:
        `<div>
            <p> Panda from China!</p>
            <city></city>
        </div>`,
    components:{
        "city": city
    }
}

// 实例化
new Vue({
    el: '#app',
    // 定义局部组件
    components:{
        // 组件注册
        "parent": parent
    }
});

// html使用
<parent></parent>

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue入门之组件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <!-- 全局组件 -->
    <div><button-counter></button-counter></div>
    <!-- 局部组件 -->
    <div><button-inner></button-inner></div>
    <!-- 常规属性传值 -->
    <div><button-props here="hello" from-here="world"></button-props></div>
    <!-- v-bind传值 -->
    <div><button-props v-bind:here="message" :from-here="message"></button-props></div>
    <!-- 父子组件调用 -->
    <div><parent></parent></div>

</div>

<script type="text/javascript">
    // 定义全局组件
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">全局组件显示: {{ count }}</button>'
    });

    // 子组件
    var city = {
        template:`<div>Sichuan of China</div>`
    }
    // 父组件
    var parent = {
        template:
            `<div>
                <p> Panda from China!</p>
                <city></city>
            </div>`,
        components:{
            "city": city
        }
    }

    // 实例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        // 定义局部组件
        components:{
            "button-inner":{
                data: function() {
                    return {
                        inner: 0
                    }
                },
                template: '<button v-on:click="inner++">局部组件显示: {{ inner }}</button>'
            },
            // 取值
            "button-props":{
                template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`,
                props:['here', 'fromHere']
            },
            // 组件注册
            "parent": parent
        }
    });
</script>
</body>
</html>

制作模板

vue中的模板使用template来实现

1、选项模板

<div id="app">
</div>

<script type="text/javascript">
    // 实例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        template:`<h1 style="color:red">我是选项模板</h1>`
    });
</script>

2、标签模板

<div id="app">
    <template id="demo2">
        <h2 style="color:red">我是template标签模板</h2>
    </template>
</div>

<script type="text/javascript">
    // 实例化
    new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        template:'#demo2'
    });
</script>

3、