2020年微信小程序开发扫盲课程,第三篇:样式和布局

1. 尺寸单位。

1.1 rpx和px

微信小程序规定了特有的尺寸单位“rpx”。
原理是无视设备原有尺寸,将所有设备的屏幕宽度统一规定为750rpx。
比如,iPhone6的屏幕宽度像素为:375px,那么在iPhone6下,1rpx = 0.5px。
由于iPhone6的屏幕宽度与微信开发时的屏幕宽度换算为简单的1:2关系,所以实际开发时一般都使用iPhone6屏幕环境进行模拟开发。

1.2 vw和vh

vw和vh是css3中的新单位,是一种视窗单位,在小程序中也同样适用。

  • 小程序中,窗口宽度固定为100vw,将窗口宽度平均分成100份,1份是1vw
  • 小程序中,窗口高度固定为100vh ,将窗口高度平均分成100份,1份是1vh

2. 样式。

xsss样式和css样式的语法和运作方式非常相似,如果有css基础,xsss样式非常好理解。

2.1 样式写法。

和css一致:

class样式:.className{/*样式内容*/}
元素样式:elementName{/*样式内容*/}
内联样式:<element style="/*样式内容*/" />

2.2 常用属性。

基本上也和css一致:

color,font-size,background-color,border,width,height

2.3 样式导入。

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径。

3. Flex布局

微信小程序使用Flex布局。
有关Flex布局的详细说明请见:http://www.leonwish.com/archives/319

2020年微信小程序开发扫盲课程,第二篇:代码结构介绍

1. 程序总体架构。

通过微信小程序开发工具新建一个项目后,会自动生成项目框架代码如下:
file

2. 全局文件。

全局文件的文件名是固定的,不可随意指定。
程序入口文件:app.js,app.json,app.wxss
项目配置文件:project.config.json
配置小程序及其页面是否允许被微信索引:sitemap.json
公共方法和变量:utils/util.js

3. pages文件夹下的目录结构。

pages文件夹的名字是可以随便指定的,但是习惯上使用pages。
pages下面存放的是小程序里面的页面文件,一个小程序页面由四个“同名但不同扩展名”的文件组成,这个四个文件又被放在一个与这四个文件同名的文件夹中。
页面文件夹与四个对应的页面文件可以手工新建,也可以通过微信新建page的方式自动生成:
file

4个页面的运作方式和普通网页HTML+CSS+JS的运行方式非常相似,具体如下:

4.1 .js文件

负责实现页面逻辑。

4.2 .json文件

负责设置标题栏和一些状态参数。

4.3 .wxml文件

页面显示内容。类似HTML文件。

4.4 .wxss文件

负责设置页面排版。类似CSS文件。

2020年微信小程序开发扫盲课程,第一篇:开发准备

1. 前言

1.1 为啥标题要加个2020呢?

因为我是从2020年2月开始学的微信小程序开发,微信的生态时刻都在更新,用时间来标识一下以便让读者能够更好地判断本文是否适合。

1.2 微信小程序的语言逻辑和Vue.js有点像

还好我是先学了些Vue.js,开始做微信小程序的时候,发现代码结构和语法和Vue.js有很多相似的地方。
不过即使你没有学过Vue.js,只要你懂Javascript,一样可以做微信小程序开发。

2. 注册微信小程序账号

2.1 如果你没有微信【服务号】【订阅号】账号

进入微信公众平台:https://mp.weixin.qq.com
注册一个微信小程序开发账号。
file
然后
file
再然后
file

2.2 如果你有微信【服务号】【订阅号】账号

可以直接登陆【服务号】或【订阅号】账号,然后在该账号下面添加微信小程序账号。

3. 填写小程序基本信息。

file

4. 下载微信小程序开发工具

点击上方【文档】
file

点击上方【工具】然后选择合适的版本下载:
file

5. 使用微信小程序开发工具

5.1 安装、登陆程序

正常安装开发工具软件,安装完毕后打开,默认出现下面的登录框:
file
用你注册小程序时认证的微信号扫描二维码即可登陆进入软件开发环境。

5.2 添加新的小程序项目

file
然后看到下面的页面:
file
上面创建小程序的时候填写的AppID要到微信公众平台里面查找:
file
点击【创建】按钮后,进入开发环境:
file

Flex布局语法

