前端入职学习笔记-第二周第一天(Vue基础、Electron入门)

学习路径

Vue

1、Vue基础

1.1 安装Vue

一般vue的安装以及其开发过程需要用到的一些包的安装使用的都是npm命令,但是 npm 安装速度慢,可以使用淘宝的镜像及其命令 cnpm,安装使用介绍参照:使用淘宝 NPM 镜像

# 查看版本
$ npm -v
2.3.0

#升级 npm
cnpm install npm -g

# 升级或安装 cnpm
npm install cnpm -g
# 最新稳定版
$ cnpm install vue

Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。

# 全局安装 vue-cli
$ cnpm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 这里需要进行一些配置,默认回车即可
This will install Vue 2.x version of the template.

For Vue 1.x use: vue init webpack#1.0 my-project

? Project name my-project
? Project description A Vue.js project
? Author runoob <test@runoob.com>
? Vue build standalone
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? Yes

   vue-cli · Generated "my-project".

   To get started:
   
     cd my-project
     npm install
     npm run dev
   
   Documentation can be found at https://vuejs-templates.github.io/webpack

进入项目,安装并运行:

$ cd my-project
$ cnpm install
$ cnpm run dev
 DONE  Compiled successfully in 4388ms

> Listening at http://localhost:8080

成功执行以上命令后访问 http://localhost:8080/。

 

1.2 插值表达式

格式:{{表达式}}

  对象(不连续3个{{ {name: 'jack'} }})

  字符串 {{'xxx'}}

  判断后的布尔值 {{true}}

  三元表达式 {{true?'是正确': '错误'}}

可以应用于页面中简单粗暴的调试

注意:必须在data这个函数的返回对象中声明

 

1.3 常用基础指令

v-text

  将一个变量的值渲染到指定的元素当中

v-html

  可以给出真正输出html元素

v-bind(或者使用":")

  绑定页面中元素的属性

v-if和v-show

  v-if:

  作用:判断是否加载固定的内容,如果是真就加载,如果是假就不加载

  语法:v-if="判断表达式"

  v-show

  作用:判断是否显示内容

  语法:v-show="判断表达式"

v-on(或者使用"@")

  作用:对页面中事件进行绑定

  语法:v-on:时间类型="监听器"

指令使用示例:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!--  -->
    <div id="app"></div>
    <script src="vue-2.4.0.js"></script>
    <script>
        new Vue({
            el:'#app',
            template:`
            <div>
                <span v-text="myText"></span>
                <hr/>
                <span v-html="myHtml"></span>
                
                <button v-if="num == 1">测试v-if</button>    
                <button v-else-if="num == 2">测试v-else-if</button>    
                <button v-else>测试v-else</button>
                <hr/>
                <button v-show="isShow">测试v-show</button>    
                <hr/>
                <input type="text" v-bind:value="myValue">
                <!-- 常量需要加'' -->                
                <input type="text" v-bind:value="'常量'">
                <hr/>
                <button v-on:click="myValue='abc'">点我改变myValue的值</button>
                <button @click="myValue='bcd'">点我改变myValue的值</button>
            </div>
            `,
            data:function(){
                return {
                    myText:'我是text的值!',
                    myHtml:'<h1>我是html的值!</h1>',
                    isExit:true,
                    num:23,
                    isShow:false,
                    myValue:12345,
                }
            }
        })
    </script>
</body>
</html>
复制代码

 

1.4 双向数据绑定

v-model

 

示例:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!--v-bind可以给任何属性赋值,是从vue到页面的单向数据流 -->
    <!--v-model只能给具备value属性的元素进行双向数据绑定(必须使用的是有value的元素) -->
    <div id="app"></div>
    <!--  -->
    <script src="vue-2.4.0.js"></script>
    <script>
        new Vue({
            el:'#app',
            template:
            `
            <div>
                <!--利用v-model双向流 实现当用户输入xxxx的时候,显示下面的button -->
                <input type="text" v-model="myValue" />
                <button v-show="myValue == 'xxxx'">用户输入的是xxxx</button>    
            </div>
            `,
            data:function(){
                return{
                    myValue:123,
                }
            }
        })
    </script>
</body>
</html>
复制代码

 

1.5 遍历列表的输出

 v-for

  作用:控制html元素中的循环

  语法:v-for="item in 集合"

示例:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .A{
            background-color: red
        }
        .B{
            background-color: green
        }
    </style>
