Vue脚手架 Vue-cli

初始化脚手架

说明

  1. Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)。

  2. 最新的版本是 5.x。

  3. 文档: https://cli.vuejs.org/zh/

具体步骤

第一步(仅第一次执行):全局安装@vue/cli。
npm install -g @vue/cli

第二步:切换到你要创建项目的目录,然后使用命令创建项目
vue create xxxx

第三步:启动项目
npm run serve

备注:

  1. 如出现下载缓慢请配置 npm 淘宝镜像:npm config set registry https://registry.npm.taobao.org

  2. Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,
    请执行:vue inspect > output.j

脚手架文件结构

├── node_modules 
├── public
   ├── favicon.ico: 页签图标
   └── index.html: 主页面
├── src
   ├── assets: 存放静态资源
      └── logo.png
   │── component: 存放组件
      └── HelloWorld.vue
   │── App.vue: 汇总所有组件
   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

关于不同版本的Vue

  1. vue.js与vue.runtime.xxx.js的区别:
    1. vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
    2. vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
  2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。
    render: h => h(App)

vue.config.js配置文件

  1. 使用vue inspect > output.js 可以查看到Vue脚手架的默认配置。
  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

ref 属性

  1. 用来给元素或子组件注册引用信息,打标识(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    1. 打标识:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
    2. 获取:this.$refs.xxx

props 配置项

  1. 功能:让组件接收外部传过来的数据

  2. 传递数据:<Demo name="xxx"/>

  3. 接收数据:

    1. 第一种方式(只接收):props:['name']
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
props:{
	name:{
	type:String, //类型
	required:true, //必要性
	default: ()=> '老王' //默认值
	}
}

注意:在传递数据时,默认都是字符,若要传递数值:<Demo :age="21"/>

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

mixin(混入)

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:

    第一步 定义混合:

    export const hunhe = {
        data(){....},
        methods:{....}
        ....
    }
    

    第二步 导入混合

    import {hunhe} from '../mixin'
    ​ 导入的名称要和 mixin.js文件里导出定义的名称一样

    第三步 使用混入:

    ​ 全局混入:Vue.mixin(hun)
    ​ 局部混入:mixins:['hun']

插件

  1. 功能:用于增强Vue

  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

  3. 定义插件:

   export default {
       install(Vue, options) {
           // 1. 添加全局过滤器
           Vue.filter(....)
   
           // 2. 添加全局指令
           Vue.directive(....)
   
           // 3. 配置全局混入(合)
           Vue.mixin(....)
   
           // 4. 添加实例方法
           Vue.prototype.$myMethod = function () {...}
           Vue.prototype.$myProperty = xxxx
   	}
   }
  1. 使用插件:
    export导出 import导入后,Vue.use(xxx)

scoped样式

  1. 作用:让样式在局部生效,防止冲突。
  2. 写法:<style scoped>

总结TodoList案例

  1. 组件化编码流程:

    ​ (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

    ​ (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

    ​ 1).一个组件在用:放在组件自身即可。

    ​ 2). 一些组件在用:放在他们共同的父组件上(状态提升)。

    ​ (3).实现交互:从绑定事件开始。

  2. props适用于:

    ​ (1).父组件 ==> 子组件 通信

    ​ (2).子组件 ==> 父组件 通信(要求父先给子一个函数)

  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

  4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

webStorage

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)

  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。

  3. 相关API:

    1. xxxxxStorage.setItem('key', 'value');
      该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

    2. xxxxxStorage.getItem('person');

      ​ 该方法接受一个键名作为参数,返回键名对应的值。

    3. xxxxxStorage.removeItem('key');

      ​ 该方法接受一个键名作为参数,并把该键名从存储中删除。

    4. xxxxxStorage.clear()

      ​ 该方法会清空存储中的所有数据。

  4. 备注:

    1. SessionStorage(会话)存储的内容会随着浏览器窗口关闭而消失。
    2. LocalStorage(永久)存储的内容,需要手动清除才会消失。
    3. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
    4. JSON.parse(null)的结果依然是null。

组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:
      <Demo @atguigu="test"/>
      <Demo v-on:atguigu="test"/>
    2. 第二种方式,在父组件中:
<Demo ref="demo"/>
......
methods: { sayHello(){console.log("hello~")} },
mounted(){
   this.$refs.xxx.$on('say-hello',this.sayHello)
}
  1. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  2. 触发自定义事件(在子组件):this.$emit('say-hello',数据)

  3. 解绑自定义事件this.$off('say-hello')

  4. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  5. 注意:通过this.$refs.xxx.$on('say-hello',回调)绑定自定义事件时,回调要么配置在methods中要么用箭头函数,否则this指向会出问题!

