笔记目录
小概
今日份学习内容:
组件补充:组件使用v-model双向绑定,props传参的数据验证,ref使用补充,scoped注意点,ES6中的模块化export语法
vue路由:路由的工作原理,单页面SPA了解,vue-router的使用
1. vue组件进阶
1.1 父子组件传参
复习一下父子组件之家的传参
- 父- ->子:父在标签内通过自定义行内属性(可以用v-bind绑定data中的数据)传递参数;子组件通过props[参数1,参数2…]接收,
- 子- ->父:事件传参,子组件通过this.$emit(‘事件名’,参数,参数2…),父组件通过 @事件名=‘处理函数’接收,参数通过处理函数形参接收。
组件使用v-model双向绑定
语法:
- 子组件中
props定义value属性
接收
数据改变的时候通过this.$emit(’input
’,新参数)- 父组件
传递数据的自定义属性写成:value
只要子组件满足上面的条件,父组件就可以直接简写为v-model
组件v-model双向绑定就是 规定父组件传过去的属性名用value,子组件props中也用value属性接收,子组件传递的事件名写写成input,这样父组件就可以使用v-model=“数据”简写。(不是很懂简写的意义和应用场景)
1.2 props进阶
默认情况下,props使用数组的方式来定义父传子的数据 . 如果想要设置这个数据的默认值,或者是限制这个数据的类型。那么就需要使用
props验证
<template>
<div class="box">
<h3>我是子组件</h3>
<p>propA:{{ propA }}</p>
<p>propB:{{ propB }}</p>
<p>propC:{{ propC }}</p>
<p>propD:{{ propD }}</p>
<p>propE:{{ propE }}</p>
<p>propF:{{ propF }}</p>
</div>
</template>
<script>
export default {
//如果没有类型验证,则props是一个数组
// props:[],
//如果需要类型验证,则props应该写错对象格式
props: {
//1.基本数据类型检查: undefined和null可以通过任何类型检查
//1.1 限制propA的数据类型为number类型
propA: Number,
//1.2 可以是string类型 或 number类型
propB: [String, Number],
//1.3 设置必填
propC: {
type: String,
required: true //限制这个值是必须要传的
},
//1.4 设置默认值
propD: {
type: Number,
default: 100 //如果不传,默认值就是100(不要跟required一起用)
},
//2.引用类型检查
//2.1 设置引用类型默认值
propE: {
type: Object, //非常严格,必须是对象。 数组和函数都不行
//引用类型的默认值,必须要写成工厂函数
default: function () {
return { name: '黑马' }
}
},
//2.2 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
},
data () {
return {}
}
}
</script>
props如果用数组的方式接参数,表示默认接收;如果需要对接收的参数验证
,就需要用一个对象接收,参数:{type:数据类型,required:t/f(是否必选),default:默认值,validator:自定义验证函数}
注意:建议父组件使用v-bind指令来传递数据,否则不管你写什么都是字符串类型
1.3 ref使用补充
ref
设置给不同的标签,获取到的东西是不同的。
- 如果设置给
dom元素(html标签)
,则获取的是dom元素对象
- 如果设置给
组件(组件也是一个标签)
,则获取的是组件vue实例对象
获取dom元素的时机mounted()钩子,.focus()获得光标,
上述操作就是在父元素中先获取子元素vue实例对象,在用.$ refs.input获取子元素中的input输入框,用. focus()设置加载页面input获得光标,
为什么直接不在子页面this.$refs.input.focus()?
如果直接在子组件中写,父元素中复用三次这个子组件,每次复用都会获得一次光标,光标永远会停留在最后一个组件的input内,无法实现让第几个input获得光标。
1.4 scoped使用注意点
scoped 用于给子组件的css样式添加作用域,防止父元素样式覆盖子元素样式
注意点:scoped尽量不要和标签选择器结合使用,建议class和id选择器(css性能问题)
1.5 ES6模块化export语法
vue将每一个组件看作是一个独立的模块(类似于nodejs中的)模块化,而组件导入
import
和导出exports
其实使用的是ES6新增的模块化语法.
- export 导出语法1
//1. 导出模块(写法一) : 变量声明 与 导出 分开写
//1.1 先声明变量
let name = '张三'
let age = 18
let sayHi = function(){
console.log(666);
}
//1.2 然后导出(一定要是对象类型)
export {name,age,sayHi}
- 导出语法2
//2. 导出模块(写法二) : 变量声明 与 导出 一起写
export let name = '张三'
export let age = 18
export let sayHi = function(){
console.log(666);
}
- import 导入语法1
//1.导入模块
//变量名必须和导出的变量名一致
import {name,age,sayHi} from "./goods.js"
console.log(name,age,sayHi);
导入语法2
//1.导入模块
//自定义导入的变量名
import {name as a,age as b,sayHi as c} from "./goods.js"
console.log(a,b,c);
- 默认导出: export default
let name = '张三'
// let age = '张三'
export default name
// export default age//报错, 如果使用export default只能导出1次
- 默认导入
//如果使用的是export default 导出,则导入的时候变量名可以不一致
import a from "./goods.js"
console.log(a);
注意点:export 显示声明后导出,导出一个对象,声明和导出一起写 export let name =‘xxx’。导出的变量名必须要和你import {变量名… }引入时写的变量名一致。如果你想修改变量名,可以用as import{name as a, …}
export default 默认导出 ,引入的时候变量名可以不一致。export default 只能导出一次,语法上可以和export 导出一起使用,但是不建议混合使用。
2.vue路
2.1 路由介绍及工作原理
前端路由和后端路由不是同一个东西,不要搞混淆.
- 后端路由:url地址和后端逻辑的对应关系(node 判断url实现接口需求…)
- 前端路由:url地址和组件的对应关系
1.前端中的路由 : 不同的路径对应加载不同的页面,且页面不会跳转
- 路由的功能类似于tab切换,但是更加的高级,性能更好
2.路由的工作原理 :
监听网页hash值变化
(#…)
- 修改网页的hash值
hash值原本的作用是来做锚点定位的,它有一个特点就是页面不会跳转- 给window注册onhashchange事件,监听hash值变化
当页面hash变化时,就会执行这个事件处理函数,然后就可以根据不同hash值加载不同页面
<!-- 1.点击按钮:修改地址栏的hash值 -->
<button onclick="window.location.hash = '#/a'">按钮1</button>
<button onclick="window.location.hash = '#/b'">按钮2</button>
<button onclick="window.location.hash = '#/c'">按钮3</button>
<div id="box">
我是组件
</div>
<script>
//2.给页面注册hash值变化事件
window.onhashchange = function(){
if(window.location.hash == '#/a'){
box.innerHTML = '<p>我是组件A</p>';
}else if(window.location.hash == '#/b'){
box.innerHTML = '<p>我是组件B</p>';
}else if(window.location.hash == '#/c'){
box.innerHTML = '<p>我是组件C</p>';
}
};
</script>
2.2 单页面应用SPA介绍
什么单页面应用?
SPA == single(单一的) page(页) application(应用)
- 单页面应用: 所有功能在一个页面上实现
- 前端路由: 实现业务场景切换
说人话:单页应用刷新方式局部刷新,切页面用户体验好,多页面整页刷新 页面切换加载慢。
单页面初次加载慢(路由懒加载优化),静态资源一次加载完毕。多页应用搜索引擎支持良好,单页应用不利于seo优化,所以商城(淘宝 京东)多页应用,网易云音乐就是单页应用。
2.3 vue路由使用流程
vue本身不提供路由功能,用vue团队提供的vue-router插件完成
vue路由的六个步骤
router路由配置页面
//导入vue框架
import Vue from 'vue'
//0.导入路由vueRouter
import VueRouter from 'vue-router'//导包
Vue.use(VueRouter)//用包
//1.导入组件
import find from '../views/find.vue'
import mine from '../views/mine.vue'
import friend from '../views/friend.vue'
//2.定义路由规则(什么路径对应什么组件)
const routes = [
{
path:'/',
name:'find',
component:find
},
{
path:'/mine',
name:'mine',
component:mine
},
{
path:'/friend',
name:'friend',
component:friend
}
]
//3.创建路由
let router = new VueRouter({
routes (缩写) 相当于 routes: routes
})
//导出路由
export default router
main.js文件
//导入vue框架
import Vue from 'vue'
//导入主组件
import App from './App.vue'
Vue.config.productionTip = false
//导入路由
import router from './router/index.js'
//4.创建vue实例对象, 并且挂载路由
new Vue({
router,//解构赋值 router:router
render: h => h(App)
}).$mount('#app')
应用页面
<template>
<div>
<div id="app">
<div class="header">
<img class="logo" src="./assets/images/logo.png" alt="" />
<!-- 5.路由导航:rount-link最终会被渲染成a标签-->
<!-- 5.设置路由导航 -->
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. : 渲染成a标签的href -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/">发现音乐</router-link>
<router-link to="/mine">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
<img class="right" src="./assets/images/right.png" alt="" />
</div>
</div>
<!-- 6.设置路由出口: 路由对应的组件应该加载到什么位置 -->
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<div class="container">
<router-view></router-view>
</div>
</div>
</template>
v-routre使用六步骤:
项目router文件夹的index.js路由模块配置路由
-1.导出vue框架import Vue from 'vue'
0.import VueRouter from 'vue-router'
导包,Vue.use(VueRouter)
使用路由
1.导入组件 import 组件名 from '组件地址'
2.定义路由规则(什么路径对应什么组件){path:路径,name:路由名称,component:组件名}
3.创建路由
4.创建vue实例对象, 并且挂载路由(就是在入口文件把创建好的路由挂载到vue实例对象上)
5.路由导航:rount-link最终会被渲染成a标签(点击路由导航跳转到我们要的hash路径)
6.设置路由出口: 路由对应的组件应该加载到什么位置(对应hash路径渲染组件的渲染地方)
总结
包含一些自己的理解,欢迎大佬纠正。想再总结回顾一下知识点,太晚了睡觉觉。晚安妈了个巴子。