</head>
<body>
    <!-- 补充知识点 -->
    <!-- 1:v-for的使用中,除了item属性,还有一些辅助属性
            stus:数组: (item,index) in stus 奇偶数的不同样式
                :class="index%2==0?'red':'green'"
                
            stus:对象 (value,key,index) in stus
    -->
    <div id="app"></div>
    <script src="vue-2.4.0.js"></script>
    <script>
        new Vue({
            el:'#app',
            template:
            `
            <div>
                <button>{{myValue}}</button>
                <ul>
                    <li v-for="item in stu" :class="item.score">
                        {{item.name}}
                    </li>    
                </ul>
                <hr/>
                <ul>
                    <li v-for="(val,key,index) in stu2">
                        val:{{val}}
                        key:{{key}}
                        index:{{index}}
                    </li>
                </ul>
            </div>
            `,
            data:function(){
                return {
                    myValue:'example',
                    stu:[
                        {name:'张三',score:'A'},
                        {name:'李四',score:'B'},
                        {name:'王五',score:'A'}
                    ],
                    stu2:{
                        'a':'张三',
                        'b':'李四',
                        'c':'王五'
                    }
                }
            }
        })
    </script>
</body>
</html>
复制代码

 

1.6 methods

new Vue({
  el:'#app',
  template:
  `
  <div>
    <h1 v-show="isShow" >1</h1>
    <h1 v-show="isShow" >2</h1>
    <h1 v-show="isShow" >3</h1>
    <h1 v-if="isShow" >4</h1>
    <button @click="changeIsShow">点我</button>
  </div>
  `,
  data:function(){
    return {
      isShow:true
    } 
  },
  //在根属性中声明methods
  methods:{
    //key是函数名,value是函数体
    changeIsShow:function(e){
    //this就是data函数return出去的对象
    //vue帮我们处理的this指向,不是事件对象了
    console.log(e.target)
    console.log(this)

    this.isShow = !this.isShow 
    }
  }
})

 

1.7 filter

将数据进行再次修饰的操作

过滤器分两种:

  1)组件内的过滤器(组件内有效)

  2)全局过滤器(所有组件共享)

先注册后使用

组件内 filters: { 过滤器: 过滤器fn } 最终fn内通过return产出最终的数据

使用方法 {{ 原有数据 | 过滤器名 }}

需求

  页面input框输入字符串,反转字符串输出,按参数显示label(中英文)

过滤器fn:

  声明function (data, argv1, argv2...) {}

       使用{{ 数据 | 过滤器名(参数1,参数2) }}

        //过滤器可以给数据显示进行添油加醋
        //需求:原本显示的数据是abc,反转成cba
        //需求实现:1、为了互动更好,用Input + v-model来获取数据到vue中
        //2、输出 :{{内容 | 使用过滤器输出}}
        
        var App = {
            template:`
                <div>
                    <input type="text" v-model="myText" />
                    {{myText | reverse('英文版','!:')}}
                </div>
            `,
            data:function(){
                return {
                    myText:''
                }
            },
            //组件内的过滤器
            filters:{
                reverse:function(dataStr,lang,arg2){ //参数1就是传递的原数据
                    return lang + arg2 + dataStr.split('').reverse().join('') //显示的内容
                }
            }
        }

        //全局过滤器
        Vue.filter('myreverse',function(data,arg1){
            return data + arg1
        })

 

1.8 变量监视

watch   监视单个

        var App = {
            template:`
                <div>
                    <input type="text" v-model="myText" />
                    {{myText}}
                    <button @click="stus[0].name = 'rose'">改变stus[0].name属性</button>
                </div>
            `,
            data:function(){
                return {
                    myText:'111',
                    stus:[
                        {name:'jack',}
                    ]
                }
            },
            watch:{
                //监视复杂类型,无法监视的原因是因为监视的是对象的地址,地址没改
                //改的是同地址属性的值
                // stus:function(){
                //     console.log('监视成功,不可能!')

                // },
                //深度监视:object || array
                stus:{
                    deep:true, //深度
                    handler:function(newV,oldV){
                         console.log('监视复杂数据类型成功')
                    }

                },

                //key是属于data属性的属性名,value是监视后的行为
                myText:function(newV,oldV){
                    console.log(newV,oldV)
                    if(newV === 'iloveyou'){
                        alert('我不爱你!')
                    }
                }

            }
        }

