赞
踩
目录
官方给出的概念:Vue(读音/vju/,类似于view)是一套用于构建用户界面的前端框架。
1.构建用户界面
2.框架
vue框架的特性,主要体现在如下两方面:
1.数据驱动视图
2.双向数据绑定
在使用vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。示意图如下:
好处:当页面数据发生变化时,页面会自动重新渲染!
注意:数据驱动视图是单向的数据绑定。
在网页中,form表单负责采集数据,Ajax负责提交数据
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理。MVVM指的是 Model、View和ViewModel,它把每个HTML页面都拆分成了这三个部分,如图所示:
ViewModel作为MVVM的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接在了一起。
当数据源发生变化时,会被viewModel监听到,VM会根据最新的数据源自动更新页面的结构
当表单元素的值发生变化时,也会被VM监听到,VM会把变化过后最新的值自动同步到Model数据源中
注意:数据驱动视图和双向数据绑定的底层原理是MVVM(Model数据源、View视图、ViewModel就是vue的实例)
vue官方提供的vue-devtools调试工具,能够方便开发者对vue项目进行调试与开发
Chrome浏览器在线安装vue-devtools:
https://chrome.google.com/webstore/detail/vuejs-devtools/nbdogjmejiglipccpnnnanhbledajbpd
指令(Directives)是vue为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
vue中的指令按照不同的用途可以分为如下6大类:
注意:指令是vue开发中的最基础、最常用、最简单的知识点
内容渲染指令用来辅助开发者渲染DOM元素的文本内容。常用的内容渲染指令有如下3个:
v-text
用法示例:
1.v-text指令的缺点:会覆盖元素内部原有的内容!
{{}}语法
vue提供的{{}}语法,专门用来解决v-text会覆盖默认文本内容的问题。这种{{}}语法的专业名称是插值表达式(英文名:Mustache)
{{}}表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!
v-html
v-html指令的作用:可以把带有标签的字符串,渲染成真正的HTML内容!
注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中!
v-bind:
-
- <!--希望Vue能够控制下面的这个div,帮我们在把数据填充到div内部-->
- <div id="app">
- <input type="text" v-bind:placeholder="tips">
- <hr/>
- <!--vue规定v-bind:指令可以简写为:-->
- <img :src="photo" style="width: 150px;">
- </div>
- <!--1.导入Vue的库文件-->
- <script src="./lib/vue-2.6.12.js"></script>
- <!--2.创建Vue的实例对象-->
- <script>
- //创建Vue的实例对象
- const vm=new Vue({
- //el 属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,接受的值是一个选择器
- el:'#app',
- //data对象就是要渲染到页面上的数据
- data:{
- tips:'请输入用户名',
- photo:'https://img-home.csdnimg.cn/images/20201124032511.png'
- }
- });
- </script>
在vue中,可以使用v-bind:指令,为元素的属性动态绑定值;
简写是:
使用Javascript表达式
在vue提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持javascript表达式的运算,例如:
vue提供了v-on时间绑定指令,用来赋值程序员为DOM元素绑定事件监听。语法格式如下:
1.v-on:简写是@
2.语法格式为:
- <button @click="add"></button>
-
- methods:{
- add(){
- //如果在方法中要修改data中的数据,可以通过this访问到
- this.count+=1
- }
- }
3.$event的应用场景:如果默认的事件对象e被覆盖了,则可以手动传递一个$event。例如:
- <button @click="add(1,$event)"></button>
-
- methods:{
- add(n,e){
- //如果在方法中要修改data中的数据,可以通过this访问到
- this.count+=1
- }
- }
.prevent
<a @click.prevent="xxx">链接</a>
.stop
<button @click.stop="xxx"></button>
v-model指令
1.input
2.textarea
3.select
v-model指令的修饰符
1.v-show的原理是:动态为元素添加或移除 display:none样式,来实现元素的显示和隐藏
2.v-if的原理是:每次动态创建或移除元素,实现元素的显示和隐藏
3.在实际开发中,绝大多数情况,不用考虑性能问题,直接使用v-if就好了
v-else
v-else-if
- <!--希望Vue能够控制下面的这个div,帮我们在把数据填充到div内部-->
- <div id="app">
- <table class="table table-bordered table-hover table-striped">
- <thead>
- <th>索引</th>
- <th>Id</th>
- <th>姓名</th>
- </thead>
- <tbody>
- <!--官方建议:只要用到了v-for指令,那么一定要绑定一个:key属性-->
- <!--而且,尽量把id作为key的值-->
- <!--官方对key的值类型,室友要求的:字符串或数字类型-->
- <!--key的值千万不能重复的,否则会终端报错:Duplicate keys detected-->
- <tr v-for="(item,index) in list" :key="item.id" :title="item.name">
- <td>{{index}}</td>
- <td>{{item.id}}</td>
- <td>{{item.name}}</td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <!--1.导入Vue的库文件-->
- <script src="./lib/vue-2.6.12.js"></script>
- <!--2.创建Vue的实例对象-->
- <script>
- //创建Vue的实例对象
- const vm = new Vue({
- //el 属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,接受的值是一个选择器
- el: '#app',
- //data对象就是要渲染到页面上的数据
- data: {
- list: [
- { id: 1, name: '张三' },
- { id: 2, name: '李四' },
- { id: 3, name: '王五' }
- ]
- }
- });
- </script>
1.要定义到filters节点下,本质是一个函数
2.在过滤器函数中,一定要有return值
3.在过滤器的形参中,就可以获取到“管道符”前面待处理的那个值
4.如果全局过滤器和私有过滤器名字一致,此时安装“就近原则”,调用的是私有过滤器
1.方法格式的侦听器
2.对象格式的侦听器
特点:
好处:
axios是一个专注于网络请求的库
- <script src="./lib/axios.js"></script>
- <script>
- //http://www.liulongbin.top:3006/api/getbooks
-
- //1.调用axios方法得到的返回值是Promise对象
- const result = axios({
- //请求方式
- method: 'GET',
- //请求的地址
- url: 'http://www.liulongbin.top:3006/api/getbooks',
- //URL中的查询参数
- params: {
- id: 1
- },
- //请求体参数
- data: {}
- }).then(function (result) {
- console.log(result);
- })
-
- </script>
- <!DOCTYPE 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">
- <title>Document</title>
- </head>
-
- <body>
-
-
- <button id="btnPost">发起POST请求</button>
- <button id="btnGet">发起GET请求</button>
- <script src="./lib/axios.js"></script>
- <script>
- //http://www.liulongbin.top:3006/api/getbooks
-
- document.querySelector('#btnPost').addEventListener('click', async function () {
- //1.调用axios方法得到的返回值是Promise对象
- //如果调用某个方法的返回值是Promise实例,则前面可以添加await
- //await 只能用在背async"修饰"的方法中
- const { data: res } = await axios({
- //请求方式
- method: 'POST',
- //请求的地址
- url: 'http://www.liulongbin.top:3006/api/post',
- //请求体参数
- data: {
- name: 'zs',
- age: 20
- }
- })
-
- console.log(res);
- })
-
- document.querySelector("#btnGet").addEventListener('click', async function () {
- //结构赋值的时候,使用:进行重命名
- //1.调用axios之后,使用async/await进行简化
- //2.使用解构赋值,从axios封装的大对象中,把data属性解构出来
- //3.把解构出来的data属性,使用冒号 进行命名,一般都重命名为{data : res}
- //1.调用axios方法得到的返回值是Promise对象
- const { data: res } = await axios({
- //请求方式
- method: 'GET',
- //请求的地址
- url: 'http://www.liulongbin.top:3006/api/getbooks',
- //URL中的查询参数
- params: {
- // id: 825
- }
- })
-
- console.log(res);
-
- })
- </script>
- </body>
-
- </html>
1.在终端下运行如下的命令,创建指定名称的项目:
vue create 项目名称
2.vue项目中src目录的构成:
assets 文件夹:存放项目钟用到的静态资源文件,例如:css样式表 图片资源
components 文件夹:程序员封装的 可复用的组件,都要放到components目录下
main.js 是项目的入口文件,整个项目的运行,要先执行main.js
App.vue 是项目的根组件
- <template>
- <div class=".test-box">
- <h3>这是用户自定义的 Test.vue --- {{username}}</h3>
- </div>
- </template>
-
- <script>
- //默认导出,这是固定写法
- export default {
- //默认导出 这是固定写法
- //data 数据源
- //注意 .vue组件中的data不能像之前一样,不能指向对象
- //注意:组件中的data必须是一个函数
- data(){
- //这个return出去的{ }中,可以定义数据
- return {
- username:'admin'
- }
- }
- }
- </script>
-
- <style>
- .test-box{
- background-color: pink;
- }
- </style>
<style lang="less" scoped>
- // 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/
- /deep/ h5 {
- color: pink;
- }
- <template>
- <div class="app-container">
- <h1 ref="myh1">App 根组件</h1>
- <button @click="showThis">更新h1</button>
- <hr />
- </div>
- </template>
-
- <script>
-
-
- export default {
- methods: {
- showThis() {
- //当前App组件的实例对象
- this.$refs.myh1.style.color = 'red'
- console.log(this);
- }
- }
- }
- </script>
app.vue如下:
- <template>
- <div class="app-container">
- <button @click="onReset">重复Left组件的count值为0</button>
- <hr />
-
- <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
- <button v-else @click="showInput">展示输入框</button>
-
- <hr/>
- <div class="box">
- <!-- 渲染 Left 组件和 Right 组件 -->
- <!-- 3. 以标签形式,使用注册好的组件 -->
- <Left ref="comLeft"></Left>
- </div>
- </div>
- </template>
-
- <script>
-
- //1.导入需要使用的.vue组件
- import Left from '@/components/Left.vue'
-
- export default {
- //2.注册组件
- components: {
- Left
- }, methods: {
- onReset() {
- this.$refs.comLeft.resetCount()
- }
- }
- }
- </script>
Left.vue如下:
- <template>
- <div class="left-container">
- <h3>Left 组件 --- {{count}}</h3>
- <button @click="count+=1">+1</button>
- <button @click="resetCount">重置</button>
- </div>
- </template>
-
- <script>
-
- export default {
- data() {
- return {
- count:0
- }
- }, methods: {
- resetCount() {
- this.count=0
- }
- }
- }
- </script>
-
- <style lang="less" scoped>
- .left-container {
- padding: 0 20px 20px;
- background-color: orange;
- min-height: 250px;
- flex: 1;
- }
-
- h3 {
- color: red;
- }
-
- // h5[data-v-3c83f0b7]
- // [data-v-3c83f0b7] h5
-
- // 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/
- /deep/ h5 {
- color: pink;
- }
- </style>
- <template>
- <div class="app-container">
-
-
- <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
- <button v-else @click="showInput">展示输入框</button>
-
- <hr/>
-
- </div>
- </template>
-
- <script>
-
- //1.导入需要使用的.vue组件
- import Left from '@/components/Left.vue'
-
- export default {
- //2.注册组件
- components: {
- Left
- }, methods: {
- //点击按钮,展示输入框
- showInput() {
- //1.切换布尔值,把文本框展示出来
- this.inputVisible = true
- //2.让展示出来的文本框,自动获取焦点
- this.$nextTick(() => {
- this.$refs.iptRef.focus()
- })
-
- },
- //输入框失去焦点,显示按钮
- showButton() {
- this.inputVisible=false
- }
- },
- data() {
- return {
- //控制输入框和按钮的按需切换
- inputVisible: false
- }
- }
- }
- </script>
- <template>
- <div class="app-container">
- <h1>App 根组件</h1>
-
- <hr/>
-
- <div class="box">
- <Left>
- <!--默认情况下,在使用组件的时候,提供的内容都会被填充到名称为default的插槽之中-->
- <!--1.如果要把内容填充到指定名称的插槽中,需要使用v-slot:这个指令-->
- <!--2.v-slot:后面要跟上插槽的名称-->
- <!--3.v-slot:指令不能直接使用在元素身上,必须用在template标签上-->
- <!--4.template这个标签,它是一个虚拟的标签,只起到包裹性质的作用,但是,不会被渲染为任何实质性的html元素-->
- <!--5.v-slot:指令的简写形式是#-->
- <template #defalut><p>这是在Left组件的内容区域,声明的p标签</p></template>
- </Left>
-
- </div>
- </div>
- </template>
-
- <script>
-
- import Left from '@/components/Left.vue'
- import Right from '@/components/Right.vue'
-
- export default {
- data() {
- return {
- //comName 表示要展示的组件的名字
- comName:'Left'
- }
- },
- components: {
- //如果在"声明组件"的时候,没有为组件指定name名称,则组件的名称默认就是"注册时候的名称"
- Left,
- Right
- }
- }
- </script>
-
- <style lang="less">
- .app-container {
- padding: 1px 20px 20px;
- background-color: #efefef;
- }
- .box {
- display: flex;
- }
- </style>
- <template>
- <div class="left-container">
- <h3>Left 组件</h3>
-
- <hr />
- <!--声明一个插槽区域-->
- <!--vue官方规定:每一个slot插槽,都要有一个name名称-->
- <!--如果省略了slot的name属性,择优一个默认名称叫做default-->
- <slot name="default"></slot>
- </div>
- </template>
-
- <script>
- export default {
-
- name:'MyLeft'
- }
- </script>
-
- <style lang="less" scoped>
- .left-container {
- padding: 0 20px 20px;
- background-color: orange;
- min-height: 250px;
- flex: 1;
- }
-
- h3 {
- color: red;
- }
-
- // h5[data-v-3c83f0b7]
- // [data-v-3c83f0b7] h5
-
- // 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/
- /deep/ h5 {
- color: pink;
- }
- </style>
- <template>
- <div class="article-container">
- <!--渲染文章的标题-->
- <div class="header-box">
- <slot name="title"></slot>
- </div>
-
- <!--文章的内容-->
- <div class="content-box">
- <slot name="content"></slot>
- </div>
-
- <!--文章的作者-->
- <div class="footer-box">
- <slot name="author"></slot>
- </div>
-
- </div>
- </template>
- <template>
- <div class="app-container">
- <h1>App 根组件</h1>
-
- <hr/>
-
- <Article>
- <template #title>
- <h3>一首诗</h3>
- </template>
-
- <template #content="scope">
- <p>啊,大海,全是水.</p>
- <p>啊,蜈蚣,全是腿</p>
- <p>啊,辣椒,净辣嘴</p>
- <p>{{ scope }}</p>
- </template>
-
- <template #author>
- <div>作者:彬果锅</div>
- </template>
-
- </Article>
- </template>
-
- <template>
- <div class="article-container">
-
- <!--文章的内容-->
- <div class="content-box">
- <!--在封装组件时,为预留的<slot>提供属性对应的值,这种用法,叫做"作用域插槽"-->
- <slot name="content" msg="hello.vue.js" :user="userInfo"></slot>
- </div>
-
- </div>
- </template>
-
- <script>
- export default {
- //首字母要大写
- name: 'Article',
- data() {
- return {
- userInfo: {
- name: 'zs',
- age:20
- }
-
- }
- }
- }
- </script>
- <template>
- <div class="app-container">
- <h1 v-color="color">App 根组件</h1>
- <p v-color="'red'">测试</p>
- </template>
-
- <script>
- export default {
- data() {
- return {
- color:'blue'
- }
- },
- directives: {
- //定义名为color的指令,指向一个配置对象
- color: {
- //当指令第一次被绑定到元素上的时候,会立即触发bind函数
- //形参中的el表示当前指令锁绑定到的那个DOM对象
- bind(el,binding) {
- console.log("触发了v-color的bind函数");
- el.style.color = binding.value
-
- console.log(binding);
-
- }
- }
- }
- }
- </script>
main.js中配置
- import Vue from 'vue'
- import App from './App.vue'
- import axios from 'axios'
-
- Vue.config.productionTip = false
-
- // 全局配置axios的请求根路径
- axios.defaults.baseURL = '请求根路径'
- // 把axios 挂载到 Vue.prototype上,供每个 .vue组件的实例直接使用
- Vue.prototype.$http = axios
-
- // 今后,在每个 .vue组件中药发起请求,直接调用 this.$http.xxx
-
- new Vue({
- render: (h) => h(App)
- }).$mount('#app')
- <template>
- <div class="app-container">
- <h1>App 根组件</h1>
-
- <a href="#/home">首页</a>
- <a href="#/movie">电影</a>
- <a href="#/about">关于</a>
- <hr />
-
- <component :is="comName"></component>
- </div>
- </template>
-
- <script>
- // 导入组件
- import Home from '@/components/Home.vue'
- import Movie from '@/components/Movie.vue'
- import About from '@/components/About.vue'
-
- export default {
- name: 'App',
- data() {
- return {
- // 在动态组件的位置,要展示的组件的名字,值必须是字符串
- comName: 'Home'
- }
- },
- created() {
- // 只要当前的App组件一被创建,就立即监听window对象的onhashchange事件
- window.onhashchange = () => {
- console.log('监听到了 hash 地址的变化', location.hash)
- switch (location.hash) {
- case '#/home':
- this.comName = 'Home'
- break
- case '#/movie':
- this.comName = 'Movie'
- break
- case '#/about':
- this.comName = 'About'
- break
- }
- }
- },
- // 注册组件
- components: {
- Home,
- Movie,
- About
- }
- }
- </script>
-
- <style lang="less" scoped>
- .app-container {
- background-color: #efefef;
- overflow: hidden;
- margin: 10px;
- padding: 15px;
- > a {
- margin-right: 10px;
- }
- }
- </style>
- // src/router/index.js 就是当前项目的路由模块
- import Vue from 'vue'
- import VueRouter from 'vue-router'
-
- //导入需要的组件
- import Home from '@/components/Home.vue'
- import Movie from '@/components/Movie.vue'
- import About from '@/components/About.vue'
-
- Vue.use(VueRouter)
-
- // 创建路由的实例对象
- const router = new VueRouter({
- //路由规则
- routes: [
- { path: '/home', component: Home },
- { path: '/movie', component: Movie },
- { path: '/about', component: About}
- ]
- })
-
- export default router
- import Vue from 'vue'
- import App from './App.vue'
- // 导入路由模块,目的:拿到路由的实例对象
- // 在进行模块化导入的时候,如果给定的是文件夹,则默认导入这个文件夹下,名字叫做 index.js 的文件
- import router from '@/router/index.js'
-
- // 导入 bootstrap 样式
- import 'bootstrap/dist/css/bootstrap.min.css'
- // 全局样式
- import '@/assets/global.css'
-
- Vue.config.productionTip = false
-
- new Vue({
- render: h => h(App),
- // 在Vue项目中,要想把路由用起来,必须把路由实例对象,通过下面的方式进行挂载
- // router: 路由的实例对象
- router: router
- }).$mount('#app')
- <template>
- <div class="app-container">
- <h1>App2 组件</h1>
-
- <!--当安装和配置了vue-router后,就可以使用router-link来替代普通的a链接了-->
- <!-- <a href="#/home">首页</a> -->
- <router-link to="/home">首页</router-link>
- <router-link to="/movie">电影</router-link>
- <router-link to="/about">关于</router-link>
-
- <hr />
-
- <!--只要在项目中安装和配置了 vue-router,就可以使用router-view这个组件了-->
- <!--它的作用很单纯:占位符-->
- <router-view></router-view>
- </div>
- </template>
-
- <script>
- export default {
- name: 'App'
- }
- </script>
-
- <style lang="less" scoped>
- .app-container {
- background-color: #efefef;
- overflow: hidden;
- margin: 10px;
- padding: 15px;
- > a {
- margin-right: 10px;
- }
- }
- </style>
- Vue.use(VueRouter)
-
- // 创建路由的实例对象
- const router = new VueRouter({
- //路由规则
- routes: [
- //当用户访问/的时候,通过redirect属性跳转到/home对应的路由规则
- { path: '/',redirect: '/home'},
- { path: '/home', component: Home },
- { path: '/movie', component: Movie },
- { path: '/about', component: About}
- ]
- })
- <template>
- <div class="about-container">
- <h3>About 组件</h3>
-
- <!--子集路由链接-->
- <router-link to="/about/tab1">tab1</router-link>
- <router-link to="/about/tab2">tab2</router-link>
- <hr />
-
- <!--子集路由占位符-->
- <router-view></router-view>
- </div>
- </template>
-
- <script>
- export default {
- name: 'About'
- }
- </script>
-
- <style lang="less" scoped>
- .about-container {
- min-height: 200px;
- background-color: skyblue;
- padding: 15px;
- > a {
- margin-right: 10px;
- }
- }
- </style>
- // src/router/index.js 就是当前项目的路由模块
- import Vue from 'vue'
- import VueRouter from 'vue-router'
-
- //导入需要的组件
- import Home from '@/components/Home.vue'
- import Movie from '@/components/Movie.vue'
- import About from '@/components/About.vue'
-
- import Tab1 from '@/components/tabs/Tab1.vue'
- import Tab2 from '@/components/tabs/Tab2.vue'
-
-
- Vue.use(VueRouter)
-
- // 创建路由的实例对象
- const router = new VueRouter({
- //路由规则
- routes: [
- //当用户访问/的时候,通过redirect属性跳转到/home对应的路由规则
- { path: '/',redirect: '/home'},
- { path: '/home', component: Home },
- { path: '/movie', component: Movie },
- {
- path: '/about', component: About, children: [
- //子路由规则
- { path: 'tab1', component: Tab1 },
- { path: 'tab2', component: Tab2 }
- ]
- }
- ]
- })
-
- export default router
使用redirect设置当前默认显示的子路由,不加默认不显示
- // 创建路由的实例对象
- const router = new VueRouter({
- //路由规则
- routes: [
- {
- path: '/about',
- component: About,
- //默认子路由
- redirect: '/about/tab1',
- children: [
- //子路由规则
- { path: 'tab1', component: Tab1 },
- { path: 'tab2', component: Tab2 }
- ]
- }
- ]
- })
this.$router.push('/movie/1')
this.$router.replace('/movie/1')
// go(-1) 表示后退一层
// 如果后退的层数超过上限,则原地不动
this.$router.go(-1)
<!--在行内使用编程式导航跳转的时候,this必须要省略,否则会报错-->
<button @click="$router.back()">back 后退</button>
<button @click="$router.forward()">forward 前进</button>
用于给不同的api调用不同的地址
在src新建utils文件夹并创建request.js
- import axios from 'axios'
-
- const request = axios.create({
- // 指定请求的根路径
- baseURL: 'https://www.escook.cn'
- })
-
- export default request
假设有多个地址,可以创建多个mini axios 调用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。