全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信
  2. 安装全局事件总线:
// main.js
new Vue({
	......
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
	},
    ......
}) 
  1. 使用事件总线:

    接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

......
mounted() {
	this.$bus.$on('xxxx',()=>{})
},
beforeDestroy() {
	this.$bus.$off("xxxx")
}

​ 谁提供数据就调用:this.$bus.$emit('xxxx',数据)

  1. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

消息订阅与发布(pubsub-js)

  1. 一种组件间通信的方式,适用于任意组件间通信

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js
    2. 引入: import pubsub from 'pubsub-js'
    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){
  demo(msgName, data){......}
}
......
mounted() {
  this.pubId = pubsub.subscribe('xxx',this.demo) //订阅消息
}
  1. 提供数据:pubsub.publish('xxx',数据)

  2. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pubId)取消订阅。

nextTick

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

Vue封装的过度与动画

  1. 作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。

  2. image-20210823172448049image-20210823172448049

  3. 写法:

    1. 准备好样式:

      • 元素进入的样式:
        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    2. 使用<transition>包裹要过度的元素,并配置name属性

  4. 自定义动画搭配过渡

<template>
  <div>
    <button @click="isShow=!isShow">显示/隐藏</button>
    <transition name="hello" appear>
      <!-- appear属性,当出现就过渡一次 -->
      <h1 v-show="isShow">你好啊!!!</h1>
    </transition>
  </div>
</template>

<script>
  export default {
    name: "Test",
    data() {
      return {
        isShow: true
      }
    },
  }
</script>

<style scoped>
  h1{
    background-color: orange;
  }

  /* 自定义合适开始动画 */
  .hello-enter-active{
    animation: comego .5s;
  }
  .hello-leave-active{
    animation: comego .5s reverse;
  }
  /* 自定义动画 */
  @keyframes comego {
    from{
      transform: translateX(-100%);
    }
    to{
      transform: translateX(0px);
    }
  }
</style>
  1. 自定义过渡
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
	<!-- 有多个元素要用 transition-group --> 
	<transition-group name="hello" appear>
	  <h1 v-show="!isShow" key="1">你好啊!</h1>
	  <h1 v-show="isShow" key="2">Hello!</h1>
	</transition-group>
  </div>
</template>

<script>
  export default {
	name:'Test2',
	data() {
	  return {
		isShow:true
		}
	  },
  }
</script>

<style scoped>
  h1{
	background-color: orange;
  }
  /* 进入的起点、离开的终点 */
  .hello-enter,.hello-leave-to{
	transform: translateX(-100%);
  }
  .hello-enter-active,.hello-leave-active{
	transition: 0.5s linear;
  }
  /* 进入的终点、离开的起点 */
  .hello-enter-to,.hello-leave{
	transform: translateX(0);
  }

</style>

备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定key值。

  1. 使用外部css库(animation.css
<template>
  <div>
    <button @click="isShow=!isShow">显示/隐藏</button>
    <transition 
      appear
      name="animate__animated animate__bounce" 
      enter-active-class="animate__swing"
      leave-active-class="animate__backOutUp"
    >
      <h1 v-show="isShow">你好啊!!!</h1>
    </transition>
  </div>
</template>

<script>
  // 安装后,导入
  import "animate.css"

  export default {
    name: "Test3",
    data() {
      return {
        isShow: true
      }
    },
  }
</script>

<style scoped>
  h1{
    background-color: orange;
  }

</style>

vue脚手架配置代理

方法一

​ 在vue.config.js中添加如下配置:

devServer:{
  proxy:"http://localhost:5000"
}

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

方法二

编写vue.config.js配置具体代理规则:

module.exports = {
	devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        pathRewrite: {'^/api1': ''},  // 必须写,代理服务器访问服务器时要修改路径
        ws: true,  // 用于支持WebSocket
        changeOrigin: true // 用于控制请求头中的host值
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        pathRewrite: {'^/api2': ''},  // 必须写,代理服务器访问服务器时要修改路径
        ws: true,  // 用于支持WebSocket
        changeOrigin: true, // 用于控制请求头中的host值
      }
    }
  }
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。

插槽

  1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ==> 子组件

  2. 分类:默认插槽、具名插槽、作用域插槽

  3. 使用方式:

    1. 默认插槽:
父组件中:
<Category>
  <div>html结构1</div>
</Category>

子组件中:
<template>
  <div>
	<!-- 定义插槽 -->
	<slot>插槽默认内容...</slot>
  </div>
</template>
  1. 具名插槽:
父组件中:
<Category>
  <template slot="center">
	<div>html结构1</div>
  </template>

  <template v-slot:footer>
    <!-- 只有template标签才能用 v-slot:xxx -->
	<div>html结构2</div>
  </template>
</Category>

子组件中:
<template>
  <div>
	<!-- 定义插槽 -->
	<slot name="center">插槽默认内容...</slot>
	<slot name="footer">插槽默认内容...</slot>
  </div>
</template>
  1. 作用域插槽:
  • 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)
  • 具体编码:
父组件中:
<Category>
  <template scope="scopeData">
	<!-- 生成的是ul列表 -->
	<ul>
	  <li v-for="g in scopeData.games" :key="g">{{g}}</li>
	</ul>
  </template>
</Category>

<Category>
  <template slot-scope="scopeData">
	<!-- 生成的是h4标题 -->
	<h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
  </template>
</Category>

推荐写法:带值的v-slot,并且可以连用 v-slot:slotName='slotProps'
<Category>
  <template v-slot="slotProps">
	<h4 v-for="g in slotProps.games" :key="g">{{g}}</h4>
  </template>
</Category>


子组件中:
<template>
  <div>
	<slot :games="games"></slot>
  </div>
</template>
		
<script>
//数据在子组件自身
  data() {
	return {
		games:['红色警戒','穿越火线','劲舞团','超级玛丽']
	}
  },
</script>

本文作者:Liwker

本文链接:https://www.cnblogs.com/Liwker/p/15170687.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Liwker  阅读(304)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 灰色と青(翻自 米津玄師) kobasolo,春茶
  2. 2 スパークル nin
  3. 3 愛にできることはまだあるかい(翻自 RADWIMPS) 春茶
  4. 4 夏恋慕 kobasolo,春茶
  5. 5 花に亡霊 ヨルシカ
  6. 6 フラレガイガール(翻自 さユり) 春茶
  7. 7 ふたりごと(翻自 RADWIMPS) 茶泡饭,kobasolo,春茶
  8. 8 Lemon 米津玄師
  9. 9 君と100回目の恋(movie ver.) 葵海 starring miwa
  10. 10 風になる つじあやの
  11. 11 Letter Song ヲタみん
  12. 12 my sweetest one Aimer
  13. 13 Ref:rain Aimer
  14. 14 YELLOW(翻自 神山羊) 麦吉_Maggie
灰色と青(翻自 米津玄師) - kobasolo,春茶
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作曲 : 米津玄師

作词 : 米津玄師

袖丈が覚束ない夏の終わり

明け方の電車に揺られて思い出した

懐かしいあの風景

たくさんの遠回りを繰り返して

同じような街並みがただ通り過ぎた

窓に僕が写ってる

君は今もあの頃みたいにいるのだろうか

ひしゃげて曲がったあの自転車で走り回った

馬鹿ばかしい綱渡り 膝に滲んだ血

今はなんだかひどく虚しい

どれだけ背丈が変わろうとも

変わらない何かがありますように

くだらない面影に励まされ

今も歌う今も歌う今も歌う

···

忙しなく街を走るタクシーに

ぼんやりと背負われたままくしゃみをした

窓の外を眺める

心から震えたあの瞬間に

もう一度出会えたらいいと強く思う

忘れることはないんだ

君は今もあの頃みたいにいるのだろうか

靴を片方茂みに落として探し回った

何があろうと僕らはきっと上手くいくと

無邪気に笑えた 日々を憶えている

どれだけ無様に傷つこうとも

終わらない毎日に花束を

くだらない面影を追いかけて

今も歌う今も歌う今も歌う

朝日が昇る前の欠けた月を

君もどこかで見ているかな

何故か訳もないのに胸が痛くて

滲む顔 霞む色

今更悲しいと叫ぶには

あまりに全てが遅すぎたかな

もう一度初めから歩けるなら

すれ違うように君に会いたい

どれだけ背丈が変わろうとも

変わらない何かがありますように

くだらない面影に励まされ

今も歌う今も歌う今も歌う

朝日が昇る前の欠けた月を

君もどこかで見ているかな

何もないと笑える朝日がきて

始まりは青い色`