computed   监视多个

        var App = {
            template:`
                <div>
                    <input type="text" v-model="n1" />    
                    +
                    <input type="text" v-model="n2" />
                    *
                    <input type="text" v-model="rate" />
                    = {{result}}       
                </div>
            `,
            data:function(){
                return {
                   n1:'',
                   n2:'',
                   rate:'', 
                }
            },
            computed:{
                //包含原值不变,缓存不调函数的优化机制
                result:function(){
                    //监视对象,写在了函数内部,
                    //凡是函数内部有this.相关属性,改变都会触发当前函数
                    //this.n1 this.n2 this.rate
                    console.log('监视到了')
                    return (+this.n1 + +this.n2)*this.rate 
                }
            }
            
        }<body> <div id="app"></div> <script src="vue-2.4.0.js"></script> <script> //slot是留坑 var MyLi = { template:`<li> <slot></slot> </li>`  } Vue.component('my-li',MyLi) //slot其实就是父组件传递的DOM结构 //vue提供的内置组件<slot></slot> var App = { template:` <div> <ul> <my-li> <button>111</button> </my-li> <my-li> <h1>222</h1> </my-li> <my-li>3</my-li> <my-li>4</my-li> <my-li>5</my-li> <my-li>6</my-li> <my-li>7</my-li> <my-li> <h1>888</h1> </my-li> <my-li> <button>999</button> </my-li> </ul> </div>  `, }

 

1.9 组件插槽

 slot留坑插槽

        //slot是留坑
        var MyLi = {
            template:`<li>
                <slot></slot>
            </li>`
        }
        Vue.component('my-li',MyLi)

        //slot其实就是父组件传递的DOM结构
        //vue提供的内置组件<slot></slot>
        var App = {
            template:`
                <div>
                    <ul>
                        <my-li>
                            <button>111</button>
                        </my-li>
                        <my-li>
                            <h1>222</h1>
                        </my-li>
                        <my-li>3</my-li>
                        <my-li>4</my-li>
                        <my-li>5</my-li>
                        <my-li>6</my-li>
                        <my-li>7</my-li>
                        <my-li>
                            <h1>888</h1>
                        </my-li>
                        <my-li>
                            <button>999</button>
                        </my-li>
                    </ul>
                </div>
            `,
        }

具名插槽

 //slot是留坑,外部填入html内容
        var MySlot = {
            template:`<li>
                以下预留第一个坑
                <slot name="one"></slot>
                <hr/>
                以下预留第二个坑
                <slot name="two"></slot>
            </li>`
        }
        Vue.component('my-slot',MySlot)

        //slot其实就是父组件传递的DOM结构
        //vue提供的内置组件<slot></slot>
        var App = {
            template:`
                <div>
                    <my-slot>
                        <h1 slot="one">我是1,对应第一个slot</h1>
                        <h1 slot="two">我是2,对应第二个slot</h1>
                    </my-slot>
                </div>
            `,
        }

 

1.10 组件生命周期函数

        var Test = {
            template:`<div>
                我是test组件{{text}}
                <button @click="text=text+1">更改</button>
            </div>`,
            data:function(){
                return {
                    text:'hello world'
                }
            },
            //-----------------------------------------------
            beforeCreate:function(){
                //组件创建之前
                // console.log(this.test)
                console.log('beforeCreate')
            },
            created:function(){
                //组件创建之后
                // console.log(this.test)
                console.log('created')
            },
            //使用该组件,就会触发以上的事件函数(钩子函数)
            //created中可以操作数据。并且可以实现vue到页面的影响,
            //应用:发起ajax请求

            //-----------------------------------------------
            beforeMount:function(){
                //vue起作用,装载数据到DOM之前
                // console.log(document.body.innerHTML)
                console.log('beforeMount')
            },
            mounted:function(){
                //vue起作用,装载数据到DOM之后
                // console.log(document.body.innerHTML)
                console.log('mounted')
            },
            //////////

            //-----------------------------------------------
            //基于数据改变,影响页面
            beforeUpdate:function(){
                // console.log(document.body.innerHTML) 
                console.log('beforeUpdate') 

            },
            updated:function(){
                // console.log(document.body.innerHTML)
                console.log('updated') 
            },
            //以上两个是当有更改数据才会触发
            //应用:beforeUpdate 可以获取原DOM
            //updated 可以获取新DOM
            //----------------------------------
            // beforeMount vue启动前的DOM
            // mounted vue启动后的DOM 只执行一次

            //-----------------------------------------------
            //对应父组件v-if false 就销毁当前组件
            beforeDestroy:function(){ //销毁之前
                // console.log(document.body.innerHTML) 
                console.log('beforeDestroy')
            },
            destroyed:function(){ //销毁之后
                // console.log(document.body.innerHTML) 
                console.log('destroyed')
            },
            //销毁,最终都是做一些其他功能的释放,保存数据到localstrorage

            //-----------------------------------------------
            activated:function(){
                console.log('组件被激活了')
            },
            deactivated:function(){
                console.log('组件被停用了')
            },           
            //created 和 actived 都是v-if="true" 子组件的状态
            //created 没有被keep-alive内置组件包裹,actived被包裹了
            //销毁和停用同上
        }

 