前言

本文摘自:https://www.runoob.com/w3cnote/flex-grammar.html

网页布局(layout)是CSS的一个重点应用。
file

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

file

Flex布局将成为未来布局的首选方案。本文介绍Flex布局的语法。

1. Flex布局是什么?

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

任何一个容器都可以指定为Flex布局。

.box{
  display: flex;
}

行内元素也可以使用Flex布局。

.box{
  display: inline-flex;
}

Webkit内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

2. 基本概念

采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。

file

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

3. 容器的属性

以下6个属性设置在容器上。

  1. flex-direction
  2. flex-wrap
  3. flex-flow
  4. justify-content
  5. align-items
  6. align-content

3.1 flex-direction属性

flex-direction属性决定主轴的方向(即项目的排列方向)。

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

file
它可能有4个值:

  1. row(默认值):主轴为水平方向,起点在左端。
  2. row-reverse:主轴为水平方向,起点在右端。
  3. column:主轴为垂直方向,起点在上沿。
  4. column-reverse:主轴为垂直方向,起点在下沿。

3.2 flex-wrap属性

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

file
它可能取三个值:

  1. nowrap(默认):不换行。
    file
  2. wrap:换行,第一行在上方。
    file
  3. wrap-reverse:换行,第一行在下方。
    file

3.3 flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。

.box {
  flex-flow: <flex-direction> <flex-wrap>;
}

3.4 justify-content属性

justify-content属性定义了项目在主轴上的对齐方式。

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

file

它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右:

  1. flex-start(默认值):左对齐
  2. flex-end:右对齐
  3. center: 居中
  4. space-between:两端对齐,项目之间的间隔都相等。
  5. space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

3.5 align-items属性

align-items属性定义项目在交叉轴上如何对齐。

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

file
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下:

  1. flex-start:交叉轴的起点对齐。
  2. flex-end:交叉轴的终点对齐。
  3. center:交叉轴的中点对齐。
  4. baseline: 项目的第一行文字的基线对齐。
  5. stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

3.6 align-content属性

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

file

该属性可能取6个值:

  1. flex-start:与交叉轴的起点对齐。
  2. flex-end:与交叉轴的终点对齐。
  3. center:与交叉轴的中点对齐。
  4. space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  5. space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  6. stretch(默认值):轴线占满整个交叉轴。

4.项目的属性

以下6个属性设置在项目上:

  1. order
  2. flex-grow
  3. flex-shrink
  4. flex-basis
  5. flex
  6. align-self

4.1 order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
  order: <integer>;
}

file

4.2 flex-grow属性

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /* default 0 */
}

file
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

4.3 flex-shrink属性

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

.item {
  flex-shrink: <number>; /* default 1 */
}

file
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

负值对该属性无效。

4.4 flex-basis属性

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis: <length> | auto; /* default auto */
}

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

4.5 flex属性

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

4.6 align-self属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

file
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

Python查询MySQL数据库并将查询结果输出到csv文件

1. 安装Python链接MySQL插件。

$ pip3 install PyMySQL

2. 完整代码如下:

import os
import pymysql

sku = []

#定义递归函数findPNG,寻找当前目录下所有png类型的文件
def findPNG(sku,dir):
    for ffName in os.listdir(dir):
        if os.path.isfile(dir+"/"+ffName):
            if ffName.split(".")[1] == "png":
                sku.append(ffName.split(".")[0]);
        elif os.path.isdir(dir+"/"+ffName):
            findPNG(sku,dir+"/"+ffName)
findPNG(sku,"./")

h = open("./ProductsInformation.csv","a")
db = pymysql.connect("地址","用户","密码","数据库名" )
cursor = db.cursor()

for s in sku:
    SQL = '''SELECT t1.model,t2.name,t2.tag
             FROM `product` AS t1, `product_description` AS t2
             WHERE t1.product_id = t2.product_id AND t1.model ="{}"'''.format(s)
    cursor.execute(SQL)
    data = cursor.fetchone()
    if data:
        for d in data:
            h.write('"'+d+'",')
        h.write('\n')
    else:
        print(s)

h.close()
db.close()

通过Vue-cli创建Vue项目流程

0 .Vue.js,Vue-cli,Node.js的理解。

一个js文件就是Vue.js

