入门Vue.js基础学习笔记记录,遇坑!

Vue.js基础学习笔记

我的主页:http://106.13.185.176:8889/#/home

资源免费提供,欢迎访问!

1.起步

1.1、文档

官方中文api:https://vuejs.bootcss.com/guide/

1.2、v-bind实例化变量传递

创建基础文件:index.html、style.css、app.js

  • index.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">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>Vuetitle>
head>

<body>
    <div id="vue-app">
        
        <h1>{
    { name }}h1>
        
        <p>{
    { greet("name") }}p>
        
        <p>
            
            
            <a :href="website">跳转a>
        p>
        
        <p v-html="websiteTag">
        p>
    div>
body>
<script src="app.js">script>

html>

注意:

用于加载vue

//—

{ { name }}

{ { greet("name") }}

  • app.js
//实例化vue对象
new Vue({
     
    el: "#vue-app", //elemenr,注入一个容器
    data() {
      //返回容器的对象
        return {
     
            name: "Tommy",
            echat: "20",
            website: "https://www.baidu.com",
            websiteTag: '跳转'	
        }
    },
    methods: {
     
        // // 第一个中写法,准备一个方法
        // greet: function () {
     
        //     return "Good night " + this.name;
        // }
        //第二种写法,准备一个方法
        greet(time) {
     
            //使用反引号,使用变量都得用${}
            return `Good ${
       time} ${
       this.name}`;
        }
    },
})

注意:

​ el: “#vue-app”, //elemenr,注入一个容器

后只能在这个容器里获取防护ide值

  • style.css

暂时没有用到

1.3、v-on事件绑定

  • app.js
new Vue({
     
    el: "#vue-app",
    data() {
     
        return {
     
            age: 10,
            x: 0,
            y: 0
        }
    },
    methods: {
     
        // 准备一个加一的方法
        add(v) {
     
            this.age += v;
        },
        subtract(v) {
     
            this.age -= v;
        },
        // 改变鼠标获取xy
        updateXY(event) {
      //这里注意调用该方法不能写成updateXY(),他会误以为你没有给参数,得写成updateXY
            this.x = event.offsetX;
            this.y = event.offsetY;
        },
        // 监听键盘按下的方法
        dow() {
     
            alert("你按下了键盘后并且按了alt键+enter键")
        }
    },
})

注意方法里调用属性值,使用this.属性名

  • index.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">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    
    <link rel="stylesheet" href="sytle.css">
    <title>dome02title>
head>

<body>
    <div id="vue-app">
        <p>
            我的年龄 {
    { age }}
        p>
        
        <button @click.once="subtract(1)">减一年button>
        <button v-on:click="add(1)">加一年button>
        <div id="mainDiv" v-on:mousemove="updateXY">
            x:{
    { x }},y:{
    { y }}
        div>
        
        <input type="text" placeholder="输入名字" @keydown.atl.enter="dow()">
    div>
    <script src="app.js">script>
body>

html>

注意:

事件绑定 v-on:,简写为@

调用mousemove方法不能updateXY(),

.once得一些修饰符,下面有说到

@keydown.atl.enter:

keydown:监听按下键盘
.alt.enter:按下alt键+enter键触发方法

  • sytle.css
#mainDiv {
     
    width: 300px;
    height: 300px;
    border: 1px solid sienna;
    text-align: center;
}
  • 事件修饰符
  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。
  • .left - (2.2.0) 只当点击鼠标左键时触发。
  • .right - (2.2.0) 只当点击鼠标右键时触发。
  • .middle - (2.2.0) 只当点击鼠标中键时触发。
  • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器

1.4、v-model双向数据绑定

  • app.js
new Vue({
     
    el: "#vue-app",
    data() {
     
        return {
     
            name: "",
            age: ""
        }
    },
    methods: {
     
        getAge() {
     
            //这里使用$refs获取传入的对象age里的value并赋给属性age,也能实现双向数据绑定
            this.age = this.$refs.age.value;
        }
    },
    // watch是用来监听属性只改变,只建议用来使用调式代码.
    watch: {
     
        age(v, o) {
     
            console.log("age的改变:新值:" + v + ",原始值:" + o);
        }
    },
})

注意:

&refs:获取ref传入的对象

watch是用来监听属性只改变,只建议用来使用调式代码.

  • index.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">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome03title>
head>

<body>

    <div id="vue-app">
        
        <input type="text" v-model="name">
        <p>
            {
    { name }}
        p>
        
        <input type="text" ref="age" @keydown="getAge()">
        <p>
            {
    { age }}
        p>
    div>
    <script src="app.js">script>
body>

html>

注意:

使用v-model来实现双向数据绑定,一般只在:input,select,textarea。

使用ref和$refs获取对象也能实现双向数据。

v-model的修饰符
v-model.lazy 只有在input输入框发生一个blur时才触发
v-model.trim 将用户输入的前后的空格去掉
v-model.number 将用户输入的字符串转换成number

1.5、computed属性数据方法

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome04title>
head>

<body>
    <div id="vue-app">
        <button @click="a++">Add abutton>
        <button @click="b++">Add bbutton>
        <p>A:{
    { a }}p>
        <p>B:{
    { b }}p>
        
        <p>age+A :{
    { addA }}p>
        <p>age+B :{
    { addB }}p>
    div>
    <script src="app.js">script>
body>

html>

注意:

调用computed方法不能带有();

  • app.js
new Vue({
     
    el: "#vue-app",
    data() {
     
        return {
     
            a: 0,
            b: 0,
            age: 0
        }
    },
    // methods: { //methods只要数据发生改变就回调用
    //     addA() {
     
    //         console.log("执行了addA");
    //         // return this.a + this.age;
    //     },
    //     addB() {
     
    //         console.log("执行了addB");
    //         // return this.b + this.age;
    //     }
    // },
    computed: {
      //computed属于计算属性,只有调用该方法才会执行
        //但每个方法一定有返回值
        addA() {
     
            console.log("执行了addA");
            return this.a + this.age;
        },
        addB() {
     
            console.log("执行了addB");
            return this.b + this.age;
        }
    },

})