1.11 组件传值父传子

使用v-bind和props

        var Son = {
            template:`<div>
                接受到父组件的数据是:{{title}}

                <h1 v-if="xxx">1</h1>
                <h1 v-show="xxx">2</h1>
                <ul>
                    <li v-for="num in ['张三','李四','王五']">{{num}}</li>
                </ul>
                <button @click="changeXxx">改变显示</button> 
                <hr/>
                    单项数据流(vue->html):
                    <input type="text" :value="text" /><br/>
                    双向数据流(vue->html->vue)
                    <input type="text" v-model="text" /><br/>
                    <h1>主要看这里:</h1>
                    {{text}}
                     
            </div>
            `,
            data:function(){
                return {
                    xxx:true,
                    text:'hello',
                } 
            },
            methods:{
                changeXxx:function(){
                    this.xxx = !this.xxx
                }
            },
            //声明接收参数
            props:['title'],
        }

        //其实 父向子传递,就是v-bind给元素的属性赋值
        var App = {
            components:{
                son:Son
            },
            template:`
                <div>
                    <son :title="xxx"></son>
                </div>
            `,
            data:function(){
                return {
                    xxx:'我是xxx数据'
                }
            }
        }

 

1.12 组件传值子传父

子组件:

复制代码
<template>
    <div class="app">
       <input @click="sendMsg" type="button" value="给父组件传递值">
    </div>
</template>
<script>
export default {
 
    data () {
        return {
            //将msg传递给父组件
            msg: "我是子组件的msg",
        }
    },
     methods:{
         sendMsg(){
             //func: 是父组件指定的传数据绑定的函数,this.msg:子组件给父组件传递的数据
             this.$emit('func',this.msg)
         }
     }
}
</script>
复制代码

子组件通过this.$emit()的方式将值传递给父组件

注意:这里的func是父组件中绑定的函数名

父组件:

复制代码
<template>
    <div class="app">
        <child @func="getMsgFromSon"></child>
    </div>
</template>
<script>
import child from './child.vue'
export default {
    data () {
        return {
            msgFromSon: "this is msg"
        }
    },
    components:{
        child,
    },
    methods:{
            getMsgFromSon(data){
                this.msgFormSon = data
                console.log(this.msgFromSon)
            }
    }
}
</script>
复制代码

 

1.13 DOM获取

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="vue-2.4.0.js"></script>
    <script>
        //1:在组件的DOM部分,任意的标签中  写上ref:"xxx"
        //2:通过组件对象 this.$refs.xxx 获取到元素

        //子组件
        var TemComponent = {
            template:`<div>我是子组件</div>`,
        }
        //声明全局组件
        Vue.component('temp',TemComponent)

        var App = {
            template:`
                <div>
                    <temp ref="tmp" />
                    <button ref="btn">我是按钮</button>
                </div>
            `,
            beforeCreate:function(){
                //这里还不能操作函数,只是初始化了事件等...
                console.log(this.$refs.btn)
            },
            created:function(){
                //可以操作数据了
                console.log(this.$refs.btn) 
            },
            beforeMount:function(){
                // new Vue 发生装载 替换 <div id="app">之前
                console.log(this.$refs.btn)
            },
            mounted:function(){ //此处才能获取this.$refs.btn
                //装载数据之后
                console.log(this.$refs.btn)
                console.log(this.$refs.tmp)
            }
        }

        //$属性:$refs 获取组件内的元素
        //$parent:获取当前组件对象的父组件
        //$children:获取当前组件对象的子组件
        //$root:获取new Vue的实例 vm
        //$el:获取组件对象的DOM元素

        var vm = new Vue({
            el:'#app',
            components:{
                app:App,
            },
            template:`<app/>`,

        })
    </script>
