不会就问就查询!科技利民,学海无涯2!
1、vue.js的安装
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="https://cdn.jsdelivr.net/npm/vue">script>
2、vue指令
<p v-once>{{message}}</p>//值不再改变
<p v-pre>{{message}}</p>//原样输出
<p v-clock>{{message}}</p>//结合[v-clock]{display:none;}样式,实现斗篷效果;
<p v-html="message">我会被覆盖</p>
v-html='属性名':动态绑定输出内容,能识别解析html标签,覆盖标签文本
<p v-text="message">我会被覆盖</p>
v-text='属性名':动态绑定输出内容,正常输出内容,覆盖标签文本
<li v-for="(item,index) in array">{{item}}</li>
v-for='':实现for循环
<button v-on:click='add'>add事件</button>
v-on:[dom事件]='事件名':绑定(点击)事件,可以绑定其他事件
<img v-bind:src="imgUrl" alt="">
v-bind:[html属性]='属性名':动态绑定属性值
3、指令详解
4、ES6中对象字面量增强(简写)写法
let name = 'aa';
let obj = {name};//增强写法,就是直接使用外面定义好的变量名;
let obj = { name:name };//常规写法
methods:{
add:function(){},//常规写法:键值对
add(){},//增强写法
}
5、针对vue中元素复用:使用key属性,避免输入框切换时value输入值被带过来;
6、key属性
<ul>
<li v-for="(item,index) in array" :key="item.id">{{item}}--{{index}}</li>
</ul>
7、vue中哪些数组方法是响应式的?
响应式:
非响应:
app.array[0]='aaa';
Vue.set(修改的对象,索引值,修改后的值);
Vue.set(this.array,0,'aaa');
8、JS数组的高阶函数
<script>
const arr = [1,2,3,4,5];
let newArr = arr.filter(function(n){
return n<3;
});
console.log(newArr);//[1,2]
</script>
const arr = [1,2,3,4,5];
let newArr = arr.map(function(n){
return n+3;
});
console.log(newArr)//[4, 5, 6, 7, 8]
const arr = [1,2,3,4,'a'];
let tatol = arr.reduce(function(pre,item){
return pre + item;
},0);
console.log(tatol)//10a 字符串
9、指令修饰符:事件修饰符、双向绑定修饰符;
v-on:click.stop="事件名";
v-model.number=" data中属性名 "
10、vue组使用件的注册
常规注册:
第一步:创建组件构造对象:Vue.extend()
;(现在一般不直接写这个,采用语法糖形式,这一步可以省;)
第二步:注册组件(全局/局部)
第三步:使用组件:
<script>
const cpn = Vue.extend({
template:`
我是父组件
`
});//创建组件构造器
Vue.component('cpn1',cpn);//注册全局组件,一般用不着这个
const app = new Vue({
el:'#app',
data:{},
components: {
myCpn:cpn
}
})//注册局部组件
</script>
补充一、语法糖形式:将创建组件模板与注册合二为一步;
Vue.component('cpn1',{
template:`我是语法糖组件
`
});//语法糖:创建并注册全局组件
-----------------------------------------------------------------------
const app = new Vue({
el: '#app',
data: {},
components: {
cpn1: {
template: `我是语法糖组件aa
`
}
}
})//语法糖:创建并注册局部组件
补充二、语法糖基础上再做模板的分离:将模板中html代码分离出去,通过id属性引入;(两种方式)
方法一:
<script type="text/x-template" id="aaa">
<div>
<p>我是语法糖组件分离写法</p>
</div>
</script>
方法二:(推荐)
<template id="aaa">
<div>
<p>我是语法糖组件分离写法</p>
</div>
</template>
--------------------------------------
<script>
const app = new Vue({
el: '#app',
data: {},
components: {
cpn1: {
template: '#aaa'
}
}
})
</script>
补充三、创建父组件子组件:创建子组件构造器,必须在父组件之前定义;
const cpn2 = Vue.extend({
template:`
我是子组件
`
});//创建子组件构造器,必须在父组件之前定义
const cpn = Vue.extend({
template:`
我是组件
`,
components:{
Cpn:cpn2
}//在父组件中注册子组件,并使用
});//创建父组件构造器
11、组件传值:父子组件传值、兄弟之间传值
12、组件访问:父组件访问子组件、子组件访问父组件;
this.$children[]
:通过下标找子组件,子组件改变可能会找错;this.refs.aaa.[属性名]
+ref="aaa"
:给子组件设置ref,按名查找;this.$parent.[属性名]
:访问父组件data中数据this.$root.[]属性名
:直接访问Vue实例data中数据13、插槽slot元素的使用
<div id="app">
<cpn><button>子组件的插槽</button></cpn>
</div>
<template id="aaa">
<slot></slot>
</template>
name
属性; <div id="app">
<cpn>
<button slot='bb'>子组件第二个插槽</button>
<p slot="aa">子组件第一个插槽</p>
</cpn>
</div>
<template id="aaa">
<div>
<slot name="aa"></slot>
<slot name="bb"></slot>
</div>
</template>
14、作用域插槽slot-scope
用于父子组件中插槽的传值:父组件中获取子组件插槽传来的数据,将数据反作用于子组件的插槽,决定插槽中数据的使用方式;
<div id="app">
<cpn>
<template slot-scope='slot'>
<p>{{slot.data}}</p>//属性名与插槽中属性命名对应即可
</template>
</cpn>
</div>
<template id="aaa">
<div>
<slot :data="array"></slot>//属性名data可以随便命名;
</div>
</template>
15、模块化开发:核心-(在js文件中)导入导出
历史:
JS文件分散,不同文件全局变量冲突—>使用匿名函数,不同文件代码不可复用—>简单模块化,文件中导出对象,暴露出去成全局变量—>统一规范的模块化(CommenJS(nodejs、webpack采用的就是这个规范)、AMD、CMD、ES6的modules)
导出:
module.exports = {
a:1,
b:'aaa'
};//导出对象形式
导入:
var { a , b } = require('../aa.js');//因为commenJS导出的是对象,所以导入时可以使用解构写法
<script src="aaa.js" type="module"></script>
<script src="bbb.js" type="module"></script>
然后,在JS文件中按需导入导出:
aaa.js导出:
export { a,b }//导出方式一,定义后统一导出
export let a = 'haha'//方式二,定义时直接导出
export function aa(){}//导出函数
bbb.js导入:
import { a,b } from "./aaa.js"
可以改名的导入导出:
export default a//只能导出一个变量
import [自主命名] from "./aaa.js"//导入时可以改名
统一导入:当需要导入很多变量时
import * as aa from "./aaa,js"//将所有要导入的变量存在aa对象中使用;
16、脚手架cli (command-line interface命令行界面)
vue-cli2、vue-cli3
npm install -g @vue/cli
;通过拉取cli2模板·,实现在cli3环境下可以创建cli2项目;npm install @vue/cli-init -g
vue init webpack [项目名]
,不用中文和大写字母vue creat [项目名]
,不用中文和大写字母runtime-only main.js:
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
------
runtime-compiler main.js:
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: ' '
})
17、路由vue-router
背景:
前端路由:防止url改变发送请求
location.hash='aaa'
:本质是修改window.location的href属性;页面不会刷新;history.pushState({},'','home')
:进栈出栈,支持浏览器点击前进后退;history.back()
:后退一步(出栈一个),等价history.go(-1)
history.forward()
:前进一步,等价history.go(1)
history.go(-n)
:后退n步history.go(n)
:前进n步history.replaceState({},'','about')
:替换,不能后退、前进vue -router 路由
vue -router 路由的安装与使用
npm install vue-router --save
Vue。use(VueRouter)
;/router/index.js
/router/index.js、App.vue
$router(路径)、$route(活跃的路由)
属性;main.js
main.js:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
HelloWorld.vue
和
2.2、index.js:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '',
redirect: '/hello'
},
{
path: '/hello',
name: 'HelloWorld',
component: HelloWorld
}
],
mode:'history'
})
2.3、App.vue:
<template>
<div id="app">
<img src="./assets/logo.png">
<router-link to='/hello'>hello</router-link>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
vue -router 路由的注意点
标签点击后的自带类:class="router-link-exact-active router-link-active"
index.js:
export default new Router({
mode: 'history',
routes: [
{
path: '/hello',
name: 'HelloWorld',
component: HelloWorld
}
],
linkActiveClass:'active'
})
实现hello
App.vue:
<script>
export default {
name: 'App',
methods: {
helloClick(){
// this.$router.push('/hello');
this.$router.replace('/hello')
}
}
}
</script>
vue -router 动态路由:vue文件
v-bind
动态绑定to
属性实现路径拼接;第二步:在路由配置路径中使用:[参数名]
接收,第三步:在活跃组件中computed
计算属性使用this.$route.params.[参数名]
获取参数值,或者利用{{$route.params.[参数名]}}
;档案
vue -router 动态懒加载与嵌套:index.js
const Home = ()=>import('../components/Home.vue')
const HomeNews = ()=>import('../components/Homes/HomeNews.vue')
const HomeMessage = ()=>import('../components/Homes/HomeMessage.vue')
const routes = [
{
path:'',
redirect: '/home'
},
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:HomeNews
},
{
path:'message',
component:HomeMessage
}
]
}
]
vue -router 全局导航守卫:(守卫不需要定义,直接传参执行的)index.js中定义(需要借助vue-router实例执行)、也可以在main.js中定义
router.beforeEach((to, from, next) => { next();[自己的代码] })
:点击路由要进入这个组件时触发,next
决定是否让进;刚加载时不执行;router.afterEach( (to,from) => {}))
:进入某个路由组件后执行;刚加载页面时也执行,from是/根目录
;main.js:
new Vue({
el: '#app',
router,
render: h => h(App)
})
router.beforeEach((to, from, next) => {
document.title = to.matched[0].meta.title;
/* console.log(to);
console.log(from); */
next('/login');//(可以利用判断条件)强制跳到login组件,不写默认进入当前组件
})
vue -router 导航守卫补充:路由独享守卫、组件内守卫
beforeEnter
,刚加载页面时也执行;(类似全局导航方法的参数) {
path:'news',
name:'HomeNews',
component:HomeNews,
beforeEnter:(to,from,next)=>{
console.log(to);
next();
}
},
export default {
name:'Profile',
beforeRouteEnter(to, from, next) {
console.log(this);
console.log(from);
console.log(to);
next()
},
beforeRouteUpdate(to,from,next){
},
beforeRouteLeave(to, from, next) {
console.log(this);
console.log(from);
console.log(to);
}
}
vue -router 路由补充:状态保存 keep-alive
;
,让所有匹配到的视图组件都会被缓存;<keep-alive><router-view/></keep-alive>
activated
、不活跃deactivated
;export default {
name:'Home',
activated () {},
deactivated () {}
}
18、Vuex状态管理模式