注意:

如果使用methods只要属性有改变方法,将会全部调用。

computed调用时一定有返回值。

1.6、动态改变样式技巧

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome05title>
    <link rel="stylesheet" href="sytle.css">
head>

<body>
    <div id="vue-app">
        
        <button :class="btSytle" @click="isColor=!isColor">修改样式button>
    div>
    <script src="app.js">script>
body>

html>

注意:

:class绑定样式,使用isColor改变属性值

  • app.js
new Vue({
     
    el: "#vue-app",
    data() {
     
        return {
     
            isColor: false
        }
    },
    // 一般动态改变样式,使用计算属性方法
    computed: {
     
        //准备改变属性的计算属性方法
        btSytle() {
     
            return {
     
                bt1: this.isColor
            };
        }
    },
})

注意:

一般改变样式都使用计算属性方法。

btSytle返回一个class对象绑定 {样式名(id,class,Tag):属性值}

  • sytle.css
.bt1 {
     
    background: wheat;
}

.bt2 {
     
    background: red;
}

1.7、v-for,v-show判断是否显示标签控件

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome06title>
head>

<body>
    <div id="app-vue">
        条件1 <button @click="isShow=!isShow">{
    { isShow }}button>
        条件2 <button @click="isShow2=!isShow2">{
    { isShow2 }}button>
        
        <p v-if="isShow">
            显示if
        p>
        <p v-else-if="isShow2">
            显示else if
        p>
        <p v-else>
            显示else
        p>
        
        <p v-show="isShow">
            显示v-show
        p>
    div>
    <script src="app.js">script>
body>

html>

注意:

v-if与v-show的区别:

v-if:直接把标签去掉删掉

v-show:display: none;隐藏

  • app.js
new Vue({
     
    el: "#app-vue",
    data() {
     
        return {
     
            isShow: false,
            isShow2: true
        }
    },
})

1.8、v-for遍历值显示标签

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome07title>
head>

<body>
    <div id="app-vue">
        
        <div v-for="(user,index) in users">
            <p>
                {
    { index }}名字{
    { user.name }}年龄:{
    { user.age }}
            p>
        div>
        <hr>
        
        <template v-for="user in users">
            <template v-for="(val,key) in user">
                <p>
                    key:{
    { key }},val:{
    { val }}
                p>
            template>
        template>
    div>
    <script src="app.js">script>
body>

html>

注意:

div与template容器使用v-for的区别:

div会遍历容器,template只遍历内容

v-for遍历对象(val,key)顺序不能改

  • app.js
new Vue({
     
    el: "#app-vue",
    data() {
     
        return {
     
            users: [{
     
                    name: "小米",
                    age: 16
                },
                {
     
                    name: "小明",
                    age: 20
                },
                {
     
                    name: "小猪",
                    age: 19
                },
                {
     
                    name: "小王",
                    age: 18
                },
            ]
        }
    },
})

1.9、Vue里的全局机制(component)

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    <title>dome09title>
head>

<body>
    <div id="app-vue1">
        <p>
            {
    { title }}
        p>
        <p>
            <Greeting>Greeting>
        p>
    div>
    <div id="app-vue2">
        {
    { title }}
        
        <p>
            {
    { getApp2 }}
        p>
    div>
    <script src="app.js">script>
body>

html>

注意:

调用全局控件:

  • app.js
