渐进式框架 -Vue.js

分离与不分离的好与坏

前后端分离后 后端仅返回前端所需的数据,大部分业务逻辑都是通过前端进行校验

不再渲染HTML页面,不再控制前端的效果,页面由页面服务器请求返回

而具体的数据通过JS去应用服务器去数据库请求得到

优点:减少页面的请求,页面无需去后端请求,最多去静态文件服务器拿到

前后端分工清晰,大项目开发维护教简单

缺点: 小项目如果使用前后端分离 前后端沟通成本加大

Vue初识

1.Vue 一个渐进式JS框架 实现单页面开发

一个页面小到一个变量,一个变量代表一个页面,大到整个项目通过Vue来控制

2.页面的切换不再是请求url 而是组件的替换,替换一个组件就是替换一个页面

3.从数据角度考虑标签 而不是一个标签

 

 

 

Vue的使用

挂载点一般定义成一个页面,一个el只对第一个 标签有效,所以挂载点一般为id

一个页面出现多个挂载点,但是一个Vue实例操作一个挂载点

所以一个el 指代一个挂载点

像{{}} 和 属性里 以 v-* 打头的都会被Vue拦截

Vue替换插值处

 

<div id="app">
    <!-- {{ vue变量 }} 插值表达式 -->
    <h1>{{ h1_msg }}</h1>
    <h2>{{ h2_msg }}</h2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',  // 挂载点
        data: {  // 为挂载点的页面结构提高数据
            h1_msg: 'h1的内容',
            h2_msg: 'h2的内容',
        }
    })
</script>

 

Vue 会识别{{ name }}   里的name会被当作插值处, 去Date找到属性,替换成真正的内容

Vue使用事件和once指令

知识点:

this 可以拿到当前的 Vue对象 要拿到实例属性可以通过 this.$date.插值名

v-on:事件=“函数” 只要触发事件就会执行Vue实例的methods里的函数方法

v-once:被插值后 就无法改变

{{}} 相当于 v-text 文本

v-html 就是html 代码块

插值处可以通过索引 data[1] 拿到data 列表里具体的值 

@事件 可以代替 v-on:事件

<div id="app">
    <div  v-on:click="pclick"  >{{ msg }}}</div>
</div>

</body>
<script src="Vue.js"></script>
<script>
    let app =new Vue({
        el:"#app",
        data:{
            msg:"adas",
        },
        methods:{
            pclick:function () {
                alert(123);
                this.msg="hahahaha"
            }
        }
    })
</script>

这样就可以通过变量 驱动页面

方法传参

所有click触发效果可以绑定到一个函数里,但是我们怎么区分那个按钮点击的呢 通过传参?

形参和实参数量可以不统一

实参如果是只有函数名的话 会把Event传过去 函数名() ,如果想传事件 又想传参就得加 $event.

<div id="app">
    <button v-on:click="tanchukuang(1)" v-text="h1">{{ h1 }}</button>
    <button v-on:click="tanchukuang(2)" v-text="h2">{{ h2 }}</button>
</div>

</body>
<script src="Vue.js"></script>
<script>
    let app=new Vue({
        el:"#app",
        data:{
            h1:"弹出框1",
            h2:"弹出框2"
        },
        methods:{
            tanchukuang:function (xxx) {
                alert(xxx)
            }
        }
    })
</script>

Vue操作属性

知识点

v-bind:属性 :属性一样 如果属性值还是键值对形式 那么插值形式可以为字典

多个类 可以通过元祖的形式 class="[a1,a2]" 来表示两个 两个类  style:”{fontsize:a1,color:a2}“

<div id="app">
    <button v-on:click="tanchukuang(1)"  :style="xxxx" >{{ h1 }}</button>
    <button v-on:click="tanchukuang(1)"  style="color: yellow" >{{ h1 }}</button>

</div>

</body>
<script src="Vue.js"></script>
<script>
    let app=new Vue({
        el:"#app",
        data:{
            h1:"弹出框1",
            h2:"弹出框2",
            xxxx:"color:yellow"
        },
        methods:{
            tanchukuang:function (xxx) {
                alert(xxx)
            }
        }
    })

v-show和v-if的区别

知识点

v-show 指的是display:none 

v-if :flase是注释 存在缓存里 改为true 从注释解开,实质是从缓存里读取出来

变为false 之后

 表单指令

v-model 控制着表单的value值  input框的value也会改变model

点击会改变 v-model的值   是个双向绑定的过程

单选框radio 万一和它的value值 相同那么就会被选上

在checked中  如果是单个的 v-model 追随为   true-value | false-value  的值   如果复选的checkbox 那么就是追随values 