</body>
</html>
复制代码

给DOM元素添加事件的特殊情况

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="vue-2.4.0.js"></script>
    <script>
        var App ={
            template:`
                <div>
                    <input type="text" v-if="isShow" ref="input" />
                    <button ref="btn">我是按钮</button>
                </div>
            `,
            data:function(){
                return {
                    isShow:false,
                }
            },
            mounted:function(){
                //装载数据之后
                //显示元素,并给与获取焦点
                this.isShow = true //会触发input元素的插入
                //给input元素获取焦点
                // this.$refs.input.focus();
                //最终代码执行完以后,vue才会根据实际的值,进行DOM的操作

                //我们希望在vue真正渲染DOM到页面以后,才做的事
                this.$nextTick(function(){
                    this.$refs.input.focus();
                })
            },
        }

        new Vue({
            el:'#app',
            components:{
                app:App,
            },
            template:`<app/>`,
        })
    </script>
</body>
</html>
复制代码

 

1.14 路由

路由原理

传统开发方式url改变后立刻发起请求,响应整个页面,渲染整个页面

SPA锚点值改变后 不会发起请求,当发起ajax请求时,只会改变局部页面数据

  故页面不跳转,用户体验更好

SPA

single page application(单页面应用程序)

前端路由

  锚点值监视

  ajax获取动态数据

  核心点时锚点值

SPA原理

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <a href="#/login">点我登录</a>
    <a href="#/register">点我注册</a>
    <div id="content"></div>
    <script type="text/javascript">
        //hashchange 事件
        //url上的部分锚点数据(#xxx)改变,可以获取到这个事件
        var div = document.getElementById('content')
        window.addEventListener('hashchange',function(){
            //根据不同的锚点值做出不同的显示
            switch(location.hash) {
                case '#/login': 
                    div.innerHTML = '<h1>登录界面<h1>';
                    break;
                case '#/register': 
                    div.innerHTML = '<h1>注册界面<h1>';
                    break;
            } 
        })
    </script>
</body>
</html> 
复制代码

使用vue.router.js

    <script src="vue.router.js"></script>
    <script>
        var Rigister = {
            template:`<div>
                我是注册页面    
            </div>`,
        }

        var Login = {
            template:`<div>
                我是登录页面    
            </div>`,
        }

        //2:安装插件 => ?
        Vue.use(VueRouter)
        //3:创建一个路由对象
        var router = new VueRouter({
            //4:配置路由对象
            routes:[{path:'/login',component:Login},{path:'/rigister',component:Rigister}]
        })
        
        //6:指定路由改变局部的位置
        var App =({
            template:`
                <div>
                    <router-view></router-view>
                </div>
            `,
        })

        //5:将配置好的路由对象关联到vue实例中
        new Vue({
            el:'#app',
            router:router, //不加这一步会导致运行的时候说undefined对象中取不到match 
            components:{
                app:App, 
            }, 
            template:`<app/>`,
        })
         

    </script>

 

1.15 meta和路由钩子函数

路由meta元数据 --> meta是对于路由规则是否需要验证权限的配置

  路由对象中和name属性同级{ meta: { isChecked: true } }

路由钩子 --> 权限控制的函数执行时期

  每次路由匹配后,渲染组件到router-view之前

  router.beforeEach(function (to, from, mext) {     })

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="vue-2.4.0.js"></script>
    <script src="vue.router.js"></script>
    <script>
        var isLogin = false;
        var Login = {
            template:`
            <div>
                我是登录界面
                <button ref="login" @click="login_now"></button>
            </div>`,
            methods:{
                login_now:function(){
                    isLogin = true
                    this.$refs.login.innerText = '已登录'
                }
            },
            mounted:function(){
                if(isLogin == true){
                    this.$refs.login.innerText = '已登录'
                }else{
                    this.$refs.login.innerText = '未登录'
                }
            }
        }
        var Music = {
            template:`<div>我的音乐界面</div>`,
        }

        var router = new VueRouter()
        //可以多次的追加路由规则,适合动态的获取路由规则
        router.addRoutes([
            //默认首页路由,如果访问的path是'/',则去到{name:'login'}
            {path:'/',redirect:{name:'login'}},

            {
                name:'login',path:'/login',component:Login,
            },
            //meta:{isChecked:true} 给未来路由的权限控制..
            //全局路由守卫 来做硬件参照条件
            {
                name:'music',path:'/music',component:Music,
                meta:{
                    isChecked:true,
                }
            }
        ])  //更为灵活,可以方便调用后追加路由规则

        router.beforeEach(function(to,from,next){
            //Login等..放行
            // if(to.name === 'login' || to.path === '/'){
            if(!to.meta.isChecked){
                next() // 不调用next就会卡住
            }else{
                //音乐访问需要判断是否登录
                if(isLogin == true){
                    next() //放行
                    //next(false)    //取消用户导航行为
                }else{
                    alert('请登录!')
                    //重定向 /login
                    next({name:'login'})
                }
            }
        })

        var App = {
            template:`
            <div>
                <router-link :to="{name:'login'}">登录</router-link>    
                <router-link :to="{name:'music'}">去听歌</router-link>    
                <router-view></router-view>
            </div>`,
        }

        new Vue({
            el:'#app',
            router:router,
            components:{
                app:App,
            },
            template:`<app/>`
        })
    </script>