// 全局变量
let data = {
     
    name: "名字",
}
// 全局控件
Vue.component("Greeting", {
     
    //html模板
    template: "

全局控件取全局变量:{ { data.name }}

"
, //也可返回一个对象 data() { return { } } }) const vue1 = new Vue({ el: "#app-vue1", data() { return { title: "第一个标题" } }, methods: { }, }) new Vue({ el: "#app-vue2", data() { return { title: "第二个标题" } }, computed: { getApp2() { return vue1.title; } } })

注意:

全局变量定义在外面即可.

全局控件定义时给名,并在template里写入模板.

在容器app2想调用app1中的属性值,得实例化app1,并直接用实例化名"."点出来。

1.10、Vue访问网络

  • index.html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    
    <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    <title>dome10title>
head>

<body>
    <div id="app-vue">
        fetch <button @click="getFetch()">使用get获取数据button>
        <button @click="postFetch()">使用post获取数据button><br>
        axios <button @click="getAxios()">获取get数据button> <button @click="postAxios()">获取post数据button>
    div>
    <script src="app.js">script>
body>

html>

注意:

使用axios必须添加cdn:

//

  • app.js
new Vue({
     
    el: "#app-vue",
    data() {
     
        return {
     
            todo: {
     
                title: "",
                completed: false
            }
        }
    },
    methods: {
     
        getFetch() {
     

            //使用fetch获取数据
            const l = fetch("https://api.ooopn.com/yan/api.php")
                .then((res) => {
     
                    return res.json(); //返回一个json数据
                })
                .then((res) => {
     
                    console.log(res); //获取json数据
                })
                .catch((e) => {
     
                    //请求失败
                    console.log("请求失败")
                })
        },
        postFetch() {
     
            //使用post访问
            fetch("http://jsonplaceholder.typicode.com/posts", {
     
                method: "POST",
                body: JSON.stringify(this.todo),
                headers: {
     
                    "Content-type": "application/json"
                }
            }).then((res) => {
     
                return res.json();
            }).then((res) => {
     
                console.log(res)
            }).catch((e) => {
     
                console.log("请求失败")
            })
        },
        // 使用axios
        getAxios() {
     
            axios.get("https://api.ooopn.com/yan/api.php")
                .then((res) => {
     
                    console.log(res.data);
                })
                .catch((e) => {
     
                    console.log("请求失败!")
                })
        },
        postAxios() {
     
            axios.post("http://jsonplaceholder.typicode.com/posts", this.todo)
                .then((res) => {
     
                    console.log(res.data);
                })
                .catch((e) => {
     
                    console.log("请求失败!")
                })
        }
    },

})

注意:

Fetch:

​ get:第一个then负责返回一个json数据,后面的then才是对象

​ post:在bodyl里添加json对象参数,headers负责指定类型,catch里请求失败的回调

axios:

​ get:无需那么复杂直接.get第一个then里返回的数据.data就是对象,catch请求失败的回调

​ post:无需那么复杂直接.post第二个参数就是json对象参数,然后then返回的数据.data就是对象了,catch请求失败的回调.

2、VUE脚手架

2.1、环境准备

  • 下载nodejs:https://nodejs.org/en/

  • 安装node.js后在cmd里使用命令下载VUE脚手架

检查node.js安装是否成功

node -v

npmm -v

在cmd里使用命令下载vue/cli 3一定要3

npm install -g @vue/cli

注意:如果下载较慢配置改错taobao镜像国内的就快了

npm config set registry https://registry.npm.taobao.org --global

npm config set disturl https://npm.taobao.org/dist --global

检测:

vue --versoin

  • 然后安装nmp下载插件加速插件

npm.taobao.org/网站里:

npm install -g cnpm --registry=https://registry.npm.taobao.org

检测:

cnpm --version

2.2、创建VUE脚手架项目

2.2.1、命令创建

  • 创建

vue create vuecli-demo(vuecli-demo是项目名)

选中:Manually select features(手动创建)

选中:Babel (按空格选择)

选中:In package.json(管理我们用的包)

输入:n不是模板名,使用自己的名字。

  • 启动项目

进入项目

cd 项目名/

启动项目:

npm run serve

  • cli4去掉es代码规范
module.exports = {
     
  root: true,
  env: {
     
    node: true
  },
  extends: [
    'plugin:vue/essential',
    //'@vue/standard'
  ],
  parserOptions: {
     
    parser: 'babel-eslint'
  },
  rules: {
     
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
  }
}

注意:

删掉’@vue/standard’即可。

2.1.2、图像化ui操作(vuecli版本得3)

进入ui图形化操作模式

  • vue ui

  • 创建项目:点击项目–选择好路径创建即可。

  • 第一次可以选择手动

  • 选择Choose Vue versin、Babel、Router(其他的看需求)

  • 去掉(Linter/Formatter)代码严谨

  • 创建项目

  • 运行项目:任务 serve运行即可。

安装插件:点击插件-----添加插件搜搜安装后配置即可—重写运行。

2.3、文件结构解析

  • README.md
全是命令行
# vuecli-demo01

## Project setup
​```
npm install			//安装项目的依赖包
​```

### Compiles and hot-reloads for development
​```	
npm run serve		//启动项目并编译
​```	

### Compiles and minifies for production
​```
npm run build		//对项目打包
​```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

  • package.json
{
     
  "name": "vuecli-demo01",
  "version": "0.1.0",
  "private": true,
    //当前项目的启动方式:serve可以修改,但修改后npm run 修改后的值
  "scripts": {
     
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
    //项目依赖
  "dependencies": {
     
    "core-js": "^3.6.4",
    "vue": "^2.6.11"
  },
    //项目插件
  "devDependencies": {
     
    "@vue/cli-plugin-babel": "~4.2.0",
    "@vue/cli-service": "~4.2.0",
    "vue-template-compiler": "^2.6.11"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

  • package-lock.json

项目提供

  • babel.config.js
//对vue处理
module.exports = {
     
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

  • .gitignore
.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

忽略文件,为了更好的提交重要文件。

  • public文件夹

    • favicon.icon

      网站图标

    • index.html

    
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title><%= htmlWebpackPlugin.options.title %>title>
      head>
      <body>
        <noscript>
          <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
        noscript>
        <div id="app">div>
        
      body>
    html>
    

    主页:

    vue容器

  • node_modules

所有插件存放的地方。

注意:

收到别人项目,或发给别人项目,是没有node_modules文件的。

需要自己使用命令通过package.json提供参数下载回来:

cnpm install

  • sec文件夹

    • assets文件夹:静态文件,css,js…

    • components文件夹:包含的都是组件

      <template>
          
        <div class="hello">
          <h1>{
              { msg }}h1>
          <p>
            For a guide and recipes on how to configure / customize this project,<br>
            check out the
            <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentationa>.
          p>
          <h3>Installed CLI Pluginsh3>
          <ul>
            <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babela>li>
          ul>
          <h3>Essential Linksh3>
          <ul>
            <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docsa>li>
            <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Foruma>li>
            <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chata>li>
            <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twittera>li>
            <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">Newsa>li>
          ul>
          <h3>Ecosystemh3>
          <ul>
            <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-routera>li>
            <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuexa>li>
            <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtoolsa>li>
            <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loadera>li>
            <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vuea>li>
          ul>
        div>
      template>
      
      <script>
      export default {
                
        name: 'HelloWorld',
        props: {
                
          msg: String
        }
      }
      script>
      
      
      
      <style scoped>
      h3 {
                
        margin: 40px 0 0;
      }
      ul {
                
        list-style-type: none;
        padding: 0;
      }
      li {
                
        display: inline-block;
        margin: 0 10px;
      }
      a {
                
        color: #42b983;
      }
      style>
      
      
    • App.vue:根组件

    
    
    
    
    
    
    
    • main.js:逻辑入口点

      import Vue from 'vue'
      import App from './App.vue'
      
      Vue.config.productionTip = false
      
      new Vue({
               
        render: h => h(App),
      }).$mount('#app')
      
      

      注意:

      vue先入index其次进入main.js

      .$mount(’#app’):最后放再#app容器中

2.4、组件嵌套的使用

2.4.1、全局组件(使用频率不高)

  • 新建一个组件





注意:

遍历数组一定得加key值而且是唯一的。

  • 在main文件使用
import Vue from 'vue'
import App from './App.vue'
// 注册全局组件
// 1.引入组件
import Users from './components/Users'
// 2.注册全局组件
Vue.component("users", Users)
Vue.config.productionTip = false

new Vue({
     
  render: h => h(App),
}).$mount('#app')

2.4.2、局部组件(使用频率高)

  • 在App.vue界面引用






2.4.3、多个组件使用

  • Header.vue头部组件



  

  • Users.vue



  

  • Footer.vue尾部



  


  • App.vue界面引用






2.5、vue脚手架样式问题




  

在style里写一个scoped标志值在当前页面使用,一般都这样使用。

如果不加可能会只要导入的都使用了。

2.6、数据绑定传输与修改

  • App.vue






注意:

App.vue中准备数据users,

引用组件时绑定数据

:users=“users”,users可以随便取赋值给的是值

  • Users.vue






注意:

传入的strnig 、number、boolean都是传入值。

传入的array、object都是引用的。

值:修改哪个值,哪个值会变。

引用:引用的是指针对象,修改一个全部都修改。

  • Footer.vue

{ {title}}

methods: { btTitle(){ // 在这里如果要修改父容器的值,得注册事件修改 // this.title = "修改"//这样直接修改会报错 this.$emit("titleUpdata","通过注册事件修改后的值"); //这样修改父容器的值就不会错了。 } },

添加修改title的事件

methods: { updateTitle(title){ this.title = title; } },

使用注册的事件:titleUpdata

2.7、VUE的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rZBwMK61-1590412890570)(E:\Typora_text\images\vue1.png)]

export default {
  name: 'HelloWorld',
  data() {
      return {
          title:"Vue Componrnts Demo"
      }
  },
  // 测试生命周期
  beforeCreate() {
    alert("进入了beforeCreate了,data还没实例化。")
  },
  created() {
    alert("进入了creaed了,实例化了data了")
  },
  beforeMount() {
    alert("进入了beforeMount了,页面准备挂载还没显示")
  },
  mounted() {
    alert("进入了mounted了,页面已经显示了。")
  },
  beforeUpdate() {
    alert("进入了beforeUpdate了,页面准备刷新数据和页面。")
  },
  updated() {
    alert("进入了updated了,页面数据和页面刷新完毕。")
  },
  beforeDestroy() {
    alert("进入了beforeDestroy了,页面准备销毁")
  },
  destroyed() {
    alert("进入了destroyed了,页面销毁完毕。")
  },
}

2.8、父类传入元素:slot

  • App.vue

{ {title}}

注意:

内容可以指定slot,也可以不指定。

  • Header.vue

注意

slot可以理解占位,如果没有name,它会把父类引用里的全部显示。
slot的样式问题:无论在父类还是子类都能获取元素
slot的获取值问题:它只能获取父类的data里的值

2.9、动态组件(components),缓存动态组件(keep-alive)

  • Framgent1.vue:第一个组件



  

  • Fragment2.vue:第二个组件



  


  • App.vue






注意:
components通过:is引入组件,但引入的组件有个缓存的问题。

如果你切换组件,输入框的内容降消失。

加上keep-alive后就是添加了缓存机制。

2.10、自定义vue脚手架模板

添加模板:

vue create 项目名

选中Manually select fatures

使用空格选中你需要的插件

选中需要的:我—ESLint + Standard config等等

选择 Lint on save保存 刚的选择

选择In dedicated config files

选择y设置为模板,输入你的模板名

删除模板:
win在用户文件夹里找到.vuerc文件删除需要删除的即可,保存

2.11、添加插件

添加:

vue add 插件

选择默认,然后默认

2.12、给项目创建全局环境变量

  • 启动模式得概念

你执行npm run serve时,对应的环境就是开发环境;

你执行npm run build时,对应的环境就是生产环境。

  • 可以自定义其他模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhRM0yE1-1590412890572)(E:\Typora_text\images\vue2.png)]

​ 设置启动模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88XwoPal-1590412890573)(E:\Typora_text\images\vue3.png)]

  • .env

VUE_APP_URL=http://localhost:8080

这里我们使用开发环境

  • Test1.vue



注意:

添加新得env文件一定得重启vue

通过data实例化出url使用process.env.VUE_APP_URL获取env里得值。

引用url即可。

2.13、添加全局启动vue(可以单独启动一个vue页面)

首先添加全局启动插件

npm install -g @vue/cli-service-global

启动即可:

vue serve Test.vue(vue界面)

2.14、vue教手架得ui模式

进入ui图形化操作模式

vue ui

创建项目:点击项目–选择好路径创建即可。

运行项目:任务 serve运行即可。

安装插件:点击插件-----添加插件搜搜安装后配置即可—重写运行。

2.15、vue的基础配置

  • vue.config.js
module.exports = {
     
    "transpileDependencies": [
        "vuetify"
    ],
    //这个是4.0后写法
    publicPath: process.env.NODE_ENV === 'production' ?
    './' : '/', //访问目录
    outputDir: "dist2", //打包后输出得目录名:npm run build
    assetsDir: "assets", //静态资源目录(js,css,img,fonts)
    lintOnSave: false, //是否eslint保存检测,有效值:true||false||error
    // 网络配置
    devServer: {
     
        open: true, //在运行自动打开浏览器
        host: "localhost", //主机号
        port: 8081, //端口号
        https: false, //是否以https模式启动
        hotOnly: false, //热更新(启动)
        //跨域配置:暂时不报错:When `proxy` in package.json is an object, each `context` object must have a `target` property specified as a url string
        // proxy: {
     
        //   '/api': {
     
        //     target: 'http://www.baidu.com/',
        //     pathRewrite: {
     
        //       '^/api': ''
        //     },
        //     changeOrigin: true, // target是域名的话,需要这个参数,
        //     secure: false, // 设置支持https协议的代理
        //   },
        //   '/api2': {
     
        //     "api": "api"
        //   }
        // }
    }

3、实战项目(电商)

3.1、创建项目

  • 选择预设
  • 选择功能
    • Babel
    • Router
    • Linter/Formatter
    • 使用配置文件
  • 配置路由
    • 关闭历史路由,默认使用哈希路由
    • 选择ESLint + Standard config文件格式
    • 选择lint on save
  • 添加插件
    • vue-cli-plugin-element
    • 修改插件配置:import Element:import on demand(按区导入)
  • 添加依赖
    • axios安装在运行依赖
    • less安装在开发依赖–less-loader
  • 去掉es代码规范:在.eslitrc.js文件中删除’@vue/standard’

3.2、初始化项目并存入Github

  • 把项目做处理(删除没必要的文件与代码)。

  • 初始化文件:git init

  • 查看添加状态:git status

  • 修改配置:

    • git config --global user.name “账号”
    • git config --global user.email “邮箱”
  • 添加文件:git add .

  • 提交文件:git commit -m “描述”

  • 推送远程仓库:

    • git remote add origin 仓库链接
    • git push -u origin master

3.3、分支login,编写Login功能

3.3.1、在components创建一个Login文件并导入App.vue

3.3.2、加入到访问路由中

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'

Vue.use(VueRouter)

const routes = [
  //访问
  {
     
    path: '/login',
    component: Login
  },
   //重置-/*dcv.binojpkl[]/\*
  {
     
    path: "/",
    redirect: "/login"
  }
]

const router = new VueRouter({
     
  routes
})

export default router

3.3.3、添加一个全局的css样式

  • 在assets里创建一个css文件夹里放入全局css样式,
  • 在main.js全局入口导入css:import ‘./assets/css/mainCss.css’

3.3.4、编写表单

  • 组件网站:https://element.eleme.cn/#/zh-CN/component/installation
  • 加入el组件,(plugins文件夹—element.js)
import Vue from 'vue'
import {
     
  Button
} from 'element-ui'
import {
     
  Form,
  FormItem
} from 'element-ui'
import {
     
  Input
} from 'element-ui'

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
  • 写入表单
<template>
  <div class="login_mainDiv">
    <div class="login_center">
      
      <div class="login_topImg">
        <img src="../assets/logo.png" />
      div>
      
      <el-form class="login_form">
        
        <el-form-item label-width="0px">
          <el-input>el-input>
        el-form-item>
        
        <el-form-item label-width="0px">
          <el-input>el-input>
        el-form-item>
        
        <el-form-item class="loginBts">
          <el-button type="primary">登陆el-button>
          <el-button type="info">重置el-button>
        el-form-item>
      el-form>
    div>
  div>
template>

3.3.5、编写访问网络进行登陆

  • 导入axios,并设置访问头
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
// 导入全局的Css
import './assets/css/mainCss.css'
// 导入配置axios
import axios from 'axios'
axios.defaults.baseURL = "https://v1.hitokoto.cn/" //给axios配置访问头
Vue.prototype.$http = axios //给vue的http配置访问头

Vue.config.productionTip = false

new Vue({
     
  router,
  render: h => h(App)
}).$mount('#app')

注意:

我们测试访问头设置头https://v1.hitokoto.cn/

  • 导入组件
import Vue from 'vue'
import {
     
  Button
} from 'element-ui'
import {
     
  Form,
  FormItem
} from 'element-ui'
import {
     
  Input
} from 'element-ui'
// 导入el的弹窗
import {
     
  Message
} from 'element-ui'
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
// 全局挂载el的弹窗
Vue.prototype.$message = Message;

注意:

Vue.prototype. m e s s a g e = M e s s a g e ; 全 局 挂 载 , 后 可 以 使 用 t h i s . message = Message;全局挂载,后可以使用this. message=Message;使this.message直接调用里的方法

  • login.vue





注意:

我们使用的是el-模式特别注意表单的结构。

使用$refs就可以获取表单了,然后调用表单里的方法。

本次测试const res = await this.$http.get("", this.loginForm);没有访问尾,只要访问通过就算登陆成功

3.3.6、登陆成功进行跳转

  • Login.vue
//登陆成功给seesionStorage里存入值以来验证是否登陆过
window.sessionStorage.setItem("isLogin", this.loginForm.user);
//并跳转页面
this.$router.push({ path: "/home" });

注意:

sessionStorage用来验证是否登陆,一般服务器给。

this.$router.push进行跳转

​ 一定设置路由,一定把App.vue里设置视图

  • App.vue






注意:

在这里不能直接写组件,写上即可

之后使用路由来跳转。

  • router—index.js路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '@/components/Login.vue'
import Home from '@/components/Home.vue'

Vue.use(VueRouter)

const routes = [
  // 登陆
  {
     
    path: '/login',
    name: 'login',
    component: Login,
    meta: {
     
      title: '登录页'
    },
  },
  {
     
    path: '/',
    redirect: "/login",
    component: Login,
    meta: {
     
      title: '登录页'
    },
  },
  // 主页
  // 登陆
  {
     
    path: '/home',
    name: 'home',
    component: Home,
    meta: {
     
      title: '主页'
    },
  },
]

const router = new VueRouter({
     
  routes
})

export default router

注意:

这是vuecli4的写法

@是转换

3.3.7、登陆后的访问页面权限

  • router—index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '@/components/Login.vue'
import Home from '@/components/Home.vue'

Vue.use(VueRouter)

const routes = [
  // 登陆
  {
     
    path: '/login',
    name: 'login',
    component: Login,
    meta: {
     
      title: '登录页'
    },
  },
  {
     
    path: '/',
    redirect: "/login",
    component: Login,
    meta: {
     
      title: '登录页'
    },
  },
  // 主页
  // 登陆
  {
     
    path: '/home',
    name: 'home',
    component: Home,
    meta: {
     
      title: '主页'
    },
  },
]

const router = new VueRouter({
     
  routes
})
//路由权限跳转
router.beforeEach((to, from, next) => {
     
  //to 将要访问的路径
  //from 代表哪个路径访问来的,
  //next 是一个函数:next()放行,next("/xx")强制跳转
  if (to.path == "/login") {
     
    next(); //如果是登陆界面就放行
    return;
  }
  //获取sesstion里的值
  const sesstion = window.sessionStorage.getItem("isLogin");
  console.log(sesstion)
  if (sesstion == null) {
     
    next("/login"); //如果是空就强制跳转到login页
    alert("请登陆后重试!")
  } else
    next(); //否则直接放行

})
export default router

注意:

beforeEach方法是router专门做访问权限的。

to 将要访问的路径
from 代表哪个路径访问来的,
next 是一个函数:next()放行,next("/xx")强制跳转

  • 拦截axios
axios.interceptors.request.use(config=>{
     
    //为请求头对象,添加token验证
    config.headers.Authorization = window.sessionStorage.getIntem("isLogin");
    return config;
})

注意:

在调用axios之前回调用interceptors.request.use。

在之前我们提交一个Authorization

写在main.js里

3.3.8、退出用户

  • Home.vue





注意:

window.sessionStorage.clear(); //清空sessionStorage
this.$router.push("/login"); //跳转访问

3.3.9、把完成号的login分支添加/提交/合并/上传

查看分支:git branch

查看提交状态:git status

添加: git add .

提交: git commit -m “提交描述”

切换回master主分支:git checkout master

合并: git merge login(分支名)

上传:git push(这个是第二次上传可以这样简写)

把login分支推送github:git push -u origin login(云端的分支名)

3.4、语法规则

3.4.1、规定引号

新建一个.prettierrc

{
     
    "semi":false,   //取消双引号
    "singleQuote":true  //使用单引号
}

注意:

如果又语法规则错误,在.eslintrc.js里的rules对象里添加保存的规则赋值为0取消规则

列:

{

‘xxxx’:0

}

3.5、主页编写

3.5.1、搭建主页框架

我们使用element-ui

自己在src里创建一个plugic文件夹里的element.js

最后的到main.js里导入文件夹。

  • 导入组件
import Vue from 'vue'
import {
     
  Button,
  Form,
  FormItem,
  Input,
  Message,
  Container,
  Header,
  Aside,
  Main
} from 'element-ui'
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
// 全局挂载el的弹窗
Vue.prototype.$message = Message;

  • Home.vue:使用上下,中左右框架





注意:

我们使用的element样式编写的架构。

justify-content样式使用:

flex-start 默认值。项目位于容器的开头。
flex-end 项目位于容器的结尾。
center 项目位于容器的中心。
space-between 项目位于各行之间留有空白的容器内。
space-around 项目位于各行之前、之间、之后都留有空白的容器内。
initial 设置该属性为它的默认值。请参阅 initial
inherit 从父元素继承该属性。请参阅 inherit

3.5.2、主页菜单项

  • 添加组件element.js
import Vue from 'vue'
import {
     
  Button,
  Form,
  FormItem,
  Input,
  Message,
  Container,
  Header,
  Aside,
  Main,
  Menu,
  Submenu,
  MenuItem
} from 'element-ui'
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
// 全局挂载el的弹窗
Vue.prototype.$message = Message;

  • Home.vue





注意:

slot="title"时element里的样式,不加则看不到文字效果.

这里我们模拟自己数据。

我们拿数据进行for来渲染布局:这里只要注意使用对象的遍历。

el-menu特别属性

  • background-color:菜单项的背景
  • text-color:菜单项文字颜色
  • active-text-color:菜单项文件点击后的颜色
  • unique-opened:只能打开一个菜单项
  • collapse:是否收起,使用默认是false没有收起,ture收起
  • collapse-transition:是否开启折叠动画

3.5.3、插入刚进入的欢迎页

  • 导入子路由:router—index.js
import welcome from '@/components/Welcome.vue'	 

{
     
    path: '/home',
    name: 'home',
    component: Home,
    meta: {
     
      title: '主页'
    },
    //home的子路由
    children: [{
     
      path: "/welcome",
      component: welcome
    }],
    redirect: "/welcome" //刚进入home发送/welcome
  },
  • 在element里的main里写入路由占位符


    
    

3.5.4、开启菜单项的路由模式

  • 在Home.vue里的el-menu里加上属性:router给ture
  • 开启后每个菜单项的index里的值就是点击后访问的地址但要自己补全/

    //---------
    
        //------------
   {
          id: 0,
          authName: "用户管理",
          children: [{ id: "0-1", name: "用户列表", path: "/users" }],
          icon: "el-icon-user-solid"
        },

3.5.5、点击激活高亮菜单项

  • Home.vue

    
    
        //-----------

注意:

default-active:给的值就是激活高亮的菜单项

@click=“onMenu = chiItem.path”:点击后把onMenu赋值

3.5.6、编写表格来承载所有用户

  • 在element.js中添加组件
  • User.vue



注意:

使用el的分栏
row里:gutter:是col之间的距离,
col里:span是栅格占据的列数,列

添加el表格
tbale的:data:是绑定数据对象,border添加边框线,stripe隔行变色
comlumn的是头标签,prop:是绑定data对象里的属性,如果设置

​ 这里的slot-scope是获取当前对象的值scope.row就是值得对象

​ 使用scope.row点出想要获取当前数据对象的属性

3.5.7、添加用户

  • 导入组件
  • User.vue
   
    
      
      
        
          
        
        
          
        
        
          
        
        
          
        
      
      
      
        取 消
        确 定
        重置
      
    
//--------------------------
//在data()里添加,自定义校验数据
   // 自定义数据验证规则:邮箱
    var checkEmail = (rule, value, ch) => {
      // 正则验证邮箱
      const reg = /^([\.a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/
      if (reg.test(value)) {
        //合法邮箱
        return ch()
      }
      ch(new Error("请输入合法的邮箱!"))
    }
    // 自定义数据验证规则:手机
    var checkPhone = (rule, value, ch) => {
      // 正则验证手机
      const reg = /^[1][3,4,5,7,8,9][0-9]{9}$/
      if (reg.test(value)) {
        //合法手机
        return ch()
      }
      ch(new Error("请输入合法的手机!"))
    }
//准备数据
   addFormRules: {
        //添加数据对象,的检测数据
        name: [
          {
            required: true,
            message: "请输入用户名",
            trigger: "blur"
          },
          { min: 3, max: 10, message: "用户名长度:3-10字符", trigger: "blur" }
        ],
        pwd: [
          {
            required: true,
            message: "请输入用户密码",
            trigger: "blur"
          },
          { min: 6, max: 15, message: "用户密码长度:6-15字符", trigger: "blur" }
        ],
        email: [
          {
            required: true,
            message: "请输入用户邮箱",
            trigger: "blur"
          },
          {
            validator: checkEmail,
            trigger: "blur"
          }
        ],
        // 调用自定义的数据校验:
        //validator指定校验的对象,trigger:焦点触发
        phone: [
          {
            required: true,
            message: "请输入用户手机",
            trigger: "blur"
          },
          {
            validator: checkPhone,
            trigger: "blur"
          }
        ]
      }
    }

注意:

点击添加的对话框!

dialog里title:提示标题,:visible.sync是否打开对话框,width:宽度

表单区

form里:model绑定数据,rules:数据检测对象,ref:添加后的对象传入ref

formItem里label:是输入框开头文字,prop:是传入rules对象的属性,@close:是关闭后的回调(这里不需要)

3.5.8、删除用户

  • 导入全局的MessageBox
MessageBox
Vue.prototype.$confirm = MessageBox.confirm;
  • User.vue
    //删除用户方法
    deleteUser(data) {
      // 点击el的是否弹出框:type指定小图标的样式
      //返回值是promise可以使用.then来获取或asyns+await
      this.$confirm("此操作将永久删除该用户, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        // 点击确定的时候,如果发生错误,他会自动执行catch
        .then(() => {
          this.FUserList.splice(data.id, 1)
          this.$message({
            type: "success",
            message: "删除成功!"
          })
        })
        //点击取消
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          })
        })
    }

注意:

点击el的是否弹出框:type指定小图标的样式
返回值是promise可以使用.then来获取或asyns+await

点击确定的时候,如果发生错误,他会自动执行catch

3.5.9、权限列表

  • 权限列表

添加路由

Rights.vue

    
    
      首页
      权限管理
      权限列表
    
    
    
      
        
        
        
        
          
        
      
    

注意:

操作差不多

3.5.10、分配权限

  • Roules.vue

    
      
      
      
      
        取 消
        确 定
      
    
//----
//分配权限
    getAllRole() {
      this.isRoles = true
    },
    alloRights() {
      this.isRoles = false
      let s = ""
      // getCheckedNodes是tree里的方法,获取选中节点的id
      for (let i = 0; i < this.$refs.treeRef.getCheckedNodes().length; i++) {
        s += this.$refs.treeRef.getCheckedNodes()[i].$treeNodeId + ","
      }
      this.$message.success(s)
    }

注意:

tree的使用

show-checkbox:是否可选择,data:数据,props显示的对象
treProps: { label: “name”, chidren: “chidren” },
default-expand-all:默认展开所有节点
node-key:指定每个节点的唯一id
default-expanded-keys:默认显示勾选节点,提供一个数组即可

获取选中节点的id

this.$refs.treeRef.getCheckedNodes()

3.5.11、商品分类

  • 添加组件
  • Cate.vue


    
    
    
    
    
    
    



    
    
        
            
        
        
            
            
        
    
    
        取 消
        确 定
    

注意:

//导入插件:vue-table-with-tree-grid

import TreeTable from 'vue-table-with-tree-grid’

//注册:vue-table-with-tree-grid

Vue.component(“tree-table”, TreeTable)

表格:vue-table-with-tree-grid的插件:https://github.com/MisterTaki/vue-table-with-tree-grid
data:绑定数据,
columns:绑定列的数据,
selection-type:是否显示复选框
expand-type:是否位展开行,注意展开与分组是不一样的
show-index:是否显示数据索引,index-text:数据索引的名称
boder:是否显示竖向边框

级联选择器
options:数据源 ,
@change:选中发生变化得回调
Props:{
label指定选项标签为选项对象的某个属性值
value指定选项的值为选项对象的某个属性值
children指定选项的子选项为选项对象的某个属性值
expandTrigger:触发
}
clearable:是否支持清空
change-on-select:是否可以选中一级级联

…后面都是控件技术省略

4、项目的打包与优化。

4.1、打build包并运行项目

打包:可以在ui里运行build包,也可以运行命令:npm run build

操作后会导出一个dist文件(项目文件)

这就代表打包成功

运行:在dist文件同级目录创建一个app.js文件

//导入express
const express = require('express')
    const app = express()
    //托管的静态资源
    app.use(express.static('./dist'))
    app.listen(80, () => {
      
        console.log("服务器启动成功!:http://127.0.0.1")
    })

在该目录初始化node

npm init -y

安装express插件管理项目

npm i express -S

最后启动项目

node .\app.js

4.2、优化项目

4.2.1、打包后去掉console打印

插件名:transform-remove-console

在babeLconfig.js里可以判断是否打包运行然后加入插件

4.2.2、使用externals减少打包后文件大小

无论是element组件还是echart插件都可以使用导入.

具体百度

4.2.3、设置路由懒加载

懒加载:可以减少加载控件的压力,需要哪个控件就记载哪个。

1:安装开发依赖@babel/plugin-syntax-dynamic-import

2:babel.config.js中声明插件

3:将路由改为这种加载格式:

const Foo = () => import(/* webpackchunkName: “group-foo” */ ‘./Foo.vue’)
(Foot是名称,import里/里是分组/,‘里是组件’)

文档:参考链接:https://router.vuejs.org/zh/guide/advanced/lazy-loading.html

4.2.4、compressoin 减少传输文件的大小

app.js中导入插件:const compression = require(‘comression’) app.use(compression)

4.2.5、以https启动项目
  • 申请SSL证书

​ ----进入https://fressl.cn官网,选择域名与品牌
​ ----输入自己的邮箱并选择相关选择
​ ----验证dns(在域名管理后台添加TXT记录)
​ ----验证通过后,下载SSL证书(full_chain.pem公钥;prvate.key私钥)

  • 导入整数并启动https服务器
const https = require('https')
const fs = require('fs')
const options={
     cret:'fs.readFileSync('./full_chain.pem')',key:'fs.readFileSync('./private.key')'}
  • 启动https服务器:443是默认端口
https.createServer(optoins,app).listen(443)
4.2.6、pm2托管项目

pm2:关闭运行终端依旧可以运行项目

​ ----安装插件 npm i pm2 -g
​ ----pm2 start 脚本(./app.js) --name 自定义启动项目名
​ ----查看所有运行项目:pm2 ls
​ ----重启项目:pm2 restart 自定义名称
​ ----停止项目:pm2 stop 自定义名称
​ ----删除项目:pm2 delete 自定义名称

5、特殊报错

5.1、启动

  • 报错关键字:Module build failed (from ./node_modules/babel-loader/lib/index.js):
  • 报错原因:插件更新了需要重写下载
  • 解决:删除node_modules文件,运行npm i重写下载即可52

5.2、访问接口,跨域问题

  • 代理解决

//const API_PROXY = 'https://bird.ioliu.cn/v1/?url='	//代理接口
 "https://bird.ioliu.cn/v1/?url=" +接口	//拼接即可

ns:数据源 ,
@change:选中发生变化得回调
Props:{
label指定选项标签为选项对象的某个属性值
value指定选项的值为选项对象的某个属性值
children指定选项的子选项为选项对象的某个属性值
expandTrigger:触发
}
clearable:是否支持清空
change-on-select:是否可以选中一级级联
–>
v-model=“catevalue”
:options=“cateData”
:props="{ expandTrigger: ‘hover’,label:‘name’,checkStrictly: true }"
@change=“cateChange”
clearable
>



取 消
确 定


> 注意:
>
> **//导入插件:vue-table-with-tree-grid**
>
> **import TreeTable from 'vue-table-with-tree-grid'**
>
> **//注册:vue-table-with-tree-grid**
>
> **Vue.component("tree-table", TreeTable)**
>
> 表格:vue-table-with-tree-grid的插件:https://github.com/MisterTaki/vue-table-with-tree-grid
> data:绑定数据,
> columns:绑定列的数据,
> selection-type:是否显示复选框
> expand-type:是否位展开行,注意展开与分组是不一样的
> show-index:是否显示数据索引,index-text:数据索引的名称
> boder:是否显示竖向边框
>
> 级联选择器
> options:数据源 ,
> @change:选中发生变化得回调
> Props:{
> label指定选项标签为选项对象的某个属性值
> value指定选项的值为选项对象的某个属性值
> children指定选项的子选项为选项对象的某个属性值
> expandTrigger:触发
> }
> clearable:是否支持清空
> change-on-select:是否可以选中一级级联

....后面都是控件技术省略

### 4、项目的打包与优化。

#### 4.1、打build包并运行项目

> 打包:可以在ui里运行build包,也可以运行命令:npm run build
>
> 操作后会导出一个dist文件(项目文件)
>
> 这就代表打包成功
>
> 运行:在dist文件同级目录创建一个app.js文件
>
> ```java
> //导入express
> const express = require('express')
>     const app = express()
>     //托管的静态资源
>     app.use(express.static('./dist'))
>     app.listen(80, () => {
>         console.log("服务器启动成功!:http://127.0.0.1")
>     })
> ```
>
> 在该目录初始化node
>
> npm init -y
>
> 安装express插件管理项目
>
> npm i express -S
>
> 最后启动项目
>
> node .\app.js

#### 4.2、优化项目

##### 4.2.1、打包后去掉console打印

> 插件名:transform-remove-console	
>
> 在babeLconfig.js里可以判断是否打包运行然后加入插件

##### 4.2.2、使用externals减少打包后文件大小

> 无论是element组件还是echart插件都可以使用导入.
>
> 具体百度

##### 4.2.3、设置路由懒加载

> 懒加载:可以减少加载控件的压力,需要哪个控件就记载哪个。
>
> 1:安装开发依赖@babel/plugin-syntax-dynamic-import
>
> 2:babel.config.js中声明插件
>
> 3:将路由改为这种加载格式: 
>
> const Foo = () => import(/* webpackchunkName: "group-foo" */ './Foo.vue')
> 	(Foot是名称,import里/*里是分组*/,'里是组件')
>
> 文档:参考链接:https://router.vuejs.org/zh/guide/advanced/lazy-loading.html

##### 4.2.4、compressoin 减少传输文件的大小

> app.js中导入插件:const compression = require('comression') app.use(compression)

##### 4.2.5、以https启动项目

+ 申请SSL证书

> ​		----进入https://fressl.cn官网,选择域名与品牌
> ​		----输入自己的邮箱并选择相关选择
> ​		----验证dns(在域名管理后台添加TXT记录)
> ​		----验证通过后,下载SSL证书(full_chain.pem公钥;prvate.key私钥)

+ 导入整数并启动https服务器

```js
const https = require('https')
const fs = require('fs')
const options={cret:'fs.readFileSync('./full_chain.pem')',key:'fs.readFileSync('./private.key')'}
  • 启动https服务器:443是默认端口
https.createServer(optoins,app).listen(443)
4.2.6、pm2托管项目

pm2:关闭运行终端依旧可以运行项目

​ ----安装插件 npm i pm2 -g
​ ----pm2 start 脚本(./app.js) --name 自定义启动项目名
​ ----查看所有运行项目:pm2 ls
​ ----重启项目:pm2 restart 自定义名称
​ ----停止项目:pm2 stop 自定义名称
​ ----删除项目:pm2 delete 自定义名称

5、特殊报错

5.1、启动

  • 报错关键字:Module build failed (from ./node_modules/babel-loader/lib/index.js):
  • 报错原因:插件更新了需要重写下载
  • 解决:删除node_modules文件,运行npm i重写下载即可52

5.2、访问接口,跨域问题

  • 代理解决

//const API_PROXY = 'https://bird.ioliu.cn/v1/?url='	//代理接口
 "https://bird.ioliu.cn/v1/?url=" +接口	//拼接即可

你可能感兴趣的:(vue学习笔记,前端新技术,vue.js,css,html5,node.js)