```html
<div id="app">
    <!-- v-model针对于表单元素 -->
    <form action="" method="get">
        <!-- 1、双向绑定:服务于文本输入框 -->
        <!-- v-model存储的值为输入框的value值 -->
        <div>
            <input type="text" name="usr" v-model="in_val">
            <input type="password" name="ps" v-model="in_val" >
            <textarea name="info" v-model="in_val"></textarea>
        </div>

        <!-- 2、单选框 -->
        <div>
            <!-- 单选框是以name进行分组,同组中只能发生单选 -->
            <!-- v-model存储的值为单选框的value值 -->
            男:<input type="radio" name="sex" value="男" v-model="ra_val">
            女:<input type="radio" name="sex" value="女" v-model="ra_val">
            {{ ra_val }}
        </div>

        <!-- 3、单一复选框 -->
        <!-- v-model存储的值为true|false -->
        <!-- 或者为自定义替换的值 -->
        <div>
            <input type="checkbox" v-model='sin_val' true-value="选中" false-value="未选中" />
            {{ sin_val }}
        </div>

        <!-- 4、多复选框 -->
        <!-- v-model存储的值为存储值多复选框value的数组 -->
        <div>
            <input type="checkbox" value="喜好男的" name="cless" v-model='more_val' />
            <input type="checkbox" value="喜好女的" name="cless" v-model='more_val' />
            <input type="checkbox" value="不挑" name="cless" v-model='more_val' />
            {{ more_val }}
        </div>
    </form>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            in_val: '',
            // 默认值可以决定单选框默认选项
            ra_val: '',
            // 默认值为true,单一复选框为选中,反之false为不选中
            sin_val: '',
            // 数组中存在的值对应的复选框默认为选中状态
            more_val: ['喜好女的','不挑']
        }
    })
</script>

条件指令

里面传递判断来决定该标签是否展示

<div v-if="true">111</div>
<div v-else-if="false">222</div>
<div v-else>222</div>

#必有一个执行 要么if 执行 要么else执行  如果两个都不执行才执行第三个

循环指令

可以循环

列表拿到 值和索引  

 <li v-for="(num, index) in nums">{{ num }} {{ index }}</li>  #循环第一个拿到的是数值 第二个才是索引
 <li v-for="num in nums">{{ num }}</li>

 

字典  拿到

<li v-for="(v, k, i) in people">{{ v }} {{ k }} {{ i }}</li>  #循环的是值 建  索引

 

 

解决插值表达式符号冲突

new Vue({
        el: '#app',
        data: {
            msg: '12345'
        },
        delimiters: ['${', '}']
    })

 

computed 返回值取决于局部作用域变化

里面出现的标签每发生一次变化就触发一次方法

data:{"i1":"1",i2:"2"}
computed:{
  i3:function(){
      return self.i1 + self.i2
        }
}    

watch 监听

watch 可以监控里面所有的插值值  插值值没发生一次变化就触发对应的函数

注意每个元素都必须在data出现

<div id="app01">
    <input type="text" v-model="i1" >
    <input type="text" v-model="i2" >
    <input type="text" v-model="i3" >
</div>

</body>
<script src="sadasd.js"></script>
<script >
    new Vue({
        el :"#app01",
        data:{
            i1:"",
            i2:"",
        },
        watch:{
            i1:function () {
                alert("i1变化")
            },
            i2:function () {
                alert("i2变化")
            }
        }

    })
</scrip

 

局部组件

是一个html代码 css js的集合体

知识点:

1.局部组件只有在挂载点里面使用

2.因为局部的原因 我们的组件是为了服用,所以数据要独立 所以data 是一个函数 有名称空间 返回一个字典

3. -单词 就可以匹配成大写的 A-aA  ---> AAA

<a-bc></a-bc> ----> aBc
实例一个Vue对象 ,通过components注册局部组件
new Vue({
   el:"#app",
  components:{"abc":localTag}     
})

一定要在Vue 上面!!!!

let localTag={
    template'<div>111<div>'
}

去通过 注册的别名来使用

<abc></abc>

全局组件

不需要在挂载点里面

Vue.component("aBc",{
     template:"<div>111</div>",
    });

无需注册

组件父传子

组件子传父

1.通过钩子  this.$emit("recv",this.my_info) 去触发 父组件的 方法

2.会把第二个参数传递  给 get_name

 

 

<div id="app01">
<abc @recv="get_name"></abc>
<div>{{msg1}}</div>
</div>
</body>
<script src="sadasd.js"></script>
<script >
    Vue.component("abc",{
       data:function () {
            return{my_info:""}
        },
        template:`<div>