</body>
</html>
复制代码

 

2、Electron入门

2.1 开发环境与Electron安装

Electron的使用需要npm与node.js的安装

# 下面这行的命令会打印出Node.js的版本信息
node -v

# 下面这行的命令会打印出npm的版本信息
npm -v

如果上述命令均打印出一个版本号,就说明Node.js已经安装好了! 然后,你只需要安装一个适合JavaScript开发的代码编辑器就可以开始开发工作了。

Electron 可以让你使用纯 JavaScript 调用丰富的原生(操作系统) APIs 来创造桌面应用。 你可以把它看作一个 Node. js 的变体,它专注于桌面应用而不是 Web 服务器端。

安装Electron

现在,您需要安装electron。 我们推荐的安装方法是把它作为您 app 中的开发依赖项,这使您可以在不同的 app 中使用不同的 Electron 版本。 在您的app所在文件夹中运行下面的命令:

npm install --save-dev electron

i、-g、-S、-D的区别

说明: i 是 install 的简写
    -g 是全局安装,不带 -g 会安装在个人文件夹
    -S 与 --save 的简写,安装包信息会写入 dependencies 中
    -D 与 --save-dev 的简写,安装包写入 devDependencies 中

dependencies 与 devDependencies

    dependencies 生产阶段的依赖,也就是项目运行时的依赖
    devDependencies 开发阶段的依赖,就是我们在开发过程中需要的依赖,只在开发阶段起作用

2.2 开发一个简易的Electron

为你的新Electron应用创建一个新的空文件夹。 打开你的命令行工具,然后从该文件夹运行npm init

npm init

npm 会帮助你创建一个基本的 package.json 文件。 其中的 main 字段所表示的脚本为应用的启动脚本,它将会在主进程中执行。 如下片段是一个 package.json 的示例:

{
  "name": "your-app",
  "version": "0.1.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  }
}

您应当在 main.js 中创建窗口,并处理程序中可能遇到的所有系统事件。添加以下功能:打开开发者工具、处理窗口关闭事件、在macOS用户点击dock上图标时重建窗口,添加后,main. js 就像下面这样:

const { app, BrowserWindow } = require('electron')

function createWindow () {   
  // 创建浏览器窗口
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  // 并且为你的应用加载index.html
  win.loadFile('index.html')

  // 打开开发者工具
  win.webContents.openDevTools()
}

// Electron会在初始化完成并且准备好创建浏览器窗口时调用这个方法
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(createWindow)

//当所有窗口都被关闭后退出
app.on('window-all-closed', () => {
  // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
  // 否则绝大部分应用及其菜单栏会保持激活。
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // 在macOS上,当单击dock图标并且没有其他窗口打开时,
  // 通常在应用程序中重新创建一个窗口。
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

// 您可以把应用程序其他的流程写在在此文件中
// 代码 也可以拆分成几个文件,然后用 require 导入。

最后,创建你想展示的 index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <!-- https://electronjs.org/docs/tutorial/security#csp-meta-tag -->
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using node <script>document.write(process.versions.node)</script>,
    Chrome <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>
</html>
在创建并初始化完成 main.jsindex.htmlpackage.json之后,您就可以在当前工程的根目录执行 npm start 命令来启动刚刚编写好的Electron程序了。
 
 
posted @ 2020-07-20 10:52  kyrie1  阅读(346)  评论(0编辑  收藏  举报