学习进度条 第九十一-第一百零五天 vue+uniapp app开发学习笔记

大佬整理的狂神老师的vue笔记+源码

https://gitee.com/lzh_gitee/Vue/tree/master/

其实原本并没有打算学vue,但是民子哥的第二个组队作业让我被迫学了vue
因为用uniapp做简单的开发加多平台发布真的很方便

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

狂神说 Vue 笔记

Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。

HTML + CSS + JS : 视图 : 给用户看,刷新后台给的数据

网络通信 : axios

页面跳转 : vue-router

状态管理:vuex

Vue-UI : ICE , Element UI

一、前端核心分析

1. VUE 概述

Vue (读音 / vju/, 类似于 view)是一套用于构建用户界面的渐进式框架,发布于 2014 年 2 月。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库 (如: vue-router: 跳转,vue-resource: 通信,vuex: 管理) 或既有项目整合

2. 前端三要素

  • HTML (结构) : 超文本标记语言 (Hyper Text Markup Language) ,决定网页的结构和内容
  • CSS (表现) : 层叠样式表 (Cascading Style sheets) ,设定网页的表现样式
  • JavaScript (行为) : 是一种弱类型脚本语言,其源代码不需经过编译,而是由浏览器解释运行, 用于控制网页的行为

3. JavaScript 框架

  • jQuery: 大家熟知的 JavaScript 框架,优点是简化了 DOM 操作,缺点是 DOM 操作太频繁, 影响前端性能; 在前端眼里使用它仅仅是为了兼容 IE6、7、8;

  • Angular: Google 收购的前端框架,由一群 Java 程序员开发,其特点是将后台的 MVC 模式搬到了前端并增加了模块化开发的理念,与微软合作,采用 TypeScript 语法开发; 对后台程序员友好,对前端程序员不太友好; 最大的缺点是版本迭代不合理 (如: 1 代 -> 2 代,除了名字,基本就是两个东西; 截止发表博客时已推出了 Angular6)

  • React: Facebook 出品,一款高性能的 JS 前端框架; 特点是提出了新概念 [虚拟 DOM] 用于减少真实 DOM 操作,在内存中模拟 DOM 操作,有效的提升了前端渲染效率; 缺点是使用复杂,因为需要额外学习一门[JSX] 语言;

  • Vue: 一款渐进式 JavaScript 框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了 Angular (模块化) 和 React (虚拟 DOM) 的优点;

  • Axios : 前端通信框架; 因为 Vue 的边界很明确,就是为了处理 DOM, 所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互; 当然也可以直接选择使用 jQuery 提供的 AJAX 通信功能;

    前端三大框架:Angular、React、Vue

二、第一个 Vue 程序

1. 什么是 MVVM

MVVM (Model-View-ViewModel) 是一种软件架构设计模式,由微软 WPF (用于替代 WinForm,以前就是用这个技术开发桌面应用程序的) 和 Silverlight (类似于 Java Applet, 简单点说就是在浏览器上运行的 WPF) 的架构师 Ken Cooper 和 Ted Peters 开发,是一种简化用户界面的事件驱动编程方式。由 John Gossman (同样也是 WPF 和 Silverlight 的架构师) 于 2005 年在他的博客上发表。

MVVM 源自于经典的 MVC (ModI-View-Controller) 模式。MVVM 的核心是 ViewModel 层,负责转换 Model 中的数据对象来让数据变得更容易管理和使用,其作用如下:

  • 该层向上与视图层进行双向数据绑定
  • 向下与 Model 层通过接口请求进行数据交互

2. 为什么要使用 MVVM

MVVM 模式和 MVC 模式一样,主要目的是分离视图 (View) 和模型(Model), 有几大好处:

  • 低耦合: 视图 (View) 可以独立于 Model 变化和修改, 一个 ViewModel 可以绑定到不同的
    View 上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变。
  • 可复用: 你可以把一些视图逻辑放在一个 ViewModel 里面,让很多 View 重用这段视图逻辑。
  • 独立开发: 开发人员可以专注于业务逻辑和数据的开发 (ViewModel), 设计人员可以专注于页面设计。
  • 可测试: 界面素来是比较难于测试的,而现在测试可以针对 ViewModel 来写。

3. Vue 是 MVVM 模式的实现者

  • Model : 模型层,在这里表示 JavaScript 对象

  • View : 视图层, 在这里表示 DOM (HTML 操作的元素)

  • ViewModel : 连接视图和数据的中间件,Vue.js 就是 MVVM 中的 ViewModel 层的实现者在 MVVM 架构中,是不允许数据和视图直接通信的,只能通过 ViewModel 来通信,而 ViewModel 就是定义了一个 Observer 观察者

  • ViewModel 能够观察到数据的变化,并对视图对应的内容进行更新

  • ViewModel 能够监听到视图的变化,并能够通知数据发生改变

至此,我们就明白了,Vue.js 就是一个 MVVM 的实现者,他的核心就是实现了 DOM 监听数据绑定

Vue 在线 cdn:

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

三、Vue 基本语法

1. v-bind

​ 现在数据和 DOM 已经被建立了关联,所有的东西都是响应式的。我们在控制台操作对象的属性,界面可以实时更新。

​ 我们可以使用v-bind来绑定元素属性!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>狂神说Java</p>

<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            message: "hello,vue"
        }
    })
</script>
</html>

2. v-if v-else

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
<p>狂神说Java</p>

<!--view层 模板-->
<div id="app">
   <h1 v-if="type==='A'">A</h1>
   <h1 v-else-if="type==='B'">B</h1>
   <h1 v-else>C</h1>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
   var vm = new Vue({
       el: "#app",
       data: {
           type: "A"
       }
   })
</script>
</html>

3. v-for

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>狂神说Java</p>

<!--view层 模板-->
<div id="app">
    <li v-for="item in items">
        姓名:{{item.name}},年龄:{{item.age}}
    </li>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            items: [
                {name: "zhangsan", age: 12},
                {name: "lisi", age: 10},
                {name: "wangwu", age: 16}
            ]
        }
    })
</script>
</html>

4. v-on 事件绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>狂神说Java</p>

