精华内容
参与话题
问答
  • Vue2.x从入门到实战

    万人学习 2018-01-01 08:26:42
    课程从Vue2.x版本的入门,一直到实战课程共58集。包括内部指令、全局API、选项、实例和内置组件、Vue-cli、Vue-router、vuex。后有一门Vue实战,带你作一个快餐店的收银系统。
  • vue2.x轻松入门

    千人学习 2018-06-22 14:55:43
    基于新的vue2.5,我们将通过简单的例子给大家讲解Vue的基础语法及编程思路,带大家的上手Vue的基础开发,这门课也包含了关于组件化和vue-cli等内容的基础讲解。
  • Vue2.x经典后台管理系统案例讲解

    千人学习 2019-09-29 10:21:31
    包括如何搭建环境,vuejs常用指令,使用ElementUI快速搭建页面,各类表单的创建和验证,vue组件使用,数据传递的各种方式,前端如何模拟数据,以及如何与后端接口联调等等。 为了让大家能构造出一个规范...
  • Vue数据双向绑定原理(vue2向vue3的过渡)

    万次阅读 多人点赞 2019-11-13 15:13:40
    vue2中的双向绑定是基于defineProperty的get操作与set操作,那么我们简单认识下defineProperty, 作用: 就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。 那么我们先来看下Object.getOwnPrope...

    众所周知,Vue的两大重要概念:

    1. 数据驱动
    2. 组件系统

    接下来我们浅析数据双向绑定的原理

    一、vue2

    1、认识defineProperty

    vue2中的双向绑定是基于definePropertyget操作set操作,那么我们简单认识下defineProperty
    作用: 就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。
    那么我们先来看下Object.getOwnPropertyDescriptor(),有定义方法就会有获取方法,对这就是与defineProperty相对的方法,它可以获取属性值。

    var a ={
        b:1,
        c:2
    }
    console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性
    

    在这里插入图片描述
    这就是打印出来的结果,configurable的意思是可便利,enumerable的意思是可枚举,writable的意思是可写。

    2、使用defineProperty实现简单的私有变量

    知道了属性内部的属性值,我们可以使用defineProperty来实现一个私有变量。

    var a ={
        b:1,
        c:2
    }
    Object.defineProperty(a,'b',{
        writable:false  //不可写
    })
    console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性
    

    在这里插入图片描述
    发现,改变不了a.b的值。


    另外,还可以使用一个很快捷的方法实现私有变量

    var a ={
        b:1,
        c:2
    }
    Object.freeze(a,'b'); //冻结,可理解为变为私有属性
    // Object.seal(a,'b'); //configurable置为false 
    console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性
    

    在这里插入图片描述
    同样,writable为false。如果使用seal()只能使configurable为false。

    3、简单认识defineProperty的get、set的方法

    我们先不要创建全局变量,跟get方法return值,你会发现值为undefined
    在这里插入图片描述
    于是我们改了改

    var a ={
        b:1,
        c:2
    }
     var _value=a.b; //b值赋值需要先赋给全局变量,不然使用不了
     Object.defineProperty(a,'b',{
        get:function(){
            console.log('get');
            return _value; // get方法必须ruturn值,值为全局变量。
        },
        set:function(newValue){
            console.log(newValue)
            _value=newValue; // 赋值
        }
     })
    

    在这里插入图片描述
    取到了。

    4、使用defineProperty简单实现Vue双向绑定

    test.js

    // 使用defineProperty
    function vue () {
        this.$data={
            a:1 // 数组的话不会更新
        };
        this.el=document.getElementById('app');
        this._html="";
        this.observe(this.$data);
        this.render();
    };
    vue.prototype.observe=function(obj){
        var value;
        var self=this;
        for(var key in obj){
            value =obj[key];
            if(typeof value === 'object'){
                this.observe(value)
            }else{
                Object.defineProperty(this.$data,key,{
                    get:function(){
                        return value;
                    },
                    set:function(newvalue){
                        value=newvalue;
                        self.render();
                    }
                })
            }
        }
    }
    vue.prototype.render=function(){
        this._html='I am '+ this.$data.a;
        this.el.innerHTML=this._html;
    }
    
    
    // ***************************************
    //数组改变更新,装饰者模式
    // var arraypro=Array.prototype;
    // var arrayob=Object.create(arraypro);
    // var arr = ["push","pop","shift"];
    // // arr里的方法,既能保持原有的方法,又能触发更新。
    // arr.forEach(function(method,index){
    //     arrayob[method]=function(){
    //         var ret=arraypro[method].apply(this,arguments);
    //         console.log('更新');
    //         return ret;
    //     }
    // })
    // var arr=[];
    // arr.__proto__=arrayob;
    // arr.push(1);
    

    test.html

    <!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>vue双向绑定原理</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script src="test.js"></script>
    <script>
        var vm = new vue();
        setTimeout(function(){
            console.log('changes');
            console.log(vm.$data);
            vm.$data.a=222;
        },2000)
    </script>
    </html>
    

    这样我们就简单实现了数据双向绑定。

    二、vue3

    1、简单认识Proxy

    就是一种机制,用来拦截外界对目标对象的访问,可以对这些访问进行过滤或者改写,所以Proxy更像是目标对象的代理器。

    var ob= {
        a:1,
        b:2
    }
    // 新创建一个Proxy对象直接替换ob对象
    ob=new Proxy(ob,{
        get:function(target,key,receive){   // target指的是原始对象,key指的是属性值,receive指的是这个Proxy对象
            console.log(target,key,receive) 
            return target[key]; //get方法 依然需要return
        },
        set:function(target,key,newvalue,receive){
            console.log(target,key,newvalue,receive) // newvalue指新创建的值
            target[key]=newvalue;
        }
    });
    

    这里需要注意的是:第一次使用proxy时,在new的时候把原对象替换掉。就会触发get方法

    看到上方的代码,我们可以总结Proxy的几个优点:

    1. defineProperty只能监听某个属性,不能对全对象监听;
    2. 所以可以省去for in 提升效率;
    3. 可以监听数组,不用再去单独的对数组做异性操作。

    2、使用Proxy简单实现数据双向绑定

    test1.js

    // 使用Proxy
    function vue () {
        this.$data={
            a:1 
        };
        this.el=document.getElementById('app');
        this._html="";
        this.observe(this.$data);
        this.render();
    };
    vue.prototype.observe=function(obj){
        var self=this;
        this.$data=new Proxy(this.$data,{
            get:function(target,key){
                return target[key];
            },
            set:function(target,key,newvalue){
                target[key]=newvalue;
                self.render();
            }
        })
    }
    vue.prototype.render=function(){
        this._html='I am '+ this.$data.a;
        this.el.innerHTML=this._html;
    }
    
    

    test.html

    <!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>vue双向绑定原理</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script src="test1.js"></script>
    <script>
        var vm = new vue();
        setTimeout(function(){
            console.log('changes');
            console.log(vm.$data);
            vm.$data.a=222;
        },2000)
    </script>
    </html>
    

    3、Proxy还可以做什么呢?

    (1)、校验类型

    function createValidator(target,validator){
        return new Proxy(target,{
            _validator:validator,
            set:function(target,key,value,proxy){
                if (target.hasOwnProperty(key)) {
                    var validator1=this._validator[key];
                    if(validator1(value)){
                        return Reflect.set(target,key,value,proxy)
                    }
                    else{
                        throw Error('type error')
                    }
                }
            }
        })
    }
    var personvalidator={
        name(val){
            return typeof val==='string'
        },
        age(val){
            return typeof val==='number'&&val>18
        }
    }
    
    class Person {
        constructor(name,age) {
            this.name=name;
            this.age=age;
            return createValidator(this,personvalidator);
        }
    }
    var tss=new Person('maomin',22);
    

    (2)、真正私有变量

    var api = {
        _secret: 'xxxx',
        _otherSec: 'bbb',
        ver: 'v0.0.1'
    };
    
    api = new Proxy(api, {
        get: function (target, key) {
            // 以 _ 下划线开头的都认为是 私有的
            if (key.startsWith('_')) {
                console.log('私有变量不能被访问');
                return false;
            }
            return target[key];
        },
        set: function (target, key, value) {
            if (key.startsWith('_')) {
                console.log('私有变量不能被修改');
                return false;
            }
            target[key] = value;
        },
        has: function (target, key) {
            return key.startsWith('_') ? false : (key in target);
        }
    });
    
    api._secret; // 私有变量不能被访问
    console.log(api.ver); // v0.0.1
    api._otherSec = 3; // 私有变量不能被修改
    console.log('_secret' in api); //false
    console.log('ver' in api); //true
    
    展开全文
  • Vue2+VueRouter2+webpack 构建项目实战(一)准备工作

    万次阅读 多人点赞 2016-11-15 14:43:06
    Vue2+VueRouter2+webpack 构建项目实战(一)准备工作之前写的博客没有采用打包工具,而是直接引用js的方式来做的。这种方式很扯淡,也因此,我写了三篇博客之后就没有再写了。通过几个月的学习和实战,基本厘清了...

    Vue2+VueRouter2+webpack 构建项目实战(一)准备工作

    2017年8月补充

    2016年,我写了一系列的 VUE 入门教程,当时写这一系列博文的时候,我也只是一个菜鸟,甚至在写的过程中关闭了代码审查,否则通不过校验。

    本来写这一系列的博文只是为了给自己看的,但没想到的是,这系列博文的点击量超过了2万以上,搜索引擎的排名也是非常理想,这让我诚惶诚恐,生怕我写的博文有所纰漏,误人子弟。

    再者,这一年的发展,VUE 项目快速迭代,看着我一年前写的博文,很可能各种提示已经发生改变,对照着过时的资料,非常可能导致新手在学习的过程中产生不必要的困扰。

    因此,本人决定,重写这个系列的博文,力求以简明、清晰、准确的图文以及代码描述,配合 github 的项目开源代码,给各位 VUE 新手提供一个高质量的入门文案。

    以下为我写的博文:

    1. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述
    2. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(二)安装 nodejs 环境以及 vue-cli 构建初始项目
    3. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(三)认识项目所有文件
    4. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由
    5. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(五)配置 Axios api 接口调用文件
    6. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(六)将接口用 webpack 代理到本地
    7. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(七)初识 *.vue 文件
    8. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(八)渲染一个列表出来先
    9. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(九)再把内容页面渲染出来
    10. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十)打包项目并发布到子目录
    11. Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十一)阶段性小结

    以下为原文

    目录索引

    《Vue2+VueRouter2+webpack 构建项目实战(一)准备工作》

    《Vue2+VueRouter2+webpack 构建项目实战(二)目录以及文件结构》

    《Vue2+VueRouter2+webpack 构建项目实战(三)配置路由,整俩页面先》

    《Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表》

    《Vue2+VueRouter2+webpack 构建项目实战(五)配置子路由》

    《Vue2+VueRouter2+webpack 构建项目实战(六)修复代码并通过验证,另发布代码》

    之前写的博客没有采用打包工具,而是直接引用js的方式来做的。这种方式很扯淡,也因此,我写了三篇博客之后就没有再写了。通过几个月的学习和实战,基本厘清了Vue1 + VueRouter1 + browserify的一些技术点。并且通过几个实际项目的工作,已经验证了自己利用该技术完成项目是没有问题的了。

    但是,现在主流的打包方式已经变成了webpack了,而在guthub上面找的很多插件在browserify上打包可能会出现错误,以至于需要自己造轮子。因此,我用了几天时间来捣鼓webpack

    更重要的是,vue和VueRouter都已经升级到2.x的版本了。我之前基于1.x版本做的那些方法都发生了改变。

    因此,我这次从头来写一个系列的博客,把自己遇到的问题和解决方法都记录下来。以便于自己的温习,也方便新手可以快速的上手。

    环境准备

    首先,要开始工作之前,还是需要把环境搭建好。我这里的环境是mac,如果你是windows,请自己确保环境没有问题。

    mac+nodejs+npm环境是必备的。另外需要文本编辑器,我使用的是atom,当然,你可以使用sublime或者其他的,都没有关系。只是,nodejs是必须要安装的。

    各个系统安装不一样,详情参考:nodejs 官方网站

    安装好nodejs 之后,在终端下面输入命令node -v会有版本号出来。就说明安装成功了。输入npm -v也会有版本号出来,就说明,npm也已经安装好了。

    有了Nodejs环境,则我们可以开始了。

    为了在学习过程中便于查找资料,一定要准备好翻墙工具。至于怎么翻墙我就不说了,因为免费的都不太好用。收费的vpn之类的一般都可以。不过我建议有条件的自己购买一个国外的vps之类的自己搭一个翻墙环境,然后自己用,无论是稳定性还是各个方面都相当不错。

    最后,不要相信百度,坑死你。

    vue-cil构建项目

    vue-cil是vue的脚手架工具。其模板可以通过 vuejs-templates 来查看。

    我们首先,需要安装vue-cil。命令如下:

    $ npm install -g vue-cli

    上面代码中的 $ 为终端前缀,不是让你输入的。下面涉及到终端的部分均是如此,不再累述。

    这个命令只需要运行一次就可以了。安装上之后,以后就不用安装了。

    下面,我们来用vue-cil构建一个项目。

    首先,我们在终端中把当前目录定位到你准备存放项目的地方。如我是准备放在~/Sites/MyWork/这个目录下面,那么我的命令如下:

    $ cd ~/Sites/MyWork

    进入到目录之后,我们按照下面的代码逐条输入,新建一个自己的vue项目

    $ vue init webpack vuedemo

    输入这个命令之后,会出现一些提示,是什么不用管,一直按回车即可。

    如上图所示,就说明我们的项目构建成功了。并且,给出了下面要执行的命令,我们来逐条执行:

    $ cd vuedemo
    $ npm install

    执行npm install需要一点时间,因为会从服务器上下载代码啦之类的。并且在执行过程中会有一些警告信息。不用管,等着就是了。如果长时间没有响应,就ctrl+c停止掉,然后再执行一次即可。如果还是照样,建议检查是不是因为没有翻墙的原因,或者,把npm源换成国内的,这里我就不说这么弄了,具体去问google

    安装完成后,终端如图:

    最后,执行下面一句,把项目跑起来

    $ npm run dev

    执行后,终端如图:

    如上:四行命令,就可以把一个名为vuedemo的项目跑起来。当然,这个名字你是可以随便起的,根据你的实际项目来定。

    好,通过上面的这些命令,我们就实现了新建一个vue+webpack的项目。在运行了npm run dev之后,会自动打开一个浏览器窗口,就可以看到实际的效果了。

    好,我们的第一步,已经顺利完成了。

    小结

    通过上面的几个命令,我们就可以把项目跑起来了。问题是,我们需要掌握一些知识点,我提出来,看官自己找资料学习:

    1. 什么是nodejs? nodejs有哪些用处?
    2. 什么是npm? npm如何安装软件?
    3. 什么是webpack? 它有什么优缺点?
    4. 终端的基本使用。

    我是强烈建议学习前端的同学整mac学习,但是如果你实在没有mac也没有关系,可以使用linux系统来学习。如果你又不用linux,那么没办法了,可以使用windows。但是windows下面的cmd工具实在是太操蛋了。我相信大家在windows上一定安装了一款软件叫git。OK,只要有这个也行,在任意文件夹右击菜单,在菜单中点击git bash here 菜单,然后可以打开一个类似于终端的面板,这里支持一些linux的常用的命令,包括vim工具都有。虽然界面是丑了点,但是比cmd要好用。

    本篇博文只是简单的说了一下如何用vue-cil来构建一个项目,但是这只是一个基础款而已,我们还是要用在我们的项目中,我们下一篇进行学习。

    本文由FungLeo原创,允许转载,但转载必须附带首发链接。如果你不带链接,我将采取包括但不限于深深的鄙视你等手段!

    首发地址:http://blog.csdn.net/fungleo/article/details/53171052

    展开全文
  • Vue 3教程(适用于Vue 2用户)

    万次阅读 2020-06-01 14:44:40
    Vue 3尚未正式发布,但是维护者已经发布了Beta版本,供我们的参与者尝试并提供反馈。 如果你想知道Vue 3的主要功能和主要变化是什么,那么我将在这篇文章中重点介绍一下,告诉你使用Vue 3 beta 9创建一个简单的应用...

    微信搜索【前端全栈开发者】关注这个脱发、摆摊、卖货、持续学习的程序员的公众号,第一时间阅读最新文章,会优先两天发表新文章。关注即可大礼包,送某网精品视频课程网盘资料,准能为你节省不少钱!

    Vue 3尚未正式发布,但是维护者已经发布了Beta版本,供我们的参与者尝试并提供反馈。

    如果你想知道Vue 3的主要功能和主要变化是什么,那么我将在这篇文章中重点介绍一下,告诉你使用Vue 3 beta 9创建一个简单的应用程序。

    我将介绍尽可能多的新内容,包括fragments,teleport,Composition API以及其他一些晦涩的更改。我将尽力解释该功能或更改的原理。

    目录


    我们将建立什么

    我们将构建一个带有模式窗口功能的简单应用。我之所以选择它,是因为它可以方便地展示Vue 3的许多变化。

    这是该应用在打开和关闭状态下的外观,因此你可以在脑海中描绘出我们正在做什么:

    Vue 3安装和setup

    与其直接安装Vue 3,不如克隆一个项目 vue-next-webpack-preview,这将为我们提供一个包括Vue 3在内的最小的Webpack设置。

    $ git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-experiment
    $ cd vue3-experiment
    $ npm i
    

    一旦克隆好了,安装好了NPM模块,我们需要做的就是删除样板文件,然后创建一个新的 main.js 文件,这样我们就可以从头开始创建我们的Vue 3 app了。

    $ rm -rf src/*
    $ touch src/main.js
    

    现在,我们将运行开发服务器:

    $ npm run dev
    

    创建一个新的Vue 3 app

    我们启动一个新的Vue应用程序的方式改变了,我们现在需要导入新的 createApp 方法,而不是使用新的 Vue()

    我们调用这个方法,传递我们的Vue实例定义对象,并将返回对象分配给一个变量 app

    接下来,我们将在 app 上调用 mount 方法,并传递一个CSS选择器来指示我们的mount元素,就像在Vue 2中使用 $mount 实例方法一样。

    // src/main.js
    
    import { createApp } from "vue";
    
    const app = createApp({
      // 根实例定义
    });
    
    app.mount("#app");
    

    变化的原因

    与旧的API一样,我们添加的任何全局配置(plugins,mixins,原型属性等)都将永久更改全局状态。例如:

    // src/main.js
    
    // 影响两个实例
    Vue.mixin({ ... })
    
    const app1 = new Vue({ el: '#app-1' })
    const app2 = new Vue({ el: '#app-2' })
    

    在单元测试中,这确实是一个问题,因为要确保将每个测试都与上一个测试隔离是很棘手的。

    在新的API下,调用 createApp 将返回一个新的app实例,该实例不会被应用于其他实例的任何全局配置污染。

    了解更多:Global API change RFC

    添加state属性

    我们的模态窗口可以处于两种状态之一——打开或关闭。让我们用一个布尔状态属性 modalOpen 来管理它,我们将给它一个初始值 false

    在Vue 2下,我们可以通过在我们的应用实例上创建一个 data 属性并将一个对象分配给该对象来声明 modalOpen 属性,例如:

    // src/main.js
    
    const app = createApp({
      data: {
        modalOpen: false
      }
    });
    

    不再允许这样做。相反,必须为数据分配一个返回状态对象的工厂函数。

    // src/main.js
    
    const app = createApp({
      data: () => ({
        modalOpen: false
      })
    });
    

    变化的原因

    使用对象而不是工厂函数来存储数据的优点是,首先,它在语法上更简单;其次,你可以在多个根实例之间共享顶级状态,例如:

    // src/main.js
    
    const state = {
      sharedVal: 0
    };
    
    const app1 = new Vue({ state });
    const app2 = new Vue({ state });
    
    // 影响两个实例
    app1._data.sharedVal = 1;
    

    这种用例很少,可以使用。因为有两种类型的声明是不适合初学者的,所以决定删除这个特性。

    了解更多:Data object declaration removed RFC

    在继续之前,我们还添加一个方法来切换 modalOpen 值。这与Vue 2没什么不同。

    // src/main.js
    
    const app = createApp({
      data: () => ({
        modalOpen: true  
      }),
      methods: {
        toggleModalState() {
          this.modalOpen = !this.modalOpen;
        }
      }
    });
    

    使用一个根组件

    如果你现在进入浏览器并检查控制台,则会看到警告“Component is missing render function”,因为我们尚未为根实例定义模板。

    Vue 2的最佳实践是为根实例创建一个最小的模板,并创建一个app组件,其中将声明主app标记。

    让我们在这里也这样做。

    $ touch src/App.vue
    

    现在我们可以获取根实例来渲染该组件。区别在于,对于Vue 2,我们通常会使用render函数来执行此操作:

    // src/main.js
    
    import App from "./App.vue";
    
    const app = createApp({
      ...
      render: h => h(App)
    });
    
    app.mount("#app");
    

    我们仍然可以做到这一点,但是Vue 3有一个更简单的方法——使 App 成为根组件。为此,我们可以删除根实例定义,而是传递 App 组件。

    // src/main.js
    
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.mount("#app");
    

    这意味着 App 组件不仅由根实例渲染,而且是根实例。

    在此过程中,我们通过删除 app 变量来简化语法:

    // src/main.js
    
    createApp(App).mount("#app");
    

    现在移至根组件,让我们向该组件重新添加状态和方法:

    // src/App.vue
    
    <script>
    export default {
      data: () => ({
        modalOpen: true  
      }),
      methods: {
        toggleModalState() {
          this.modalOpen = !this.modalOpen;
        }
      }
    };
    </script>
    

    我们还为模态功能创建一个新组件:

    $ touch src/Modal.vue
    

    现在,我们将提供一个最小的模板,其中包括内容插槽。这确保了我们的模态是可重用的。稍后我们将向此组件添加更多内容。

    // src/Modal.vue
    
    <template>
      <div class="modal">
        <slot></slot>
      </div>
    </template>
    

    多根模板

    现在让我们为我们的根组件创建模板。我们将创建一个按钮来打开模态,它将触发 toggleModalState 方法。

    我们还将使用我们刚刚创建的modal组件,它将根据 modalState 的值来渲染。让我们也在槽中插入一段文字作为内容。

    // src/App.vue
    
    <template>
      <button @click="toggleModalState">Open modal</button>
      <modal v-if="modalOpen">
        <p>Hello, I'm a modal window.</p>
      </modal>
    </template>
    <script>
    import Modal from "./Modal.vue";
    export default {
      components: {
        Modal
      },
      ...
    }
    </script>
    

    注意这个模板有什么奇怪的地方吗?再看一遍。

    没错——有两个根元素。在Vue 3中,由于有了一个叫做片段(fragments)的功能,它不再强制要求有一个单一的根元素!

    使用Composition API进行重构

    Vue 3的旗舰功能是Composition API。这个新的API允许你使用 setup 功能而不是使用添加到组件定义对象的属性来定义组件功能。

    现在,让我们重构App组件以使用Composition API。

    在解释代码之前,请清楚我们所做的只是重构——组件的功能将相同。还要注意,模板没有更改,因为Composition API仅影响我们定义组件功能的方式,而不影响我们渲染它的方式。

    src/App.vue

    <template>
      <button @click="toggleModalState">Open modal</button>
      <modal v-if="modalOpen">
        <p>Hello, I'm a modal window.</p>
      </modal>
    </template>
    <script>
    import Modal from "./Modal.vue";
    import { ref } from "vue";
    export default {
      setup () {
        const modalState = ref(false);
        const toggleModalState = () => {
          modalState.value = !modalState.value;
        };
        return {
          modalState,
          toggleModalState
        }
      }
    };
    </script>
    

    setup 方法

    首先,请注意,我们导入了 ref 函数,该函数允许我们定义响应式变量 modalState。此变量等效于this.modalState

    toggleModalState 方法只是一个普通的JavaScript函数。但是,请注意,要更改方法主体中的 modalState 值,我们需要更改其子属性 value。 这是因为使用 ref 创建的响应式变量被封装在一个对象中。这对于保留它们的响应式是非常必要的,因为它们在被传递的过程中会被保留下来。

    最后,我们从 setup 方法返回 modalStatetoggleModalState ,因为这些是在呈现模板时传递给模板的值。

    变化的原因

    请记住,Composition API并不是更改,因为它纯粹是可选的。主要动机是允许更好的代码组织和组件之间的代码重用(因为mixin本质上是一种反模式)。

    如果你认为在这个例子中重构App组件以使用Composition API是没有必要的,那你的想法是正确的。但是,如果这是一个更大的组件,或者我们需要与其他组件共享其功能,那么你就会发现它的用处。

    Teleporting content

    如果你曾经创建过模态功能,你会知道它通常被放置在关闭的 </body> 标签之前。

    <body>
      <div>
        <!--main page content here-->
      </div>
      <!--modal here-->
    </body>
    

    这样做是因为模式通常具有覆盖页面的背景,要使用CSS来实现,您不需要处理父元素定位和z-index堆栈上下文,因此最简单的解决方案是将模式放在DOM的最底部。

    但这在Vue.js中产生了一个问题,它假定UI将作为一个单一的组件树来构建。为了允许将树的片段移动到DOM中的其他位置,在Vue 3中添加了一个新的 teleport 组件。

    要使用teleport,首先要在页面上添加一个元素,我们要将模态内容移动到该页面。我们将转到 index.html,并将ID为 modal-wrapperdiv 放在Vue的安装元素旁边。

    index.html

    <body>
      ...
      <div id="app"></div><!--Vue mounting element-->
      <div id="modal-wrapper">
        <!--modal should get moved here-->
      </div>
    </body>
    

    现在,回到 App.vue,我们将模态内容包装在 teleport 组件中。我们还需要指定一个 to 属性,为该属性分配一个查询选择器,以标识目标元素,在本例中为 #modal-wrapper

    src/App.vue

    <template>
      <button @click="toggleModalState">Open modal</button>
      <teleport to="#modal-wrapper">
        <modal v-if="modalOpen">
          <p>Hello, I'm a modal window.</p>
        </modal>
      </teleport>
    </template>
    

    就是这样,teleport 中的任何内容都将渲染在目标元素中。

    Emitting 和 event

    现在,让我们在modal中添加一个按钮,让它可以被关闭。要做到这一点,我们要在modal 模板中添加一个按钮元素,并添加一个点击处理程序,该处理程序会发出一个 close 事件。

    src/Modal.vue

    <template>
      <div class="modal">
        <slot></slot>
        <button @click="$emit('close')">Dismiss</button>
      </div>
    </template>
    

    然后,该事件将由父组件捕获,并将切换 modalState 的值,从逻辑上将其设置为 false 并导致窗口关闭。

    src/App.vue

    <template>
      ...
        <modal 
          v-if="modalOpen" 
          @click="toggleModalState"
        >
          <p>Hello, I'm a modal window.</p>
        </modal>
      </teleport>
    </template>
    

    到目前为止,此功能与Vue 2中的功能相同。但是,现在在Vue 3中,建议您使用新的 emits 组件选项显式声明组件的事件。就像props一样,你可以简单地创建一个字符串数组来命名组件将发出的每个事件。

    src/Modal.vue

    <template>...</template>
    <script>
    export default {
      emits: [ "close" ]
    }
    </script>
    

    变化的原因

    想象一下,打开别人写的组件的文件,看到它的prop和event明文声明。马上,你就会明白这个组件的界面,也就是它要发送和接收什么。

    除了提供自说明代码外,你还可以使用事件声明来验证你的事件有效载荷,虽然我在这个例子中找不到理由来验证。

    了解更多:Emits Option RFC

    样式插槽内容

    为了使模态可重用,我们提供了一个内容插槽。让我们开始通过为组件添加 style 标签来为内容设置样式。

    在我们的组件中使用 scoped CSS是一种很好的做法,以确保我们提供的规则不会对页面中的其他内容产生意外影响。

    让我们把任何被放入插槽中的段落文字变成斜体。要做到这一点,我们将使用 p 选择器创建一个新的CSS规则。

    src/Modal.vue

    <template>...</template>
    <script>...</script>
    <style scoped>
      p {
        font-style: italic;
      }
    </style>
    

    如果你尝试一下,你会发现这一点并不奏效。问题是,在编译时,当插槽内容仍属于父对象时,Scoped styling是在编译时确定的。

    Vue 3提供的解决方案是提供一个伪选择器 ::v-slotted(),允许你在提供插槽的组件中使用范围化规则来针对插槽内容。

    这是我们的用法:

    <style scoped>
      ::v-slotted(p) {
        font-style: italic;
      }
    </style>
    

    Vue 3还包含了其他一些新的Scoped Styling选择器:::v-deep::v-global,你可以在这里了解更多:Scoped Styles RFC

    其他改变

    好吧,这就是我可以在一个简单示例中涵盖的所有新功能。主要的我基本都有了,但这里有一些我认为很重要的,在总结文章之前,我觉得足够重要,可以自己研究一下。

    添加的:

    移出的:

    更改的:

    关于Vue Router也有各种变化,但我将专门用一篇文章来介绍这些变化!


    本文首发于公众号 《前端全栈开发者》,私信回复:大礼包,送某网精品视频课程网盘资料,准能为你节省不少钱!

    展开全文
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述前言2016年,我写了一系列的 VUE 入门教程,当时写这一系列博文的时候,我也只是一个菜鸟,甚至在写的过程中关闭了代码审查,否则通不过...

    Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述

    前言

    2016年,我写了一系列的 VUE 入门教程,当时写这一系列博文的时候,我也只是一个菜鸟,甚至在写的过程中关闭了代码审查,否则通不过校验。

    本来写这一系列的博文只是为了给自己看的,但没想到的是,这系列博文的点击量超过了2万以上,搜索引擎的排名也是非常理想,这让我诚惶诚恐,生怕我写的博文有所纰漏,误人子弟。

    再者,这一年的发展,VUE 项目快速迭代,看着我一年前写的博文,很可能各种提示已经发生改变,对照着过时的资料,非常可能导致新手在学习的过程中产生不必要的困扰。

    因此,本人决定,重写这个系列的博文,力求以简明、清晰、准确的图文以及代码描述,配合 github 的项目开源代码,给各位 VUE 新手提供一个高质量的入门文案。

    基本理念

    通过对接 cnode.js 的公开 api 的列表,以及详情页面,实现一个超小型的项目实战,尽可能的掌握 vue 的项目入门的各项关键配置。
    本系列博文不涉及 vuex 的内容。因为这部分内容属于比较高阶的内容,并且在大多数中小型项目中是没有多大用处的。所以情况是,大多数情况下,你并不需要 vuex。当你需要的时候,你应该有看懂官方文档的水平。如果你没有看懂官方文档的水平,我说再多都是没有什么用的。并且在 vue 的入门文档中涉及这部分内容的话,会给新手徒增烦恼,所以本系列博文不涉及 vuex 的内容。

    基础概念论述

    前后端分离开发模式

    在若干年前,我们的 WEB 项目开发模式是如下的:

    1. 设计师设计页面设计稿
    2. 前端工程师切成 html+css+js 的页面
    3. 后端工程师拿到前端工程师的做好的页面,利用模板引擎或其他技术嵌套进后端代码中,实现项目开发。

    这种开发模式的缺点是,哪怕页面出现一点点小的改变,也需要前端人员和后端人员同时协调开发,并且后端人员不能把全部精力放在业务流程以及数据逻辑等方面,还必须和前端人员一起来处理各种兼容问题。开发效率不高,沟通繁琐。

    所以,我们推崇前后端分离的开发模式。

    1. 设计师设计页面设计稿
    2. 前端工程师和后端工程师以及其他技术人员约定项目开发接口规范
    3. 后端工程师按照约定接口规范开发相应接口
    4. 前端工程师开发页面,并对接后端接口(可能先期采用假接口)开发页面

    与不分离的开发模式相比,对前端技术人员的技术要求高了很多,原先只需要会写静态页面即可,但是现在必须了解如何对接接口,以及其他很多内容。很多十年以上的前端开发人员在学习这些新内容的过程中,崩溃了。

    我经常在我的博客评论里,看到这样的评论 我艹,现在前端开发都这个样子了

    时代发展浩浩荡荡,你我不进则退,我作为十三年前端开发经验的人,也从13年开始,疯狂学习 JS 相关内容,否则,真的只有转业了。

    SPA

    不是指水疗。是 single page web application 的缩写。中文翻译为 单页应用程序单页Web应用。更多解释清参看 百度百科:SPA

    所有的前端人员都应该明白我们的页面的 url 构成:

    http://www.fengcms.com/index.html?name=fungleo&old=32#mylove/is/world/peace

    如上的 url 由以下部分组成:

    1. http:// 规定了页面采用的协议。
    2. www.fengcms.com 为页面所属的域名。
    3. index.html 为读取的文件名称。
    4. ?name=fungleo&old=32 给页面通过 GET 方式传送的参数
    5. #mylove/is/world/peace 为页面的锚点区域

    前面四个发生改变的时候,会触发浏览器的跳转亦或是刷新行为,而更改 url 中的锚点,并不会出现这种行为,因此,几乎所有的 spa 应用都是利用锚点的这个特性来实现路由的转换。以我们的 vue 项目为例,它的本地 url 结构一般为以下格式:

    http://localhost:8080/#/setting/task

    可以明显的看到我们所谓的路由地址是在 # 号后面的,也就是利用了锚点的特性。

    以上理解是我的个人描述,不代表百分百符合标准答案,但这样理解是没有问题的。

    RESTful 风格接口

    实际情况是,我们在前后端在约定接口的时候,可以约定各种风格的接口,但是,RESTful 接口是目前来说比较流行的,并且在运用中比较方便和常见的接口。

    虽然它有一些缺陷,目前 github 也在主推 GraphQL 这种新的接口风格,但目前国内来说还是 RESTful 接口风格比较普遍。

    并且,在掌握了 RESTful 接口风格之后,会深入的理解这种接口的优缺点,到时候,你自然会去想解决方案,并且在项目中实行新的更好的理念,所以,我这系列的博文,依然采用 http://cnodejs.org/ 网站提供的 RESTful 接口来实战。

    了解程序开发的都应该知道,我们所做的大多数操作都是对数据库的四格操作 “增删改查” 对应到我们的接口操作分别是:

    1. post 插入新数据
    2. delete 删除数据
    3. put 修改数据
    4. get 查询数据

    注意,这里是我们约定,并非这些动作只能干这件事情。从表层来说,除get外的其他方法,没有什么区别,都是一样的。从深层来说包括 get 在内的所有方法都是一模一样的,没有任何区别。但是,我们约定,每种动作对应不同的操作,这样方便我们统一规范我们的所有操作。

    假设,我们的接口是 /api/v1/love 这样的接口,采用 RESTful 接口风格对应操作是如下的:


    get 操作 /api/v1/love

    获取 /api/v1/love 的分页列表数据,得到的主体,将是一个数组,我们可以用数据来遍历循环列表

    post 操作 /api/v1/love

    我们会往 /api/v1/love 插入一条新的数据,我们插入的数据,将是JOSN利用对象传输的。

    get 操作 /api/v1/love/1

    我们获取到一个 ID 为 1 的的数据,数据一般为一个对象,里面包含了 1 的各项字段信息。

    put 操作 /api/v1/love/1

    我们向接口提交了一个新的信息,来修改 ID 为 1 的这条信息

    delete 操作 /api/v1/love/1

    我们向接口请求,删除 ID 为 1 的这一条数据


    由上述例子可知,我们实现了5种操作,但只用了两个接口地址, /api/v1/love/api/v1/love/1 。所以,采用这种接口风格,可以大幅的简化我们的接口设计。

    以上内容均为本人的认知与理解,与标准教科书肯定不一样。但有助于新人简洁明了的理解内容。更多内容,请查看:RESTful API 设计指南
    另外,RESTful 风格也不仅仅只有这几种操作,还有更多的操作。但我们常见的操作,就是这些。就好比我们不需要掌握了男女的全部卫生知识再去做爱一样,我一般崇尚的是,脱掉裤子,just do it now! 我们在不断的实践中,不断的提高我们的技术以及技巧,临渊羡鱼不如退而结网就是这个道理。

    vue 是什么,以及我们为什么选择 vue

    在我们公司的实际拓展中,由于选择框架时,angular 正在新旧交替,江山未稳,因此我们当时尝试在两个项目中引用不同的技术路线 reactvue

    实践证明,这两个都是非常优秀的框架。但是同时也证明,在前端初学者的面前,vue 的学习成本明显比 react 要低很多。

    在同样优秀,并且都能实现效果的情况下,我们选择了 vue 技术框架。

    所以,选择的理由特别的简单——只是因为它更简单!

    好,vue 是什么?

    我不管官方的解释是什么,我的解释如下:

    为了实现前后端分离的开发理念,开发前端 SPA 项目,实现数据绑定,路由配置,项目编译打包等一系列工作的技术框架

    这里,我们说的 vue 不仅仅是 vue.js 这一个文件,而是围绕 vue.js 配套的一系列的工具。就好比我们说的 linux 不仅仅是 linux 这个系统核心,而是包含了一整套外围工具的完整系统。

    具体如下:

    1. vue.js 核心,不解释。
    2. VueRouter2 实现路由组织工具。
    3. webpack 项目打包以及编译工具。
    4. nodejs 前端开发环境。
    5. npm 前端包管理器。
    6. axios ajax 接口请求工具。
    7. sass-loadernode-sass css 预处理。
    8. element 基于 vue 的后台组件库。
    9. iview 基于 vue 的另一套后台组件库。
    10. vue-cli vue 项目脚手架。一键安装 vue 全家桶的工具。

    其他还有很多,我们用到哪边,说哪边。

    命令行的重要性

    如果你依然沉浸在 GUI 的图形界面中无法自拔,对于 CLI 命令行充满恐惧或者敌视,那么,现实会残酷的告诉你,你落伍了。

    虽然有很多项目在尽力的实现这些内容的可视化操作,例如 iviewiView Cli ,我虽然肯定这些卓越的工程师做出的艰辛的努力,但是,不可否认的说,它也没有彻底的拜托命令行。

    并且,命令行

    更好

    更快

    更强

    更装逼

    所以,无论如何,你都不应该排斥命令行,还要积极的拥抱它,学习它,掌握它。

    甚至,关注我博客的同学可能会注意到,我前面自己甚至写了很多的 shell 的相关博客。要知道,我可是一个老前端工程师。这里我不是显摆我的资历,而是客观的评价自己,已经跟不上时代了。我所掌握的那些知识,是非常陈旧的。因此,只有不断的学习,才能不断的提高自己。

    我对你的建议如下:

    1. 抛弃 windows 操作系统,不管它是什么版本的 windows
    2. 购买一台 macbook pro 没钱购买可以选择 黑苹果 ,可以参考我的系列博文 打造前端MAC工作站以及相关文章索引
    3. 如果不是 photoshop 的重度用户,并且想要更深层次的掌握更多内容,请使用 linux 系统。ubuntu 操作系统还是比较简单上手的。有一定 linux 使用经验的同学,建议使用 arch linux 操作系统,新手不要尝试,因为你一定安装不上。
    4. 除了使用 atomvscode 这样的现代编辑器,更推荐掌握 vim 这样基于cli的编辑器的基本使用。能用到什么样的层次,取决于你自己的需求,相关内容可以参考:世界上最牛的编辑器: Vim系列博文。

    最后强调,别问我有关 windows 的问题,我很久没用过 windows 系统,并且关于系统底层的问题,我根本就不知道如何解决。

    我说的,你不一定要全部掌握或者理解。但一定要有一个起码的概念。至少,知道我说的大概是一个什么样的玩意儿。

    第一篇博文,基本没有涉及到任何代码的部分,但是下面,我们要开始干活儿了。

    如果文章由于我学识浅薄,导致您发现有严重谬误的地方,请一定在评论中指出,我会在第一时间修正我的博文,以避免误人子弟。

    本文由 FungLeo 原创,允许转载,但转载必须保留首发链接。

    展开全文
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由前情回顾在上一篇《Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(三)认识项目所有文件》,我们已经重新整理了...
  • Vue2+VueRouter2+webpack 构建项目实战(五)配置子路由

    万次阅读 多人点赞 2016-11-18 10:14:17
    Vue2+VueRouter2+webpack 构建项目实战(五)配置子路由前情回顾《Vue2+VueRouter2+webpack 构建项目实战(一)准备工作》《Vue2+VueRouter2+webpack 构建项目实战(二)目录以及文件结构》《Vue2+VueRouter2+...
  • Vue2+VueRouter2+webpack 构建项目实战(二)目录以及文件结构通过上一篇博文《Vue2+VueRouter2+webpack 构建项目实战(一)准备工作》,我们已经新建好了一个基于vue+webpack的项目。本篇博文将详细的厘清一下这个...
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(七)初识 *.vue 文件前情回顾在上一篇文章《Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(六)将接口用 webpack 代理到本地》中,我们顺利的将...
  • 使用vue2开发了微信公众号,现在登录后重定向出现如下问题 , 还望经验丰富的专家给与帮助。 流程 1、微信公众号按钮(指定的url) ; 2、router.beforeEach 拦截url判断有没有登录; 3、未登录,重定向到授权页面...
  • Vue2+VueRouter2+webpack 构建项目实战(三)配置路由,整俩页面先 2017年8月补充 2016年,我写了一系列的 VUE 入门教程,当时写这一系列博文的时候,我也只是一个菜鸟,甚至在写的过程中关闭了代码审查,否则通...
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(二)安装 nodejs 环境以及 vue-cli 构建初始项目在上一篇《Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述》中,我简要的说明了...
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(五)配置 Axios api 接口调用文件前情回顾在上一篇《Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由》,我们通过...
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(三)认识项目所有文件在《Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(二)安装 nodejs 环境以及 vue-cli 构建初始项目》中,我们通过安装 ...
  • Vue2集成UIkit

    千次阅读 2017-04-26 10:43:05
    Vue只是为我们提供了一个很优秀的前端组件式开发框架,但单纯依靠Vue是做不出一个漂亮的网页应用的,甚至连“不难看”这个标准都达不到。这个时候借助界面框架... 本文出自《Vue2实践揭秘》一书。2实践揭秘》一书。
  • 官方文档 vue https://cn.vuejs.org/v2/guide/vue-cli https://cli.vuejs.org/zh/ vue2 vue3 基于 vue-cli 基于 @vue/cli 初始化项目 ...
  • Leaflet的Vue组件 — Vue2Leaflet

    万次阅读 热门讨论 2018-04-29 18:18:09
    原文地址:Leaflet的Vue组件 — Vue2Leaflet 这两天折腾Vue,在GitHub上发现了一个开源项目Vue2Leaflet,Vue2Leaflet是一个Vue框架的JavaScript库,封装了Leaflet,它使构建地图变得更简单。本文简单介绍了如何...
  • Vue2 全局-Vue.set更新vue数据

    千次阅读 2017-09-03 16:06:43
    代码: {{ name }} --- {{ price }} --- {{ count }} 减少 function reduceOne() { Vue.set(cartData, 'count', cartData.count-1); } var cartData={ name:"T-shirt
  • vue2 使用vue-cli2 搭建项目

    千次阅读 2018-06-28 17:29:46
    npm install --g vue-cli 全局下载脚手架vue init webpack test 生成项目 形成基本结构npm install 依赖包npm run dev 启动项目配置Eslint 百度下规则配置路由配置 css js 文件夹在main.js 引用sass axios bus ...
  • 搭建vue2 vue-router2 webpack项目

    千次阅读 2016-11-18 18:37:51
    原文不断修错,补充等,这里更新会滞后一些,建议直接查看原文。...项目地址http://git.oschina.net/qinshenxue/vue2practice 之前出了一篇vue@1.x工程配置的文章《vue vue-router webpack》(下面简

空空如也

1 2 3 4 5 ... 20
收藏数 89,033
精华内容 35,613
关键字:

vue2

vue 订阅