番茄酱
主 题
vue中解决数据改变而dom不重新渲染问题
language
// 把组件用v-if设置为条件渲染
data(){
return {
hackReset = true;
}
}
this.hackReset = false;
this.$nextTick(() => {
this.hackReset = true;
})
一般情况下vue里面的computed仅是getter,但也可以设置为setter
language
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
v-model可以有修饰符 v-model.number 、 v-model.trim
手动挂载组件$mount()
language
1. 在index.vue文件中
<template>
<el-dialog
title="登录"
:visible.sync="loginVisible"
:close-on-click-modal="false"
class="xia-dialog-login"
width="400px"
:modal="true"
>
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginrules"
class="loginForm"
>
<el-form-item prop="username" class="me-item">
<div class="xia-item">
<i class="fas fa-user mg-r-10" />
<el-input
v-model="loginForm.username"
class="inline"
type="username"
autocomplete="on"
/>
</div>
</el-form-item>
<el-form-item prop="password" class="me-item">
<div class="xia-item">
<i class="fas fa-lock mg-r-10" />
<el-input
v-model="loginForm.password"
class="inline"
type="password"
autocomplete="on"
@keydown.native.enter="tologinForm('loginForm')"
/>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- <el-button @click="loginVisible = false">取 消</el-button> -->
<el-button
type="primary"
@click="tologinForm('loginForm')"
>登 录</el-button>
</span>
</el-dialog>
</template>
<script>
import store from '@/store'
export default {
name: 'XiaLogin',
data() {
return {
token: '',
loginVisible: false,
loginForm: {
username: '',
password: '',
grant_type: 'password'
},
loginrules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
}
},
computed: {},
methods: {
async init() {
this.loginTypeHandle()
},
showXiaLogin(option = {}) {
this.init()
},
hideXiaLogin() {
this.loginVisible = false
},
destory() {
this.$destroy()
},
/* 登录方式控制 */
loginTypeHandle() {
const code = this.$getCode()
const service_url = location.protocol + '//' + location.host + location.pathname + 'login'
switch (code) {
// 单点登录
case 'gyfy_117' :
top.location.href = 'https://www.elungcare.com/sso/login?service=' + service_url
break
default:
this.loginVisible = true
break
}
},
/* 登录回调 */
tologinForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
store.dispatch('user/login', this.loginForm).then(async res => {
if (res) {
// 重定向或者首页
this.$message.success('登录成功')
this.token = this.$getToken()
this.hideXiaLogin()
await store.dispatch('user/getUserInfo')
location.reload()
} else {
this.$message.error('用户名,密码不匹配')
}
})
} else {
this.$message.error('输入信息有误!请重新输入')
return false
}
})
}
}
}
</script>
<style scoped lang="scss">
@import "~@/styles/scss/_mixins";
.xia-dialog-login {
.xia-item {
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
2. 在main.js中
import Vue from 'vue'
import XiaLogin from './index.vue'
const XiaLoginConstructor = Vue.extend(XiaLogin)
let XiaLoginInstance
function createXiaLogin(args = {}) {
// 创建一个vue构造器 初始化时可传参到.vue文件组件中
XiaLoginInstance = new XiaLoginConstructor({ data: {}})
// 当$mount() 函数没有传任何参数时
// 返回未挂载dom节点(自己理解:类似创建dom片段但是未渲染dom树上)
XiaLoginInstance.$mount()
// 手动 将 生成的对应 dom 插进 body 里面
document.body.appendChild(XiaLoginInstance.$el)
// console.log(XiaLoginConstructor)
// console.log(XiaLoginInstance)
return XiaLoginInstance
}
export function showXiaLogin(args, callback) {
// 每次调用时都可传参给组件的方法
// 为了让当前的实例 只有一个,防止占用太多内存
if (!XiaLoginInstance) {
XiaLoginInstance = createXiaLogin(args)
}
// console.log(XiaLoginInstance )
XiaLoginInstance.showXiaLogin(args)
callback && callback()
return XiaLoginInstance
}
export function hideXiaLogin() {
if (!XiaLoginInstance) return
XiaLoginInstance.hideXiaLogin()
return XiaLoginInstance
}
export function destoryXiaLogin() {
if (!XiaLoginInstance) return
XiaLoginInstance.destory()
}
export default showXiaLogin
vue比较好用的切要注意的属性和方法
language
1.一定要注意单向数据流(即父组件数据更新子组件也更新)
2.对于props传入引用型数据时,虽然子组件可以直接修改props的数据,但会造成数据流向不明确(不建议使用)
3.可以使用provide和inject传递数据,避免层层传递
4.sync和$emit(update:variable)使用
5.$listener 封装组件时把对个元素包裹的input元素 直接当前input元素使用
使用vnode编写 渲染内容
language
function messageLogListHandle(task_id) {
request.messageLogList({ task_id, no_page: 1 }).then(res => {
const h = this.$createElement
const data_list = res.data.data_list
const list = []
data_list.forEach((v) => {
const node = h('p', null, [
h('span', { style: 'font-weight: 500' }, `${v.pat_name}:`),
h('span', { style: 'font-weight: 500' }, `${v.phone_number}`),
h('span', { style: {
color: v.notify_result === 1 ? '#67C23A' : '#F56C6C',
marginLeft: '20px'
}}, `${v.notify_result === 1 ? '成功' : '失败'}`)
])
list.push(node)
})
this.$msgbox({
customClass: 'xia-msgbox',
title: '已发送列表',
message: h('div', null, list),
showCancelButton: false,
confirmButtonText: '确定'
}).catch((err) => err)
})
}
全部评论(0)