<!--view层 模板-->
<div id="app">
    <button v-on:click="sayHi">Click Me</button>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            message: "你点我干嘛?"
        },
        methods: {
            //方法必须绑定在Vue的Methods对象中,v-on:事件
            sayHi: (function (event) {
                alert(this.message)
            })
        }
    })
</script>
</html>

四、Vue 双向绑定 v-model

1. 什么是双向绑定

​ Vue.js 是一个 MVVM 框架,即数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是 Vue.js 的精髓之处了。

​ 值得注意的是,我们所说的数据双向绑定,一定是对于 UI 控件来说的,非 UI 控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用 vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。

2. 为什么要实现数据的双向绑定

在 Vue.js 中,如果使用 vuex ,实际上数据还是单向的,之所以说是数据双向绑定,这是用的 UI 控件来说,对于我们处理表单,Vue.js 的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项, 方便跟踪; 局部性数据流使用双向,简单易操作。

3. 在表单中使用双向数据绑定

你可以用v-model指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

注意:v-model 会忽略所有元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源,你应该通过 JavaScript 在组件的 data 选项中声明。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    下拉框:
    <select v-model="selected">
        <option value="" disabled>-请选择-</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <p>value:{{selected}}</p>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            selected: ""
        }
    })
</script>
</html>

五、Vue 组件

​ 组件是可复用的Vue实例,说白了就是一组可以重复使用的模板,跟 JSTL 的自定义标签、Thymeleaf 的th:fragment 等框架有着异曲同工之妙。通常一个应用会以一棵嵌套的组件树的形式来组织:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    <qinjiang v-for="item in items" v-bind:qin="item"></qinjiang>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    Vue.component("qinjiang",{
        props: ['qin'],
        template: '<li>{{qin}}</li>'
    })

    var vm = new Vue({
        el: "#app",
        data: {
            items: ['Java','Python','Php']
        }
    })
</script>
</html>

六、Axios 通信

1. 什么是 Axios

Axios 是一个开源的可以用在浏览器端和NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests

  • 从 node.js 创建 http 请求

  • 支持 Promise API [JS 中链式编程]

  • 拦截请求和响应

  • 转换请求数据和响应数据

  • 取消请求

  • 自动转换 JSON 数据

  • 客户端支持防御 XSRF (跨站请求伪造)

    GitHub: https://github.com/ axios/axios
    中文文档: http://www.axios-js.com/

2. 为什么要使用 Axios

​ 由于Vue.js是一个视图层框架且作者 (尤雨溪) 严格准守 SoC (关注度分离原则),所以Vue.js并不包含 Ajax 的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource的插件,不过在进入 2.0 版本以后停止了对该插件的维护并推荐了Axios 框架。少用 jQuery,因为它操作 Dom 太频繁 !

模拟 Json 数据:

{
  "name": "weg",
  "age": "18",
  "sex": "男",
  "url":"https://www.baidu.com",
  "address": {
    "street": "文苑路",
    "city": "南京",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://www.bilibili.com"
    },
    {
      "name": "baidu",
      "url": "https://www.baidu.com"
    },
    {
      "name": "cqh video",
      "url": "https://www.4399.com"
    }
  ]
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层 模板-->
<div id="vue">
    <div>{{info.name}}</div>
    <a v-bind:href="info.url">点我进入</a>
</div>
</body>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<!--导入axios-->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>

    var vm = new Vue({
        el: "#vue",
        data: {
            items: ['Java','Python','Php']
        },
        //data:vm的属性
        //data():vm方法
        data(){
            return{
                //请求的返回参数,必须和json字符串一样
               info:{
                   name: null,
                   age: null,
                   sex: null,
                   url: null,
                   address: {
                       street: null,
                       city: null,
                       country: null
                   }
               }
            }
        },
        //钩子函数,链式编程,ES6新特性
        mounted(){
            axios.get("../data.json").then(res => (this.info=res.data))
        }
    })
</script>
</html>

3. Vue 计算属性

计算属性的重点突出在属性两个字上 (属性是名词),首先它是个属性其次这个属性有计算的能力 (计算是动词),这里的计算就是个函数; 简单点说,它就是一个能够将计算结果缓存起来的属性 (将行为转化成了静态的属性),仅此而已; 可以想象为缓存

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    <div>currentTime1: {{currentTime1()}}</div>
    <div>currentTime2: {{currentTime2}}</div>
</div>
</body>

<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            message: "hello,world!"
        },
        methods: {
            currentTime1: function () {
                return Date.now(); // 返回一个时间戳
            }
        },
        computed: {
            //计算属性:methods,computed 方法名不能重名,重名字后,只会调用methods的方法
            currentTime2: function () {
                this.message;
                // 返回一个时间戳
                return Date.now();
            }
        }
    })
</script>
</html>

结论:
 调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢? 此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点, 计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;

七、内容分发 slot

在 Vue.js 中我们使用 元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:></todo-title>
        <todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
    </todo>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //slot 插槽 这个组件要定义在前面不然出不来数据
    Vue.component("todo", {
        template: '<div>\
                <slot ></slot>\
                <ul>\
                <slot ></slot>\
                </ul>\
                <div>'
    });
    Vue.component("todo-title", {
        //属性
        props: ['name'],
        template: '<div>{{name}}</div>'
    });
    Vue.component("todo-items", {
        props: ['item'],
        template: '<li>{{item}}</li>'
    });
    let vm = new Vue({
        el: "#app",
        data: {
            //标题
            title: "图书馆系列图书",
            //列表
            todoItems: ['三国演义', '红楼梦', '西游记', '水浒传']
        }
    });
</script>
</body>
</html>


八、自定义事件内容分发

​ 通过以上代码不难发现,数据项在 Vue 的实例中,但删除操作要在组件中完成,那么组件如何才能删除 Vue 实例中的数据呢? 此时就涉及到参数传递与事件分发了,Vue 为我们提供了自定义事件的功能很好的帮助我们解决了这个问题;

