vue.js
vue.js
谁在影响着页面?model中的data
api学习步骤
- 引文件
- 写结构
- 初始化js
简介
是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。 (数据驱动编程)
MVVM
- m 数据模型
- v 视图模型
- vm 一个同步
声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<div id="app">
{{ message }}
</div>
|||||||||||||||||||||||||||||||
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
差值表达式--渲染文本(推荐使用)
位于标签的innerHTML的位置
- 表达式
- 三元表达式
指令(以v-
开头)
位于标签属性位置,同样可以使用表达式
v-text
--渲染文本
不能渲染带标签的文本
v-html
--(谨慎使用)
可以解析标签,比较危险,永不用在用户提交的内容上
v-bind
--(给属性赋值)
可以用来动态绑定属性 使用方式:
v-bind:属性名="data中的属性"
简写方式::属性名="data中的属性"
可以绑定任何属性,此绑定在往后的组件开发中经常使用 可以动态绑定样式::class="{'类名':布尔值}"
true:有类名,false:没有类名;也可以:class="{'类名':布尔值, '类名': 变量名}"
,可以通过更改变量的值,来动态操作类名
v-for
--(for循环--渲染数组和对象)
- 渲染数组
- v-for="item in arr", item是数组中的每一项的意思,可以随意,arr表示需要便利的数组
- v-for="(item,index)in arr" index表示数组项的索引
- 渲染对象
- v-for="value in obj", value是对象键的值,可以随意,obj表示需要便利的对象
- v-for="(value,key,index)in obj" index表示数组项的索引
- 迭代数字
v-for="item in 数字"
- 改变数组
Vue.set() Array.prototype.aplice()或者Array.aplice()
- :key
只要写了 v-for 就必须写上 :key --唯一标识,提高性能
v-model--(用来双向数据绑定)
只能在input/tettxtarea/select
v-on--(事件监听)
在methods属性中定义函数,要获取data中的属性,需要加上this.,this表示vue实例
v-on: 任意的事件类型="执行的函数"
- 简写形式:
@任意的事件类型="执行的函数"
- 通过执行函数添加参数
- 通过执行函数中添加$event参数传递事件对象--名字不能更改,不能加引号
- 事件修饰符,可以给事件添加特殊功能:
.prevent
(阻止默认跳转),.stop
(阻止冒泡) - 可以给和按键相关的事件添加按键修饰符,常有的
keyup.enter
,keyup.键盘码
v-if 和 v-show
控制元素的显示可隐藏,
v-if="布尔值"
,v-show="布尔值"
,true则显示,false则隐藏 区别:v-if通过控制dom来控制元素显示和隐藏;v-show通过控制display:none来控制元素显示和隐藏; 使用场景:
- 涉及到大量dom操作的时候,我们需要使用v-show; 多次显示和隐藏 使用
v-show
- 涉及到异步数据渲染的时候,需要使用v-if; 单次显示和隐藏 使用
v-if
v-if,v-else-if,v-else 条件判断
<p v-if="type ==='A'">A</p>
<p v-else-if="type ==='B'">B</p>
<p v-else-if="type ==='C'">C</p>
<p v-else>not:A/B/C</p>
---
var vm = new Vue({
el: '#app',
data: {
isvisibilty: true,
type: 'B'
}
})
v-cloak -- (解决元素闪烁的问题)
- 给闪烁的元素加上v-cloak指令
- 写样式:[v-cloak]{display:none},当vue实例结束编译之后(当vue文件加载完成后),v-clock会被删除
- 另外,可以使用v-text添加内容,此时,vue文件没有加载时,元素不会得到内容,就不存在闪烁问题
this指向
在vue中,this指向创建的实例对象
mounted--钩子函数
表示页面一加载就执行函数里的内容 注意:函数的名字不能随意取,而且,不能写在methods中
自动获取焦点
- ref="名字"--表示对dom的引用
- 通过this.$refs.名字获取dom操作元素
- focus()自动获取焦点
自定义指令
- 形式一
- 通过全局方法
Vue.directive()
创建,包含两个参数,1.表示自定义指令的名字(全部小写);2.是一个对象,表示自定义指令的配置项 - 配置项中是一些钩子函数
-
inserted
钩子函数,表示自定义指令插入到标签中的时候就执行 - 参数
(el,binding)
:1.el
:使用自定义指令的元素,2.binding
表示自定义指令的信息
-
- 使用:dom中加入
v-myfocus
Vue.directive('myfocus',{
inserted(el,binding){
el.focus();
}
})
- 形式二
Vue.filter()--创建过滤器
参数:过滤器名称,函数
{{item.timer | fmtTime('/')}}
Vue.filter('fmtTime'.function(time,seprator){
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.detDate();
return y+seprator+m+seprator+d;
})
computed--计算属性
根据data中已有的实行,计算得到一个新属性 创建计算属性,通过computed关键字,它是一个对象 这里的fullName就是一个计算属性,是一个函数,但可以当做属性来使用 好处:
- 有缓存的特性,多次使用,只会计算一次,提升性能
{{fullName}}
computed:{
fullName(){
return this.firstName+this.lastName;
}
}
watch--监听器
用来监听data中的数据的值,当数据发生改变,就执行相应的函数,通过watch创建监听器,它是一个对象,函数名是监听的对象,执行的函数有两个参数(newVal,oldVal) 开发时,能用computed就不用watch computed 有缓存的功能,需要计算的时候,使用computed watch会一直监听,需要执行异步操作时使用watch
watch:{
firstName(newVal,oldVal){
this.watchName = newVal + this.lastName;
},
lastName(newVal.oldVal){
this.watchNamw = this.firstName + newVal;
}
}
深度监听--监听对象
-
handeler:(newVal,oldVal){}
--监听处理函数,名字固定 -
deep:true
--深度监听
watch:{
user:{
handler(newVal,oldVal){
console.log(newVal.name)
},
deep:true
}
}
搜索功能实现
数组的过滤
filter--有循环遍历的功能
过滤条件:判断是否包含字符串
indexof
return this.list.filter(value=>value.name.indexOf(this.searchVal) !== -1)
axios--get
axios--post
过渡和动画
- 使用 transition 标签包裹
animate.css
动画库--第三方css动画库
- 引入css文件
- 使用
transition
标签包裹 - 添加
属性名="animated 添加类名"
-
enter-active-class="animated fadeInRight"
定义进入的动画状态 -
leave-active-class="animated fadeOutRight"
定义离开的动画状态
-
JavaScript 钩子
删除动画
Vue组件
-
什么是组件
-
组件开发好处
- 封装功能性代码,提升开发效率
组件的创建
注意:
- 模板template中只能有一个根节点
- 组件的名字,如果使用驼峰命名的话,在使用的时候需要嘉盛"-",比如组件的名字叫indexA,在使用时就叫index-A
创建方式一
使用Vue.extend()和Vue.component()两个方法
- Vue.extend()函数 会返回一个组建的构造器,它里面包含一个参数template,他是一个对象,里面是一些配置项,指定组件显示的模板
- Vue.component()函数会利用Vue.extend()函数返回的构造器创建一个组件的实例,它有两个参数,一个是组件的名字,另外一个组件的构造器
组件使用步骤
- 定义组件(显示的内容)
var Index = Vue.extend({
//指定组件显示的模板
template: "<div>我是首页</div>"
});
- 注册组件
Vue.component('index',Index);
- 使用组件,就像使用HTML标签一样
<index></index>
创建方式二
Vue.component()这个方法本质上还是要调用Vue.extend()方法
Vue.component('indexB',{
template: "<div>我是首页</div>"
});
---
<index-b></index-b>
创建方式三
通过指定模板创建,定义的模板需要在Vue管辖范围之外
//模板一(推荐使用)
<template id="itcast">
<div>我是首页</div>
</template>
//推荐二(js标签)
<script type="x-template" id="iecast">
<div>我是首页</div>
</script>
---
Vue.component('indexC',{
template: "#itcast"
});
---
<index-c></index-c>
组件中使用指令和事件
父子组件的创建
//创建father组件
Vue.component('father',{
template:'<div>我是父组件<son></son></div>';
//通过components属性创建子组件
components:{
创建一个son组件
son:{
template:'我是子组件'
}
}
})
---使用---
<father></father>
父子组件和子组件间的传值
- 父子组件传值给子组件
父组件向子组件传值需要考虑两个问题: 父组件怎么传值:属性动态绑定(v-bind) 子组件怎么接收:props:能够获得当前组件身上属性对应的值
//创建father组件
Vue.component('father',{
//通过v-bind给指令,给子组件中的props赋值
template:'<div>我是父组件,我儿子叫{{sonName}},今年{{age}}<son :myName="sonName"></son></div>',
data(){
return{
sonName:'小明',
age:20
}
}
//通过components属性创建子组件
components:{
创建一个son组件
son:{
//1\. 声明props,它的作用是,用来接收父组件传过来的值,props可以跟一个数组,数组里的值是一个一个的字符串,可以当做属性使用
props:['myName'],
template:'我是子组件,我叫{{myName}}'
}
}
})
- 子组件给父组件传值
- 子组件传值给父组件,需要用到$emit()方法,这个方法可以传递两个参数,一个是事件名,另外一个是需要传递的值-----(触发一个事件tellFatherMyName,并且传递一个值)
- 父组件接收参数:注册一个事件getMySonName,接收参数data
//创建father组件
Vue.component('father',{
template:'<div>我是父组件,我儿子的名字是{{sonName}}
<son @tellFatherMyName="getMySonName"></son>
</div>';
data(){
return{
sonName:''
}
},
methods:{
getMySonName(data){
this.sonName=data
}
}
//通过components属性创建子组件
components:{
创建一个son组件
son:{
template:'我是子组件,我的名字{{myName}},<button @click="emitMyName">发送数据</button>',
data(){
return{
myName:'小明'
}
},
methods:{
emitMyName(){
this.$emit('tellFatherMyName',this.myName)
}
}
}
}
})
- 兄弟组件传值
创建动态组件
利用component标签创建动态组件,他的is属性指向谁,就显示哪个组件
<ul>
<li @click="currentCom='index'">首页</li>
<li @click="currentCom='productType'">蔬菜</li>
<li @click="currentCom='productType'">水果</li>
</ul>
<component :is="currentCom"></component>
//组件
Vue.component('index',{
template:"<div>首页</div>"
})
Vue.component('productType',{
template:"<div>这里显示商品编号</div>"
})
vue实例(组件)生命周期
在实例被创建之后立即被调用,在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event时间回调。然而,挂载阶段还没开始,dom还未开始,$el属性目前不可见。
created:function(){
console.log(this.$el);
console.log(this/$data);
console.log(this.info);
}
模板编译之后调用,
mounted:function(){
console.log(this.$el);
console.log(this/$data);
console.log(this.info);
}
Vue-router 路由
路由初体验
- 引入路由文件
vue-router.js
- 准备路由需要的组件
Vue.component('index', {
template: "<div>首页</div>"
})
Vue.component('productType', {
template: "<div>这里显示商品编号</div>"
})
- 创建路由对象,在这个对象里配置路由规则
var routers = new Router()
- 通过routes属性配置路由规则,它是一个数组,里面放的是对象,每个对象对应一条规则。并且每个对象都包含(name,path,component)--(路由规则的名称,路径,路径对应的组件)
routes:[
{name:'index',path:'/index',component:index},
{name:'productType',path:'/product_type',component:productType}
]
- 在vue实例中注册路由,这样整个应用程序中都会拥有路由
var vm = new Vue({
el: '#app',
router: routers,
data: {
}
})
- 通过router-view挖坑,路径匹配到的组件都会渲染到这个坑里
<router-view></router-view>
- vue路由中通过router-link(这是一个标签)去做跳转,他的to属性,这个值必须和path中的路径对应
- router-link,将来会被渲染成a标签,to属性会被渲染成a标签的href属性,但它的值前面会加一个#,变为锚点
<router-link to="/index">首页</touter-link>
<router-link to="/product_type">水果</router-link>
- 总结:步骤一共三步:1.问路,2.创建路由规则 3. 创建组件 4. 注册路由 5.挖坑
路由参数
- 第一种方法
- 路由加参数:
:参数名
--{name:'productType',path:'/product_type/:id',component:productType}
- 在html中获取路由参数,通过
$route.params.参数名
template: "<div>这里显示商品编号{{$route.params.id}}</div>"
- 在js中获取路由参数,通过
this.$route.params.参数名
template: "<div>这里显示商品编号{{$route.params.id}}</div>",
mounted(){
console.log(this.$route.params.id);
}
- 第二种方法(不影响路由path)
- 直接在跳转路径后使用真正传参的方式:
/product_type?参数名=值
<router-link to="/product_type?id=22">水果</router-link>
- HTML中获取路由参数,通过
$route.query.参数名
template:"<div>商品编号{{$route.query.id}}</div>"
- js中获取路由参数,通过
this.$route.query.参数名
监听路由参数的变化-watch
'$route'表示监听对象,to表示将要去的路由对象,from表示你从呢个路由对象来
watch:{
'$route'(to,from){
console.log(to);
console.log(from);
if(to.perams.id === 22){
console.log('胡萝卜。。。')
} else {
console.log('苹果')
}
}
}
嵌套路由和编程式导航
路由重定向
当不符合前边的规则,此规格生效,path:表示输入的所有路径,redirect:表示,强制跳转的路由地址
{name:'default',path:'*',redirect:'/index'}
{name:'default',path:'*',redirect:{name:'index'}
webpack
什么是webpack
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
webpack起步
- 安装
cnpm i webpack#3.11.0 -g
- 打包:
webpack app.js index.js
(改变代码,都要重新打包) - 配置文件:webpack.config.js
var path = require('path')
module.exports={
//配置入口文件
entry:'./src/app.js',
//配置输出文件
output:{
//表示输出文件的路径(绝对路径)
path:path.join(__dirname,'dist'),
//表示输出文件的名字
filename:'bundle.js'
}
}
此时,命令中直接输入
webpack
就可以,自动创建一个文件夹dist,这里边放的是打包后的文件
-
webpack-dev-server
(插件,解决以上问题)
cnpm init -y
cnpm i webpack-dev-server@2.9.7 webpack@3.11.0 -D
-
webpack.config.js
中配置publicPath: '/dist',
-
-
index.html
中修改<script src="/dist/bundle.js"></script>
-
- 运行:
webpack-dev-server
- 运行:
- 运行:
webpack-dev-server --inline --hot --open --port 8090
- 运行:
- 配置
script:"dev": "webpack-dev-server --inline --hot --open --port 8090"
- 配置
npm run dev
单文件组件
- 全局组件的弊端:
- 名字不能重复
- template没有语法高亮
- 不支持css
- 没有构建步骤
- 单文件组件
- 扩展名:
.vue
完整语法高亮; CommonJS 模块; 组件作用域的 CSS 步骤:
// 1\. 安装vue的包: cnpm i vue -S
// 2\. 由于 在 webpack 中,推荐使用 .vue 这个组件模板文件定义组件,所以,需要安装 能解析这种文件的 loader cnpm i vue-loader vue-template-complier -D
// 3\. 在 app.js 中,导入 vue 模块 import Vue from 'vue'
// 4\. 定义一个 .vue 结尾的组件,其中,组件有三部分组成: template script style
// 5\. 使用 import App from './components/App.vue' 导入这个组件
// 6\. 创建 vm 的实例 var vm = new Vue({ el: '#app', render:h => h(App) })
// 7\. 在页面中创建一个 id 为 app 的 div 元素,作为我们 vm 实例要控制的区域;
vue.cil脚手架工具
- 准备工作:
- 运行:
cnpm i vue-cli -g
- 新建一个文件夹(project)
- 在此文件夹中打开终端,
vue init webpack admin
,出现? Project name (admin)
表示成功,后一直按回车,。。出现? Use ESLint to lint your code? (Y/n)
按n
,继续按回车,出现
? Should we run `npm install` for you after the project has been cre
ated? (recommended) (Use arrow keys)
> Yes, use NPM
Yes, use Yarn
No, I will handle that myself
按上下键,选择no,完成。
- 打开admin文件夹,打开终端,
cnpm i
, 完成后输入npm run dev
出现I Your application is running here: http://localhost:8080
,表示成功 - 新建数据库,数据库名:itcast,编码字符集utf-8
- 导入sql文件
D:\js高级资料\Vue\Vue_day06\代码\shop2-server\db
- config文件夹中
default.json
文件中更改用户名密码 -
D:\js高级资料\Vue\Vue_day06\代码\shop2-server
路径下,打开终端,运行cnpm i
- 运行
node app
,成功
element-ul
框架
- 下载
cnpm i element-ui -S
- 完整引入----在 main.js 中写入以下内容:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
以上代码便完成了 Element 的引入。需要注意的是,样式文件需要单独引入。