项目中,通过<script>标签引入一个vue.js文件,这就是我们理解的Vue.js。

命令行里运行vue就是Vue-cli

如果想要在cmd里面运行vue命令,那么就需要安装vue-cli工具。

Node.js就是Javascript的JVM

Node.js就好像是Javascript世界里面的JVM。
vue-cli工具是通过npm的安装的。

1. 安装Node.js

Node.js环境具体安装方法见:http://www.leonwish.com/archives/278

2. 安装vue-cli

vue-cli在vue官网上叫做“脚手架工具”,其实就是个vue的客户端(client)。安装命令如下:

npm install -g vue-cli  //这是npm命令

3. 基于webpack-simple初始化项目

当然,你可以不基于webpack-simple初始化项目,通过vue list命令可以看到,有以下几种初始化方式备选:
file
通过命令行切换到你的项目创建目录,运行如下命名:

vue init webpack-simple my-project //这是vue命令

这时,基于webpack-simple创建的项目就建好了。

4. 安装相关的依赖。

第三步只是创建了项目骨架,在你实际运行这个项目前,还需要根据自动生成的package.json文件,安装相关的依赖,安装依赖命令如下:

cd my-project //先进到项目目录。
npm install //或者cnpm install,这是npm命令

5. 运行项目

npm run dev //这也是npm命令,npm run命令将会运行项目中的package.json文件中的script部分内容。run后面跟dev,就是运行package.json文件中script部分的dev部分内容。

Vue.js组件学习(4)高级篇—单文件组件

1. 单文件组件的意义。

在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素。

这种方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:

  • 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
  • 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器,如 Pug (formerly Jade) 和 Babel

文件扩展名为 .vue 的 single-file components(单文件组件) 为以上所有问题提供了解决方法,并且还可以使用 webpack 或 Browserify 等构建工具。

2. 单文件组建的使用环境搭建。

在本机安装:

  • npm(Node.js)
  • vue-cli
  • webpack

3. 单文件组件的结构。

<template>
</template>

<script>
</script>

<style>
</style>

4. 第一个单文件组件的例子。

4.1 新建一个Vue项目

可以通过vue命令行创建:

vue init webpack 项目名

也可以通过HBuilder创建:

4.2 创建完的项目目录结构如下:

file

  • node_modules:依赖文件
  • public:静态文件
  • src
    • assets:资源文件
    • components:单文件组件文件
    • App.vue:项目入口文件
    • main.js:主js文件

4.3 新建test.vue

在components下新建test.vue文件,内容如下:

<template>
    <button>{{btncontent}}</button>
</template>

<script>
    export default{
        props:["btncontent"],
        data:function(){
            return {
            }
        }
    }
</script>

<style>
</style>

4.4 修改App.vue

<template>
  <div id="app">
    <SuperButton btncontent="点我吧!"></SuperButton>
  </div>
</template>

<script>
import SuperButton from './components/test.vue'

export default {
  components: {
    SuperButton
  }
}
</script>

<style>
</style>

这样就可以了!

Vue.js组件学习(3)升级篇

1. 组件的命名规则

1.1 两种命名可选方案

使用kebab-case(短横线分隔命名)方法命名

Vue.component('my-component-name', { /* ... */ })
当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用PascalCase(驼峰命名法)方法命名

Vue.component('MyComponentName', { /* ... */ })
当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

1.2 强烈建议使用kebab-case命名法

命名组件的时候,强烈推荐使用kebab-case方法命名。这样可以避免和HTML既有元素相冲突。

2. 组件中的props命名规则

HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用DOM中的模板时,camelCase (驼峰命名法)的prop名需要使用其等价的kebab-case(短横线分隔命名)命名:

Vue.component('blog-post', {
  // 在 JavaScript 中是 camelCase 的
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>

如果你使用字符串模板,那么这个限制就不存在了。

3. 组建的全局注册和局部注册

3.1 全局注册和使用。

Vue.component("Com-Name",{...});

全局注册后,任何新创建的Vue根实例id对应的模板中都可以直接使用。

3.2 局部注册和使用

var newCom = {...}

局部注册后,如果需要使用,则需要在创建的Vue的components选项中先定义你想要使用的组件。

var vm = new Vue({
el:"app",
components:{
    'new-com':newCom
}
data:{}
});

Vue.js组件学习(2)进阶篇

1. 监听子组件事件

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            <div v-bind:style="{fontSize:newsFontSize+'px'}">
                Hello Component!<br/>
                <news-show v-for="item in news" v-bind:newsprops="item" v-on:zoom-in-text="newsFontSize+=1"></news-show>
            </div>
        </div>    
        <script type="text/javascript">
            Vue.component("news-show",{
                template:`<p>
                          <span>TITLE:{{newsprops.title}}</span> 
                          <span>CONTENT:{{newsprops.content}}</span> 
                          <span>TIME:{{newsprops.time}}</span> 
                          <button v-on:click="$emit(\'zoom-in-text\')">放大文字</button>
                          </p>`,
                props:["newsprops"]
            });
            var vm = new Vue({
                el:app,
                data:{
                    news:[
                        {title:"标题1",content:"内容1",time:"2020-01-01"},
                        {title:"标题2",content:"内容2",time:"2020-01-02"},
                        {title:"标题3",content:"内容3",time:"2020-01-03"},
                        ],
                    newsFontSize:20
                }
            });
        </script>
    </body>
</html>

以上代码理解方式如下:
file

2. 使用事件抛出一个值

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            <div v-bind:style="{fontSize:newsFontSize+'px'}">
                Hello Component!<br/>
                <news-show v-for="item in news" v-bind:newsprops="item" v-on:zoom-in-text="newsFontSize+=$event"></news-show>
            </div>
        </div>    
        <script type="text/javascript">
            Vue.component("news-show",{
                template:`<p>
                          <span>TITLE:{{newsprops.title}}</span> 
                          <span>CONTENT:{{newsprops.content}}</span> 
                          <span>TIME:{{newsprops.time}}</span> 
                          <button v-on:click="$emit('zoom-in-text',5)">放大文字</button>
                          </p>`,
                props:["newsprops"]
            });
            var vm = new Vue({
                el:app,
                data:{
                    news:[
                        {title:"标题1",content:"内容1",time:"2020-01-01"},
                        {title:"标题2",content:"内容2",time:"2020-01-02"},
                        {title:"标题3",content:"内容3",time:"2020-01-03"},
                        ],
                    newsFontSize:20
                }
            });
        </script>
    </body>
</html>

以上代码理解方式如下:

file

3. 组件的插槽功能

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            <div v-bind:style="{fontSize:newsFontSize+'px'}">
                Hello Component!<br/>
                <news-show v-for="item in news" v-bind:newsprops="item" v-on:zoom-in-text="newsFontSize+=$event">插槽内容,哈哈哈!</news-show>
            </div>
        </div>    
        <script type="text/javascript">
            Vue.component("news-show",{
                template:`<p>
                          <span>TITLE:{{newsprops.title}}</span> 
                          <span>CONTENT:{{newsprops.content}}</span> 
                          <slot></slot>
                          <span>TIME:{{newsprops.time}}</span> 
                          <button v-on:click="$emit('zoom-in-text',5)">放大文字</button>
                          </p>`,
                props:["newsprops"]
            });
            var vm = new Vue({
                el:app,
                data:{
                    news:[
                        {title:"标题1",content:"内容1",time:"2020-01-01"},
                        {title:"标题2",content:"内容2",time:"2020-01-02"},
                        {title:"标题3",content:"内容3",time:"2020-01-03"},
                        ],
                    newsFontSize:20
                }
            });
        </script>
    </body>
</html>

以上内容的重点如下:
file

Vue.js组件学习(1)基础篇

关于Vue.js官网教程的点点疑问

我是通过Vue.js官网(https://cn.vuejs.org) 学习的Vue技术,先看的视频,后看的文档。
在看视频教程的时候,主讲人说的英文差到我怀疑人生,我当时在想:Vue.js的创始人不是在美国留学的高材生吗?怎么英语还会这么差?不过转念一想,主讲人肯定不是创始人呀,所以英文差也是可以理解的。
然后我又看的文档教程,文档教程中文语言的晦涩程度又让我咋舌,感觉像是硬生生的从英文直译过来的一样。
所以呢,真心建议Vue.js好好的优化一下教程。
以下内容是我综合了Vue.js官网和诸多教程的内容,用相对简单的话素进行了描述,希望能帮到初学者。

1. 什么是组件

组件可以理解为将某些控件、功能集成在一起的类。
在代码中调用页面的方法是:<组件名></组件名>
作为初学者,我更愿意把组件理解为“自定义标签”,将若干复杂的空间、功能封装在一个标签内,然后再去调用。比如,你可以把网页导航条的全部代码封装在组件中。

2. 最简单的组件的定义和使用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            Hello Component!<br/>
            <button-counter></button-counter>
        </div>

        <script type="text/javascript">
            Vue.component("button-counter",{
                template:'<button>Button Counter</button>',
            });

            var vm = new Vue({
                el:app
            });
        </script>
    </body>
</html>

这里面的逻辑关系是这样的:

  1. 定义(注册)一个组件。
  2. 通过new Vue创建Vue的根实例。
  3. 在Vue的根实例中使用已经定义(注册)的组件。

注意:

  • 1、2步顺序不可以颠倒,也就是说,组件要先于Vue根实例定义(注册)。
  • 组件的定义(注册)有两种形式:全局注册局部注册,本例中的组件是采用全局注册的形式进行定义(注册)的。
  • 全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的Vue根实例中,也包括其组件树中的所有子组件的模板中。

file

3. 给组件增加data

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            Hello Component!<br/>
            <button-counter></button-counter>
        </div>

        <script type="text/javascript">
            Vue.component("button-counter",{
                template:'<button v-on:click="count++">Button Counter {{count}} times!</button>',
                data:function(){
                    return {count:0};
                }
            });
            var vm = new Vue({
                el:app
            });
        </script>
    </body>
</html>

上面的代码实现了<button-counter>组件的点击自增功能,这里面值得注意的如下:

  1. 可以为组件增加data选项。但data并不是像在new Vue定义时对应一个对象:data: {count: 0};取而代之的是,一个组件的data选项必须对应一个函数,这样每个组件的实例可以单独维护一份独立的拷贝。如果Vue没有这条规则,则组件实例间的data选项则是共享的。
  2. 组件data选项中的元素可以在组件template中被使用。
    file

4. 给组件增加props进行简单数据交互

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            Hello Component!<br/>
            <button-counter title="你好!属性"></button-counter>
        </div>

        <script type="text/javascript">
            Vue.component("button-counter",{
                template:'<button v-on:click="count++">{{title}} Button Counter {{count}} times!</button>',
                data:function(){
                    return {count:0};
                },
                props:["title"]
            });
            var vm = new Vue({
                el:app
            });
        </script>
    </body>
</html>

上面的代码值得注意的如下:
file

5. 给组件增加props进行复杂数据交互

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            Hello Component!<br/>
            <news-show v-for="item in news" v-bind:title="item.title" v-bind:content="item.content" v-bind:time="item.time"></news-show>
        </div>    
        <script type="text/javascript">
            Vue.component("news-show",{
                template:'<p><span>TITLE:{{title}}</span> <span>CONTENT:{{content}}</span> <span>TIME:{{time}}</span></p>',
                props:["title","content","time"]
            });
            var vm = new Vue({
                el:app,
                data:{
                    news:[
                        {title:"标题1",content:"内容1",time:"2020-01-01"},
                        {title:"标题2",content:"内容2",time:"2020-01-02"},
                        {title:"标题3",content:"内容3",time:"2020-01-03"},
                        ]
                }
            });
        </script>
    </body>
</html>

上面这个复杂些,理解方法如下:
file

6. 对第5部分的属性交换代码进行简化。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>About Component</title>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            Hello Component!<br/>
            <news-show v-for="item in news" v-bind:newsprops="item"></news-show>
        </div>    
        <script type="text/javascript">
            Vue.component("news-show",{
                template:'<p><span>TITLE:{{newsprops.title}}</span> <span>CONTENT:{{newsprops.content}}</span> <span>TIME:{{newsprops.time}}</span></p>',
                props:["newsprops"]
            });
            var vm = new Vue({
                el:app,
                data:{
                    news:[
                        {title:"标题1",content:"内容1",time:"2020-01-01"},
                        {title:"标题2",content:"内容2",time:"2020-01-02"},
                        {title:"标题3",content:"内容3",time:"2020-01-03"},
                        ]
                }
            });
        </script>
    </body>
</html>

上面这部分可能更加不好理解,解释如下:
file