​ 使用this.$emit (‘自定义事件名’,参数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:></todo-title>
        <todo-items slot="todo-items" v-for="(item,index) in todoItems" v-bind:item="item"
                    v-bind:index="index" v-on:remove="removeItems(index)"></todo-items>
    </todo>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //slot 插槽 这个组件要定义在前面不然出不来数据
    Vue.component("todo", {
        template: '<div>\
                <slot ></slot>\
                <ul>\
                <slot ></slot>\
                </ul>\
                <div>'
    });
    Vue.component("todo-title", {
        //属性
        props: ['name'],
        template: '<div>{{name}}</div>'
    });
    Vue.component("todo-items", {
        props: ['item','index'],
        template: '<li>{{index}}---{{item}} <button @click="remove">删除</button></li>',
        methods: {
            remove: function (index) {
                // this.$emit 自定义事件分发
                this.$emit('remove',index)
            }
        }
    });
    let vm = new Vue({
        el: "#app",
        data: {
            //标题
            title: "图书馆系列图书",
            //列表
            todoItems: ['三国演义', '红楼梦', '西游记', '水浒传']
        },
        methods: {
            removeItems: function (index) {
                console.log("删除了"+this.todoItems[index]+"OK");
                this.todoItems.splice(index,1);
            }
        }
    });
</script>
</body>
</html>

九、第一个 vue-cli 项目

1. 什么是 vue-cli

​ vue-cli 官方提供的一个脚手架, 用于快速生成一个 vue 的项目模板;

​ 预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架, 我们的开发更加的快速;

主要功能:

  • 统一的目录结构
  • 本地调试
  • 热部署
  • 单元测试
  • 集成打包上线

2. 需要的环境

确认 nodejs 安装成功:

  • cmd 下输入 node -v, 查看是否能够正确打印出版本号即可!
  • cmd 下输入 npm-v, 查看是否能够正确打印出版本号即可!

这个 npm, 就是一个软件包管理工具, 就和 linux 下的 apt 软件安装差不多!

npm 是 JavaScript 世界的包管理工具, 并且是 Node.js 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码, 管理项目依赖关系。

安装 Node.js 淘宝镜像加速器(cnpm)

这样子的话, 下载会快很多~

# -g 就是全局安装
npm install cnpm -g

# 若安装失败,则将源npm源换成淘宝镜像
# 因为npm安装插件是从国外服务器下载,受网络影响大
npm config set registry https://registry.npm.taobao.org

# 然后再执行
npm install cnpm -g

安装的位置: C:\Users\Administrator\AppData\Roaming\npm

3. 安装 vue-cli

#在命令台输入
cnpm install vue-cli -g
#查看是否安装成功
vue list

4. 第一个 vue-cli 应用程序

创建一个 Vue 项目, 我们随便建立一个空的文件夹在电脑上。

​ 我这里在 D 盘下新建一个目录 D:\Project\vue-study;

创建一个基于 webpack 模板的 vue 应用程序

# 这里的 myvue 是项目名称,可以根据自己的需求起名
vue init webpack myvue

​ 一路都选择 no 即可;

​ 初始化并运行

cd myvue
npm install
npm run dev

​ 执行完成后, 目录多了很多依赖

十、Webpack

​ WebPack 是一款模块加载器兼打包工具,它能把各种资源,如 JS、JSX、ES6、SASS、LESS、图片等都作为模块来处理和使用。

npm install webpack -g
npm install webpack-cli -g

​ 测试安装成功: 输入以下命令有版本号输出即为安装成功

webpack -v
webpack-cli -v

1. 什么是 Webpack

​ 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器 (module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图 (dependency graph), 其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle.
 Webpack 是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过 loader 转换,任何形式的资源都可以当做模块,比如 CommonsJS、AMD、ES6、 CSS、JSON、CoffeeScript、LESS 等;
 伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了 WebApp 模式。它们运行在现代浏览器里,使用 HTML5、CSS3、ES6 等新的技术来开发丰富的功能,网页已经不仅仅是完成浏览器的基本需求; WebApp 通常是一个 SPA (单页面应用) ,每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的 JS 代码,这给前端的开发流程和资源组织带来了巨大挑战。
 前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。

2. 使用 Webpack

  1. 先创建一个包 交由 idea 打开 会生成一个. idea 文件 那么就说明该文件就交由 idea 负责

  2. 在 idea 中创建 modules 包,再创建 hello.js,hello.js 暴露接口 相当于 Java 中的类

    //暴露一个方法
    exports.sayHi = function () {
        document.write("<h1>狂神说ES6</h1>>")
    }
    
    
  3. 创建 main.js 当作是 js 主入口 , main.js 请求 hello.js 调用 sayHi() 方法

    var hello = require("./hello");
    hello.sayHi()
    
    
  4. 在主目录创建 webpack-config.js , webpack-config.js 这个相当于 webpack 的配置文件

    enrty 请求 main.js 的文件

    output 是输出的位置和名字

    module.exports = {
        entry: './modules/main.js',
        output: {
            filename: './js/bundle.js'
        }
    }
    
    
  5. 在 idea 命令台输入 webpack 命令(idea 要设置管理员启动)

  6. 完成上述操作之后会在主目录生成一个 dist 文件 生成的 js 文件夹路径为 / dist/js/bundle.js

  7. 在主目录创建 index.html 导入 bundle.js
    index.html

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="dist/js/bundle.js"></script>
    </head>
    <body>
    </body>
    </html>
    
    

十一、vue-router 路由

​ Vue Router 是 Vue.js 官方的路由管理器(路径跳转)。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由 / 视图表

  • 模块化的、基于组件的路由配置

  • 路由参数、查询、通配符

  • 基于 Vue.js 过渡系统的视图过渡效果

  • 细粒度的导航控制

  • 带有自动激活的 CSS class 的链接

  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级

  • 自定义的滚动条行为

1. 安装

​ 基于第一个 vue-cli 进行测试学习; 先查看 node_modules 中是否存在 vue-router
 vue-router 是一个插件包,所以我们还是需要用 npm/cnpm 来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

npm install vue-router --save-dev

​ 安装完之后去node_modules路径看看是否有 vue-router 信息 有的话则表明安装成功。

2. vue-router demo 实例

  1. 将之前案例由 vue-cli 生成的案例用 idea 打开

  2. 清理不用的东西 assert 下的 logo 图片 component 定义的 helloworld 组件 我们用自己定义的组件

  3. 清理代码 以下为清理之后的代码 src 下的 App.vue 和 main.js 以及根目录的 index.html
    这三个文件的关系是 index.html 调用main.js 调用App.vue

    index.html:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta >
        <title>myvue</title>
      </head>
      <body>
        <div></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
    

    main.js:

    import Vue from 'vue'
    import App from './App'
    import router from './router' //自动扫描里面的路由配置
    
    Vue.config.productionTip = false
    
    new Vue({
      el: '#app',
      //配置路由
      router,
      components: { App },
      template: '<App/>'
    })
    
    

    App.vue:

    <template>
      <div>
        <img src="./assets/logo.png">
        <h1>迪师傅</h1>
    
        <router-link to="/main">首页</router-link>
        <router-link to="/content">内容页</router-link>
        <router-link to="/kuang">Kuang</router-link>
        <router-view></router-view>
    
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
      }
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    
  4. 在 components 目录下创建一个自己的组件 Content,Test,Main(这两个和 Content 内容一样的就不放示例代码了

Content.vue:

<template>
  <h1>内容</h1>
</template>

<script>
    export default {
        name: "Content"
    }
</script>

<style scoped>

</style>

  1. 安装路由, 在 src 目录下, 新建一个文件夹 : router, 专门存放路由 index.js(默认配置文件都是这个名字)

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Content from "../components/Content";
    import Main from "../components/Main";
    import Kuang from "../components/Kuang";
    
    //安装路由
    Vue.use(VueRouter);
    
    //配置导出路由
    export default new VueRouter({
      routes: [
        {
          //路由路径
          path: '/content',
          name: 'content',
          //跳转的组件
          component: Content
        },
        {
          //路由路径
          path: '/main',
          name: 'main',
          //跳转的组件
          component: Main
        },
        {
          //路由路径
          path: '/kuang',
          name: 'kuang',
          //跳转的组件
          component: Kuang
        }
      ]
    })
    
    
  2. 在 main.js 中配置路由

    main.js:

    import Vue from 'vue'
    import App from './App'
    import router from './router' //自动扫描里面的路由配置
    
    Vue.config.productionTip = false
    
    new Vue({
      el: '#app',
      //配置路由
      router,
      components: { App },
      template: '<App/>'
    })
    
    
  3. 在 App.vue 中使用路由

    App.vue:

    <template>
      <div>
        <img src="./assets/logo.png">
        <h1>迪师傅</h1>
    
        <router-link to="/main">首页</router-link>
        <router-link to="/content">内容页</router-link>
        <router-link to="/kuang">Kuang</router-link>
        <router-view></router-view>
    
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
      }
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    
  4. 启动测试一下 : npm run dev

  5. 项目结构图 & 运行效果图


十二、vue + ElementUI

根据之前创建 vue-cli 项目一样再来创建一个新项目

  1. 创建一个名为 hello-vue 的工程

    vue init webpack hello-vue
    
    
  2. 安装依赖,我们需要安装 vue-routerelement-uisass-loadernode-sass 四个插件

# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev	

  1. Npm 命令解释

    • npm install moduleName:安装模块到项目目录下
    • npm install -g moduleName:-g 的意思是将模块安装到全局,具体安装到磁盘的哪个位置,要看 npm config prefix 的位置
    • npm install moduleName -save:–save 的意思是将模块安装到项目目录下,并在 package 文件的 dependencies 节点写入依赖,-S 为该命令的缩写
    • npm install moduleName -save-dev:–save-dev 的意思是将模块安装到项目目录下,并在 package 文件的 devDependencies 节点写入依赖,-D 为该命令的缩写
  2. 创建成功后用 idea 打开,并删除净东西 创建 views 和 router 文件夹用来存放视图和路由

  3. 在 views 创建 Main.vue

    Main.vue:

    <template>
      <h1>首页</h1>
    </template>
    <script>
        export default {
            name: "Main"
        }
    </script>
    <style scoped>
    </style>
    
    
  4. 在 views 中创建 Login.vue 视图组件

Login.vue:(用的 ElementUI 中的代码)

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: "Login",
    data() {
      return {
        form: {
          username: '',
          password: ''
        },

        // 表单验证,需要在 el-form-item 元素中增加 prop 属性
        rules: {
          username: [
            {required: true, message: '账号不可为空', trigger: 'blur'}
          ],
          password: [
            {required: true, message: '密码不可为空', trigger: 'blur'}
          ]
        },

        // 对话框显示和隐藏
        dialogVisible: false
      }
    },
    methods: {
      onSubmit(formName) {
        // 为表单绑定验证功能
        this.$refs[formName].validate((valid) => {
          if (valid) {
            // 使用 vue-router 路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main");
          } else {
            this.dialogVisible = true;
            return false;
          }
        });
      }
    }
  }