<input type="text" v-model="my_info" >
<input type="button" @click="cccc">
</div>`,
        methods:{
            cccc:function () {
                this.$emit("recv",this.my_info)
            },
        }
    });
    new Vue({
        el:"#app01",
        data:{
            msg1:""
        },
        methods: {
            get_name:function (msg) {
                this.msg1=msg},

            }
    })
</script>

 使用服务器请求资源

既然我们要使用到单页面开发  Django的不在发挥出他的优势 我们需要寻找一种轻量级的,且最好能更好的和前端打交道的服务器

此时我们使用到了JavaScript语言的服务器 Node.js ,他的居然把 V8的引擎搬到了他的Node.js上,这也是第一次有人把前端的语言作为服务器

所以Node.js没有自己的语言,就因为他使用了强大的V8引擎,所以这一小个东西,就能发挥极强的优势 

1.一个Node,js只是一个单线程 2.非阻塞io 3.事件驱动

我们就可以做到点击某个按钮跳转到其他页面就不需要请求url 而是组件的替换

需要做 安装(见我的Node.js专题栏

以及  配置nmp为国内镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org

搭建 Vue架子脚 cnpm install -g @vue/cli

起步

1.cd 项目路径

2.vue create 目录名

3.选择自定义

4.Y/N 选择大写的 ,其他都为选择第一个

5勾选 Babel jsES6语法转换ES5,Router路由 Vuex组件数据交互 Formatter格式化代码

6.完成后启动server (开发过程使用 IDE可以事实更新 npm run serve ) 

 

项目目录

"""
node_modules:依赖
public:共有资源
    ico:页面标签的logo
    html:单页面 - 整个项目的唯一页面
src:代码主体
...:项目、插件等相关配置
"""

""" src
assets:静态资源
components:小组件
views:视图组件
App.vue:根组件
main.js:主脚本文件
router.js:路由脚本文件 vue-router
store.js:仓库脚本文件 vuex
"""
View Code

组件结构

<template>
    <!-- 只能有一个根标签 -->  html
</template>

<script>
    export default {
        name: "Main",
        data: function() {
            return {
                
            }
        },
        ...
    }
</script>

<style scoped>  #css作用域
    /* scoped */
</style>

根组件导入自组件

<!-- App.vue根组件 -->
<template>
    <div id="app">
        <!-- 3.使用 -->
        <Main></Main>
    </div>
</template>
<script>
    // 1.导入
    import Main from '@/views/Main'
    export default {
        // 2.注册
        components: {
            Main: Main
        }
    }
</script>
<style>
    html, body {
        margin: 0;
    }
</style>

组件的使用与跳转

挂载点内部 可以使用注册的name 来使用组
<div id="app"> <!-- 3.使用 --> <Main></Main> #必须导入之后使用 </div>
<router-link to="/home">home</router-link>会根据URL进行组件的替换 #需要在main.js里配

<router-view/>会根据当前页url 放置组件  例如 V1在main.js 对应组件1  那么url为xxx时 对应的就是这个组件 

 

生命周期钩子以及发送AJax

生命周期钩子

钩子是个回掉函数 当触发某个条件是 会执行,那么生命周期钩子就是在组件的出现阶段调用的函数

创建之前调用这个  创建时立马调用这个  创建之后调用另一个

beforeCreate () {
        console.log("实例刚刚创建");
        console.log(this.msg
                    
    },
    created () {
        console.log("实例创建成功, data, methods已拥有");
        console.log(this.msg);
    },
    mounted () {
        console.log("页面已被vue实例渲染, data, methods已更新");
    }
    // 拿到需求 => 确定钩子函数 => 解决需求的逻辑代码块

AJax

 

1.下载npm install axios--save

2.main.js 配置全局Vue添加ajax属性
import Axios from "axios"
Vue.prototype.$ajax = Axios;
new Vue(){} 之前

3.使用
mounted () {
            window.console.log('Goods组件渲染完毕');
            this.aaaa = 12345;
            window.console.log(this.aaaa);
            // 请求后台
            let _this = this;
            this.$ajax({
                url: 'http://127.0.0.1:8000/goods/',
                method: 'post',
                params: {
                    info: '前台数据'
                }
            }).then(function (result) {
                let data = result.data;
                // this 指向的是then的function
                _this.aaaa = data;
            })

        }

跨域问题

django有csrf_token了 但是还是无法相信绝对安全的跨域请求

通常情况下,A网页访问B服务器资源时,不满足以下三个条件其一就是跨域访问
1. 协议不同
2. 端口不同
3. 主机不同

1. 安装django-cors-headers模块
2.# 注册app
INSTALLED_APPS = [
    ...
    'corsheaders'
]
3 添加中间件
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware'
]
4# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2019-06-26 17:35  谢Rain  阅读(381)  评论(1编辑  收藏  举报