</script>

<style lang="scss" scoped>
  .login-box {
    border: 1px solid #DCDFE6;
    width: 350px;
    margin: 180px auto;
    padding: 35px 35px 15px 35px;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    box-shadow: 0 0 25px #909399;
  }

  .login-title {
    text-align: center;
    margin: 0 auto 40px auto;
    color: #303133;
  }
</style>

  1. 创建路由

    在 router 目录下创建一个名为 index.js 的 vue-router 路由配置文件

    index.js:

    import Vue from "vue";
    import Router from "vue-router";
    import Main from "../views/Main";
    import Login from "../views/Login";
    
    Vue.use(Router);
    
    export default new Router({
      routes: [
        {
          path: '/main',
          component: Main
        },
        {
          path: '/login',
          component: Login
        }
      ]
    });
    
    
  2. 在 main.js 中配置相关

    main.js 是 index.html 调用的 所以前面注册的组件要在这里导入

    一定不要忘记扫描路由配置并将其用到 new Vue 中

    main.js:

    import Vue from 'vue'
    import App from './App'
    //扫描路由配置
    import router from './router'
    //导入elementUI
    import ElementUI from "element-ui"
    //导入element css
    import 'element-ui/lib/theme-chalk/index.css'
    
    Vue.use(router);
    Vue.use(ElementUI)
    
    new Vue({
      el: '#app',
      router,
      render: h => h(App),//ElementUI规定这样使用
    })
    
    
  3. 在 App.vue 中配置显示视图

    App.vue :

    <template>
      <div>
        <router-link to="/login">login</router-link>
        <router-view></router-view>
      </div>
    </template>
    <script>
    export default {
      name: 'App',
    }
    </script>
    
    
  4. 测试运行

```
npm run dev

```

> 测试:在浏览器打开 http://localhost:8080/#/login
> 如果出现错误: 可能是因为sass-loader的版本过高导致的编译错误,当前最高版本是8.0.2,需要退回到7.3.1 ;
> 去package.json文件里面的 "sass-loader"的版本更换成7.3.1,然后重新cnpm install就可以了;

十三、路由嵌套

​ 嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。

Demo

  1. 创建用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件;

    Profile.vue

    <template>
      <h1>个人信息</h1>
    </template>
    <script>
      export default {
        name: "UserProfile"
      }
    </script>
    <style scoped>
    </style>
    
    
  2. 在用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件;

    List.vue

    <template>
      <h1>用户列表</h1>
    </template>
    <script>
      export default {
        name: "UserList"
      }
    </script>
    <style scoped>
    </style>
    
    
  3. 修改首页视图,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件,代码如下:

Main.vue

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <el-menu :default-openeds="['1']">
          <el-submenu index="1">
            <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
            <el-menu-item-group>
              <el-menu-item index="1-1">
                <!--插入的地方-->
                <router-link to="/user/profile">个人信息</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <!--插入的地方-->
                <router-link to="/user/list">用户列表</router-link>
              </el-menu-item>
            </el-menu-item-group>
          </el-submenu>
          <el-submenu index="2">
            <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
            <el-menu-item-group>
              <el-menu-item index="2-1">分类管理</el-menu-item>
              <el-menu-item index="2-2">内容列表</el-menu-item>
            </el-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>

      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right: 15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>个人信息</el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </el-header>
        <el-main>
          <!--在这里展示视图-->
          <router-view />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
  export default {
    name: "Main"
  }
</script>
<style scoped lang="scss">
  .el-header {
    background-color: #B3C0D1;
    color: #333;
    line-height: 60px;
  }
  .el-aside {
    color: #333;
  }
</style>

  1. 配置嵌套路由修改 router 目录下的 index.js 路由配置文件,使用 children 放入 main 中写入子模块,代码如下

    index.js

    import Vue from "vue";
    import Router from "vue-router";
    import Main from "../views/Main";
    import Login from "../views/Login";
    import UserList from "../views/user/List";
    import UserProfile from "../views/user/Profile";
    
    Vue.use(Router);
    
    export default new Router({
      routes: [
        {
          path: '/main',
          component: Main,
          //路由嵌套
          children: [
            {path: '/user/profile',component: UserProfile},
            {path: '/user/list',component: UserList}
          ]
        },
        {
          path: '/login',
          component: Login
        }
      ]
    });
    
    
  2. 路由嵌套效果图

十四、参数传递

1. Demo

  1. 前端传递参数

    ​ 此时我们在 Main.vue 中的 route-link 位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径;

    <!--name:传组件名 params:传递参数,需要绑定对象:v-bind-->
    <router-link v-bind:to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link>
    
    
  2. 修改路由配置,增加 props:true 属性

    ​ 主要是 router 下的 index.js 中的 path 属性中增加了 :id 这样的占位符

    {
      path: '/user/profile/:id',
      name: 'UserProfile',
      component: UserProfile,
      props:true
    }
    
    
  3. 前端显示

    在要展示的组件 Profile.vue 中接收参数

    Profile.vue:

    <template>
      <div>
        个人信息
        {{ id }}
      </div>
    </template>
    <script>
        export default {
          props: ['id'],
          name: "UserProfile"
        }
    </script>
    <style scoped>
    </style>
    
    
  4. 运行

2. 组件重定向

​ 重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:
​ 在 router 下面 index.js 的配置

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  path: '/goHome',
  redirect: '/main'
}

说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;

使用的话,只需要在 Main.vue 设置对应路径即可;

<el-menu-item index="1-3">
    <router-link to="/goHome">回到首页</router-link>
</el-menu-item>

十五、路由钩子与异步请求

1. 路由模式与 404

路由模式有两种

  • hash:路径带 # 符号,如 http://localhost/#/login

  • history:路径不带 # 符号,如 http://localhost/login

    修改路由配置,代码如下:

    export default new Router({
      mode: 'history',
      routes: [
      ]
    });
    
    

    404 界面:

    1. 创建一个 NotFound.vue 视图组件

      <template>
          <div>
            <h1>404,你的页面走丢了</h1>
          </div>
      </template>
      <script>
          export default {
              name: "NotFound"
          }
      </script>
      <style scoped>
      </style>
      
      
    2. 修改路由配置 index.js

      import NotFound from '../views/NotFound'
      {
         path: '*',
         component: NotFound
      }
      
      

2. 路由钩子与异步请求

beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行

在 Profile.vue 中写:

  export default {
    name: "UserProfile",
    beforeRouteEnter: (to, from, next) => {
      console.log("准备进入个人信息页");
      next();
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("准备离开个人信息页");
      next();
    }
  }

参数说明:

  • to:路由将要跳转的路径信息
  • from:路径跳转前的路径信息
  • next:路由的控制参数
  • next() 跳入下一个页面
  • next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
  • next(false) 返回原来的页面
  • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

3. 在钩子函数中使用异步请求

  1. 安装 Axios

    cnpm install --save vue-axios
    
    
  2. main.js 引用 Axios

    import axios from 'axios'
    import VueAxios from 'vue-axios'
    Vue.use(VueAxios, axios)
    
    
  3. 准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
    数据和之前用的 json 数据一样 需要的去上述 axios 例子里

    // 静态数据存放的位置
    static/mock/data.json
    
    
  4. 在 beforeRouteEnter 中进行异步请求

    Profile.vue:

      export default {
        //第二种取值方式
        // props:['id'],
        name: "UserProfile",
        //钩子函数 过滤器
        beforeRouteEnter: (to, from, next) => {
          //加载数据
          console.log("进入路由之前")
          next(vm => {
            //进入路由之前执行getData方法
            vm.getData()
          });
        },
        beforeRouteLeave: (to, from, next) => {
          console.log("离开路由之前")
          next();
        },
        //axios
        methods: {
          getData: function () {
            this.axios({
              method: 'get',
              url: 'http://localhost:8080/static/mock/data.json'
            }).then(function (response) {
              console.log(response)
            })
          }
        }
      }
    
    
  5. 执行

javascript
export default {
name: “UserProfile”,
beforeRouteEnter: (to, from, next) => {
console.log(“准备进入个人信息页”);
next();
},
beforeRouteLeave: (to, from, next) => {
console.log(“准备离开个人信息页”);
next();
}
}

==**参数说明:**==

- to:路由将要跳转的路径信息
- from:路径跳转前的路径信息
- next:路由的控制参数
- next() 跳入下一个页面
- next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
- next(false) 返回原来的页面
- next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例



### 3. 在钩子函数中使用异步请求

1. 安装 Axios


cnpm install --save vue-axios

2. main.js引用 Axios

```javascript
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

  1. 准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
    数据和之前用的 json 数据一样 需要的去上述 axios 例子里

    // 静态数据存放的位置
    static/mock/data.json
    
    
  2. 在 beforeRouteEnter 中进行异步请求

    Profile.vue:

      export default {
        //第二种取值方式
        // props:['id'],
        name: "UserProfile",
        //钩子函数 过滤器
        beforeRouteEnter: (to, from, next) => {
          //加载数据
          console.log("进入路由之前")
          next(vm => {
            //进入路由之前执行getData方法
            vm.getData()
          });
        },
        beforeRouteLeave: (to, from, next) => {
          console.log("离开路由之前")
          next();
        },
        //axios
        methods: {
          getData: function () {
            this.axios({
              method: 'get',
              url: 'http://localhost:8080/static/mock/data.json'
            }).then(function (response) {
              console.log(response)
            })
          }
        }
      }
    
    
  3. 执行

uniapp

这里主要看的是 公众号“字节逆旅”

uniapp是Dcloud公司的产品,是一个跨端开发框架,基于vue.js技术栈。开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。这是它的功能架构图,可以看下,了解下它的架构。

简单总结下,uniapp底层集成了native技术,就是h5+引擎,能调用手机原生api,所以uniapp能开发接近原生性能的app,这是js引擎部分;它是双引擎,渲染又是独立一个独立引擎。这个渲染引擎又分为nvue渲染和webview渲染,nvue其实就是集成的weex,webview这个有了解的应该知道它的内核是webkit,可以看这篇文章了解。

生态环境
uniapp官方的qq群目前已经有35个了,都是2000人的大群。还有各种基于uniapp的开源组件库,比如uViewUI、colorui、ThorUI、uCharts,最完整最出名的目前是uViewUI,官方文档也是比较完备了,uviewui.com/。 他们的官方qq群现在有4个,可以加群找开发者解答疑问。uniapp官方说有600万开发者,整体上看,生态还算不错。

正确姿势
1、阅读官方文档

官方文档从入门介绍到学习方法再到用法说明、注意事项等等,一应俱全。如果文档看不下去,可以看看社区帖子,或者从插件市场找些现成的用起来。

2、活用插件市场
插件上包含了各种组件、SDK、项目模板等各种资源,甚至还有uniCloud、HbuilderX的相关插件。如果官方的基础组件、官方的uni-ui扩展组件库不能满足你的需求,都可以到插件市场找找看。官方是很重视这个插件市场的,比如uni-ui有一篇官方文档介绍说明uniapp.dcloud.io/component/R…

看这个插件市场排名,也能大概了解目前的插件市场现状,整体上还是比较活跃的:

除了上面提到的比较综合的组件库,其实还有很多优秀的插件作者,他们是专注在特定领域,下面推荐几个:

可能是uniapp生态最好的路由插件
应该是最强大的富文本插件(已经被uviewui集成)
个人觉得目前最好的table组件
挺不错的日期时间选择器
3、通过社区、qq群、插件留言向开发者提问
如果你严格按照文档进行开发,仍然遇到了问题,这时可能需要向他人求助了。如果是uniapp官方问题,可以在社区查找相关资料,这里的案例相当多,基本能找到大部分问题;

插件问题最好就是直接在插件市场对应插件下留言,如果你的问题描述清楚明确,都会有人回答,有的时候,在线就能等到回复。也可以加相应的qq群,里面的热心人还是不少的。

实战教程
前面介绍了uniapp官方资源的正确食用方式,下面介绍一下uniapp如何进行开发、调试、发布,这里涉及到app、h5及小程序(微信小程序)。

一、环境搭建
1、安装hbuilderX
hbuilderx也是dcloud公司出品的ide产品。用uniapp开发跨多端产品,实现一次开发,多端发布就必须用hbuilderx这个神器IDE。

2、安装夜神模拟器
既然是开发app,就少不了连机调试,你可以连接手机,也可以安装一个模拟器,这里推荐夜神模拟器,下载地址:www.yeshen.com/

3、配置环境
hbuilderx连接到模拟器,选择工具--设置,打开配置界面,选择运行配置,如图。

adb路径选择模拟器安装包的adb.exe地址,模拟器端口,夜神模拟器默认是62001,填上就可以了。如果你不确定它的端口,可以在adb.exe的同级目录下找到文件,双击运行,可以看到这个结果

这个就是夜神模拟器的监听端口。

5、插件市场插件安装
插件市场的插件安装一般是这种方式:

点击这个按钮就可以安装到本地。这也分几种,我了解的就是组件类、编译类。像组件类,点击安装后会直接安装到当前打开的uniapp项目中,而且是指定的文件夹components中;像编译类,这种其实类似于webpack的loader,这个是放在hbx的安装包里。

二、uniapp手把手实战
1、新建uniapp空模板项目
cli模式
用hbx创建项目在官方教程上讲得比较细致了,我这里只介绍下用vue-cli创建项目过程。创建步骤在官网上也有,相比用hbx的可视化搭建,用cli搭起来慢了不少。

//安装vue/cli全局依赖
npm install -g @vue/cli

//创建项目模板
vue create -p dcloudio/uni-preset-vue my-project
复制代码
如果在执行脚本时有这样的错误提示:vue: 无法加载文件 C:....vue.ps1。说明你的脚本运行被禁止了,解决办法就是打开当前项目地址的资源管理器,点击文件,弹出对话框,如图点击所示位置

会有弹出框,在里面执行这个段代码:

set-ExecutionPolicy RemoteSigned
复制代码
执行之后,按提示输入Y或者A就可以了,再按上面进行项目创建,就正常了:

最后,它会提示你选择项目模板:

一般建议选择hello uni-app的模板。如果一切顺利(理想情况下),创建完成的项目,看起来是这样的,如下图

我们可以观察下它的package.json文件,可以看到有很多的打包、运行命令,uniapp确实帮我们做了很多事!

cd my-project进入到项目中,运行一下npm run dev:h5,试下效果。

可以看到确实成功了,打开启动页,按f12将页面切换到手机模式,就能看到效果了。

这种cli模式下无法连接到模拟器调试,要实时调试app版本,只能用hbx这个ide。cli模式除了能调试h5版本,还可以调试小程序,以微信小程序为例,这需要先准备好开发工具。

hbuilderx模式
考虑到app是我们最主要的产品输出,最好还是切换到hbuilderx编译器上,其实用习惯之后,感觉还是挺好用的。cli模式适合开发h5或者小程序。具体的步骤看官网就可以了,比较简单,可视化操作,一步步走就没问题。其实前面用cli模式创建的项目,也可以用hbx开发,在hbx编译器上打开文件夹,选择cli项目的src文件夹,就是一个标准的hbuilderx创建项目了。

这时选择运行--运行到模拟器就可以了

2、目录结构
我们来观察下这个项目结构,这是官方的一个介绍,我copy过来了

┌─cloudfunctions 云函数目录(阿里云为aliyun,腾讯云为tcb,详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid 存放本地网页的目录,详见
├─platforms 存放各平台专用页面的目录,详见
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见

复制代码
重点是pages、static、main.js、App.vue、manifest.json、pages.json这几个目录或者文件。

3、必学内容
我这里没必要把官方文档从头讲一遍,这里可以告诉你重点内容,你学习时重点关注,重点消化就可以了。

第一个就是框架介绍这里,你要把框架简介的内容通读并熟悉。

第二个就是上手开发了,这时框架这块要知道怎么用了,如何配置pages.json文件非常重要!具体的其实我也记不住,但是通过配置调试你就能知道是怎么回事了,这个熟悉就行了。

4、uniapp路由页面配置(pages.json)
打开pages.json文件,这是一个uniapp项目配置文件,是json格式。如果内容较多,可以右键--显示文档结构图,可以看到这个文件的基本结构是这样:

pages是项目中用到的所有的页面配置,第一项是登录app的启动页,一般放登录页或者首页,其他的可以参考官方文档看看说明并手动设置下参数,看下效果就明白了。subPackages是分包加载配置,这个是为小程序准备的,小程序在发布上传代码时对总包大小(目前是16M)有要求,还要示对总包进行分包,每个小分包不能超过2M,这个就要求在这里进行配置分包加载。globalStyle这个是设置全局样式的,一般都会有一个统一风格的样式,可以在这里设置,包括导航栏、标题、窗口背景色这些。tabBar这个也非常重要,这是app的标配,相当于是一级导航栏,拿我们这个hello uniapp的项目举例来说,框住部分就是tabBar的内容。

tabBar各组内容最多只能有5项,最少要有2项,都在list项进行配置

看下list项具体内容

5、生命周期
这里按照粒度从粗到细分为应用生命周期、页面生命周期及组件生命周期,具体的可以看下文档。其中组件生命周期是跟vue组件的生命周期相同。具体用法要结合业务场景配合来使用用。

6、状态管理
状态管理这块有几种方式,

vuex

vuex用法与vue项目上是一样的。唯一要注意的就是import store from './store/store.js'这句只能写在main.js里,在别处引用都会报错?!

uni.storage

这块看下对应api的具体用法,这个状态数据是持久化的,除非你调用它的清除接口,这个数据会一直缓存在本地。

globalData
这个用的比较少,这是在app.vue页面定义全局变量,具体用法如下:

//在其他页面调用/修改全局变量
getApp().globalData.text = 'test'
复制代码
7、全局事件
uniapp的API文档非常详细,甚至封装了全局事件,我们可以直接用了

8、接口请求封装
这一块内容在API模块的网络栏,一般的接口请求就用uni.request(object)就可以了。普通的接口调用用这个就已经够了,如果需要用到请求拦截,需要到插件市场找合适的插件。这里推荐luch-request,文档很清楚,功能比较全。

9、路由跳转
路由跳转对应的API可能看下官方文档,基本上都是常用的。这里有个前提就是,当前页面必须在pages.json中配置好,才能调用这些跳转的api。还有个要注意的就是tabbar页面只能用uni.switchTab来跳转。我们知道vue有vueRouter来支持路由跳转、路由守卫,但是uniapp不支持这个插件,如果要在uniapp上实现,这里推荐uni-simple-router

10、全局样式
样式这一块要注意的地方比较多,我总结了一下特别要注意是这些地方:

尺寸单位
uniapp目前通用的尺寸单位是px、rpx,px即我们通常理解的像素单位;rpx是一个响应式单位,它会根据屏幕宽度按给定值占比来计算出像素值。

前面提到的pages.json页面的globalStyle配置节点,可以通过配置来控制rpx的计算参数

css变量及固定值

这几个参数主要是在跨端样式控制时要注意,经常会遇到app布局弄得差不多了,然后到h5端,样式就不对了,或者到小程序上也是异常。看上面这个表,主要就是要注意这三个变量在不同环境下,它的值是不同的,要特别注意。下面这个表,是对上面的一个补充,如果在h5端,不存在原生顶部导航栏与tabBar,就是自定义的div,我们在设置样式时就要参照这些变量的固定值。

字体图标
通用的支持格式包括base64格式、网络路径即在线字体(须https开头)
小程序不支持在css中引用本地文件,包括图片或者字体
uniapp会自动把小于40kb的字体文件转换为base64,uniapp不会编译static文件夹下的内容
其他的像样式导入、内联样式等与web端应用开发差不多。还有一个要注意的就是如果要设置全局样式,可以在App.vue中设置或者用@import导入外联样式就可以了。

11、组件及组件库
组件这块是非常重要的,对uniapp来说包括框架设计、底层原理这些都是灵魂是骨架;前面讲到的各种规则及配置都是行为习惯、准则;还有前面提到的状态管理、路由、事件、样式、接口请求等,这些就像是血管、淋巴一样不可缺少;组件就是内脏、肌肉了,具体作用就看它的定位了。

官方文档这块将组件专门列为一个栏目,可以大概看下有哪些组件。平时开发基本功能用官方提供的组件基本上就满足了。开源的组件库也是基于官方组件进行的二次封装,一般原则是优先参考官方组件,如果官方组件不支持的,或者用起来不方便的,再到开源市场寻找开源插件。

12、登录跳转到首页
接下来,我们开发一个登录跳转的功能。前面我们用vuecli创建了一个项目,那个是hellouni的,内容有点多,现在我们重新搭建一个空的项目模板,这样清楚一点。步骤跟前面一样,就是选择模板时选默认模板就行了。

开发登录功能
在空模板项目上尝试开发一个登录功能,一般需要这几步:

新建一个登录页面,配置pages页面路由参数

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path" : "pages/login/login",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}

    },{
		"path": "pages/index/index",
		"style": {
			"navigationBarTitleText": "uni-app"
		}
	}
]

复制代码
准备一个可用的登录接口,进行封装
uni.request({
// #ifdef H5
url: '/data-receive/v1/login',
// #endif
// #ifndef H5
url: 'http://##.##.##.##:##/data-receive/v1/login',
// #endif
method: 'POST',
data: {
username: this.name,
password: this.password
},
dataType: 'json',
success(res) {
if (res.statusCode == 200 && res.data.code == 200) {
//跳转到首页
uni.navigateTo({
url: '../index/index'
})
}
}
})
复制代码
新建登录页面,完成布局、样式,登录逻辑

复制代码
将登录接口请求分两种情况:h5环境、非h5环境
// #ifdef H5
url: '/data-receive/v1/login',
// #endif
// #ifndef H5
url: 'http://##.##.##.##:##/data-receive/v1/login',
// #endif
复制代码
h5环境用代理解决跨域
"h5" : {
"router" : {
"base" : "./"
},
"devServer" : {
"proxy" : {
"/data-receive" : {
"target" : "http://##.##.##.##:##/data-receive",
"pathRewrite" : {
"^/data-receive" : ""
}
}
}
}
}
复制代码
页面跳转
uni.navigateTo({
url: '../index/index'
})
复制代码
更多跳转请参考路由与页面跳转

13、开发调试
app开发调试

h5开发调试
h5其实就是网页,这个调试就比较简单了,跟开发web项目一样的。

在hbx上运行到浏览器(内置或者其他浏览器)
f12并开启手机调试模式
小程序开发调试
首先要明白uniapp小程序版本的开发方式:开发还是在hbx上开发,只不过要运行到小程序开发工具上,然后在hbx上开发会实时更新到小程序上。也就是说小程序开发工具只是个模拟器,看效果的,上面的代码都是从uniapp版本编译过来的,对开发不太友好,不建议在小程序开发工具上修改。以下是微信小程序开发步骤:

到微信公众平台注册一个小程序,并填写相关信息
在开发设置完成小程序开发者绑定,生成小程序之后会有一个小程序appid,这个要保存
下载安装小程序开发工具
如果项目是第一次运行到小程序,需要在小程序开发工具上绑定前面注册保存的appid,小程序代码地址(此例是在newproject\src\unpackage\dist\dev\mp-weixin),绑定好了就能看到小程序的开发状态了,就像这样:

前面讲过小程序的开发还是在hbx上,小程序工具是看效果的,但是调试找bug还是得在小程序开发工具上,调式模块就在右下角,类似于谷歌浏览器的调试窗,如果觉得窗口太小,这击这个浮动窗口按钮就能弹出调试窗口。

已经弹出的调试窗口

14、打包发布
app打包发布
app打包流程比较简单,分为安卓和苹果两大平台。一般app上线都应该走云打包流程,选择发行-->原生App云打包,弹出这个对话框。

这个是安卓包,如果不需要上市场上的应用平台,就可以选择公共测试证书的打包方式。

这是苹果版本的打包,苹果打包后要上线,只有上线appstore一条路,证书相关的三个文件都不能少。

点击打包之后,进入云打包队列排队等待,成功之后会给出下载地址:

安卓版本是可以直接安装使用的,你可以放在生产环境服务器上供用户下载。如果是苹果版本,打包后的ipa文件不能直接使用,还要提交到appstore审核通过,最后才能发布,这个周期大概在一周左右。

app热更新
在app上线之后,后面的版本升级就可以用热更新方式更新了,不用每次都发布一个新的完整包。选择发行-->原生App-制作应用wgt包,弹出更新包对话框:

生成wgt后,将wgt文件放在服务器,用户在app上检测到有更新时就会下载更新包在本地热更新。

发行wgt时,manifest.json配置页面的应用版本名称与应用版本号都必须高于上一次设置的值;

检测版本是否更新,如果有更新就下载更新包、安装并重启应用,这里有个完整教程
h5打包发布
h5版本的打包应该是最简单的,发布也可以按网页部署方式来,如果想用微信打开网页,最好将h5部署在外网域名所在的服务器上。

小程序打包发布
分包
小程序打包对包的大小有限制,之前是16M现在升级到了20M。具体的分包方法参考官方文档说明,我们分包是要在uniapp上进行分包,注意uniapp分包要求。我写了关于uniapp适配微信小程序的文章,对分包上传有说明,可以参考。

上传代码

posted @ 2021-06-02 15:11  tifaIsMyWife  阅读(454)  评论(0编辑  收藏  举报